Preserving commit history am: b7e221621d am: 7d05f42406
am: ac95818199

Change-Id: I03d7d631ac4c2f0dec9704ce6c73d3f6230dab29
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..16db129
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,44 @@
+/lib
+bin
+.manager
+target
+.settings
+*~
+.project
+.classpath
+release.properties
+**/.DS_Store
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+.gradle
+build-*
+*.asc
+build
+out
+.java-version
+
+
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/dictionaries
+
+# Sensitive or high-churn files:
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.xml
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+
+# Gradle:
+.idea/**/gradle.xml
+.idea/**/libraries
+
+*.iws
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..eac2ad1
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+javaparser-parent
\ No newline at end of file
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
new file mode 100644
index 0000000..d7c1d0e
--- /dev/null
+++ b/.idea/codeStyleSettings.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectCodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS">
+      <value />
+    </option>
+    <option name="PREFERRED_PROJECT_CODE_STYLE" value="JavaParser" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..0aebde2
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+  <state>
+    <option name="PREFERRED_PROJECT_CODE_STYLE" value="JavaParser" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..a785d8b
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <annotationProcessing>
+      <profile name="Maven default annotation processors profile" enabled="true">
+        <sourceOutputDir name="target/generated-sources/annotations" />
+        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
+        <outputRelativeToContentRoot value="true" />
+        <module name="javaparser-core" />
+        <module name="javaparser-core-generators" />
+        <module name="javaparser-metamodel-generator" />
+        <module name="javaparser-symbol-solver-core" />
+        <module name="javaparser-symbol-solver-logic" />
+        <module name="javaparser-symbol-solver-model" />
+        <module name="javaparser-symbol-solver-testing" />
+        <module name="javaparser-testing" />
+      </profile>
+    </annotationProcessing>
+    <bytecodeTargetLevel>
+      <module name="javaparser-core" target="1.8" />
+      <module name="javaparser-core-generators" target="1.8" />
+      <module name="javaparser-metamodel-generator" target="1.8" />
+      <module name="javaparser-parent" target="1.8" />
+      <module name="javaparser-symbol-solver-core" target="1.8" />
+      <module name="javaparser-symbol-solver-logic" target="1.8" />
+      <module name="javaparser-symbol-solver-model" target="1.8" />
+      <module name="javaparser-symbol-solver-testing" target="1.8" />
+      <module name="javaparser-testing" target="1.8" />
+    </bytecodeTargetLevel>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..4d6b457
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-core" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-core-generators" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-metamodel-generator" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-symbol-solver-core" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-symbol-solver-logic" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-symbol-solver-model" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-symbol-solver-testing" charset="UTF-8" />
+    <file url="file://$PROJECT_DIR$/javaparser-testing" charset="UTF-8" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..146ab09
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,10 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
+      <option name="processCode" value="true" />
+      <option name="processLiterals" value="true" />
+      <option name="processComments" value="true" />
+    </inspection_tool>
+  </profile>
+</component>
\ No newline at end of file
diff --git a/.idea/markdown-doclet.xml b/.idea/markdown-doclet.xml
new file mode 100644
index 0000000..d7bd314
--- /dev/null
+++ b/.idea/markdown-doclet.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ch.raffael.mddoclet.integrations.idea.MarkdownDocletIdea.ProjectConfiguration">
+    <option name="enabled" value="true" />
+    <option name="renderingOptions">
+      <RenderingOptions />
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..68010fc
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <list size="4">
+      <item index="0" class="java.lang.String" itemvalue="com.github.javaparser.metamodel.DerivedProperty" />
+      <item index="1" class="java.lang.String" itemvalue="org.jbehave.core.annotations.Given" />
+      <item index="2" class="java.lang.String" itemvalue="org.jbehave.core.annotations.Then" />
+      <item index="3" class="java.lang.String" itemvalue="org.jbehave.core.annotations.When" />
+    </list>
+  </component>
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..1a08e14
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/javaparser-core/javaparser-core.iml" filepath="$PROJECT_DIR$/javaparser-core/javaparser-core.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-core-generators/javaparser-core-generators.iml" filepath="$PROJECT_DIR$/javaparser-core-generators/javaparser-core-generators.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-metamodel-generator/javaparser-metamodel-generator.iml" filepath="$PROJECT_DIR$/javaparser-metamodel-generator/javaparser-metamodel-generator.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-parent.iml" filepath="$PROJECT_DIR$/javaparser-parent.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-symbol-solver-core/javaparser-symbol-solver-core.iml" filepath="$PROJECT_DIR$/javaparser-symbol-solver-core/javaparser-symbol-solver-core.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-symbol-solver-logic/javaparser-symbol-solver-logic.iml" filepath="$PROJECT_DIR$/javaparser-symbol-solver-logic/javaparser-symbol-solver-logic.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-symbol-solver-model/javaparser-symbol-solver-model.iml" filepath="$PROJECT_DIR$/javaparser-symbol-solver-model/javaparser-symbol-solver-model.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-symbol-solver-testing/javaparser-symbol-solver-testing.iml" filepath="$PROJECT_DIR$/javaparser-symbol-solver-testing/javaparser-symbol-solver-testing.iml" />
+      <module fileurl="file://$PROJECT_DIR$/javaparser-testing/javaparser-testing.iml" filepath="$PROJECT_DIR$/javaparser-testing/javaparser-testing.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..640d3ae
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,16 @@
+sudo: false
+language: java
+install: mvn install -DskipTests=true
+script: mvn test
+jdk:
+  - oraclejdk8
+  - oraclejdk9
+notifications:
+  webhooks:
+    urls:
+      - "https://webhooks.gitter.im/e/ec3127975d8a2b8f11d0"
+    on_success: always  # options: [always|never|change] default: always
+    on_failure: always  # options: [always|never|change] default: always
+after_success:
+  - mvn test jacoco:report coveralls:report
+# http://lint.travis-ci.org/ validator
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..829165e
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,30 @@
+## Getting started
+Here is some information that's good to know when contributing to JavaParser:
+
+- There is some interesting information on the [wiki](https://github.com/javaparser/javaparser/wiki).
+- We work on JavaParser because we like to, not because it earns us money. Please remember that we try to run a professional project in our spare time, on a budget of zero.
+- Be sure to check [the coding guidelines](https://github.com/javaparser/javaparser/wiki/Coding-Guidelines) which are easily used by installing the formatting rules as described there.
+- If you're new and like to casually contribute something, check out the [easy issues](https://github.com/javaparser/javaparser/labels/Easy).
+- If you're new and would like to become a member, start your own project that uses JavaParser.
+We noticed we get the best feedback from those. 
+Here are [some fun project ideas](https://github.com/javaparser/javaparser/labels/fun%20project%20idea).
+- If you start working on an issue, please say so with a comment in the issue.
+- If you know how to fix a problem, please fix it and open a pull request instead of opening an issue.
+
+Thanks for helping!
+
+## Contribution Workflow
+
+Our development workflow is based on Pull Request. If you are not familiar with the Pull Requests, we suggest you to checkout the [Github Documentation](https://help.github.com/articles/creating-a-pull-request/) for more information.
+
+1. **Fork** the JavaParser project. If you already have a fork, ensure to fetch the latest commits.
+2. In your forked project, **create a branch** related to the issue you are working on. This is important to ensure that your pull request will not contain unrelated work.
+3. When your work in your branch is done, **push your branch to your forked repository**.
+4. Go back to the [javaparser project site](https://github.com/javaparser/javaparser) and it should have a message offering to **create a pull request**. If it doesn't you can [create one manually](https://github.com/javaparser/javaparser/compare).
+
+### Remember:
+- A pull request should include tests. You can either use BDD ([more information here](https://github.com/javaparser/javaparser/wiki/Testing)) or JUnit.
+- Every pull request will automatically be checked by a few tools. Make sure AppVeyor and Travis are green.
+- Pull requests often stay open for at least a few days to give people a chance to review it.
+- A pull request is merged when all comments on it have been resolved.
+- If you create a pull request for an issue, mention the issue in the format #123 to make github link it automatically.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..012ddda
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,6 @@
+JavaParser is available either under the terms of the LGPL License or the Apache License. You as the user are entitled to choose the terms under which to adopt JavaParser.
+
+For details about the LGPL License please refer to LICENSE.LGPL. Please note
+that LGPL is just an extension to GPL, located in LICENSE.GPL.
+
+For details about the Apache License please refer to LICENSE.APACHE
diff --git a/LICENSE.APACHE b/LICENSE.APACHE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.APACHE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       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.
diff --git a/LICENSE.GPL b/LICENSE.GPL
new file mode 100644
index 0000000..fb1a1b0
--- /dev/null
+++ b/LICENSE.GPL
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE

+                       Version 3, 29 June 2007

+

+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>

+ Everyone is permitted to copy and distribute verbatim copies

+ of this license document, but changing it is not allowed.

+

+                            Preamble

+

+  The GNU General Public License is a free, copyleft license for

+software and other kinds of works.

+

+  The licenses for most software and other practical works are designed

+to take away your freedom to share and change the works.  By contrast,

+the GNU General Public License is intended to guarantee your freedom to

+share and change all versions of a program--to make sure it remains free

+software for all its users.  We, the Free Software Foundation, use the

+GNU General Public License for most of our software; it applies also to

+any other work released this way by its authors.  You can apply it to

+your programs, too.

+

+  When we speak of free software, we are referring to freedom, not

+price.  Our General Public Licenses are designed to make sure that you

+have the freedom to distribute copies of free software (and charge for

+them if you wish), that you receive source code or can get it if you

+want it, that you can change the software or use pieces of it in new

+free programs, and that you know you can do these things.

+

+  To protect your rights, we need to prevent others from denying you

+these rights or asking you to surrender the rights.  Therefore, you have

+certain responsibilities if you distribute copies of the software, or if

+you modify it: responsibilities to respect the freedom of others.

+

+  For example, if you distribute copies of such a program, whether

+gratis or for a fee, you must pass on to the recipients the same

+freedoms that you received.  You must make sure that they, too, receive

+or can get the source code.  And you must show them these terms so they

+know their rights.

+

+  Developers that use the GNU GPL protect your rights with two steps:

+(1) assert copyright on the software, and (2) offer you this License

+giving you legal permission to copy, distribute and/or modify it.

+

+  For the developers' and authors' protection, the GPL clearly explains

+that there is no warranty for this free software.  For both users' and

+authors' sake, the GPL requires that modified versions be marked as

+changed, so that their problems will not be attributed erroneously to

+authors of previous versions.

+

+  Some devices are designed to deny users access to install or run

+modified versions of the software inside them, although the manufacturer

+can do so.  This is fundamentally incompatible with the aim of

+protecting users' freedom to change the software.  The systematic

+pattern of such abuse occurs in the area of products for individuals to

+use, which is precisely where it is most unacceptable.  Therefore, we

+have designed this version of the GPL to prohibit the practice for those

+products.  If such problems arise substantially in other domains, we

+stand ready to extend this provision to those domains in future versions

+of the GPL, as needed to protect the freedom of users.

+

+  Finally, every program is threatened constantly by software patents.

+States should not allow patents to restrict development and use of

+software on general-purpose computers, but in those that do, we wish to

+avoid the special danger that patents applied to a free program could

+make it effectively proprietary.  To prevent this, the GPL assures that

+patents cannot be used to render the program non-free.

+

+  The precise terms and conditions for copying, distribution and

+modification follow.

+

+                       TERMS AND CONDITIONS

+

+  0. Definitions.

+

+  "This License" refers to version 3 of the GNU General Public License.

+

+  "Copyright" also means copyright-like laws that apply to other kinds of

+works, such as semiconductor masks.

+

+  "The Program" refers to any copyrightable work licensed under this

+License.  Each licensee is addressed as "you".  "Licensees" and

+"recipients" may be individuals or organizations.

+

+  To "modify" a work means to copy from or adapt all or part of the work

+in a fashion requiring copyright permission, other than the making of an

+exact copy.  The resulting work is called a "modified version" of the

+earlier work or a work "based on" the earlier work.

+

+  A "covered work" means either the unmodified Program or a work based

+on the Program.

+

+  To "propagate" a work means to do anything with it that, without

+permission, would make you directly or secondarily liable for

+infringement under applicable copyright law, except executing it on a

+computer or modifying a private copy.  Propagation includes copying,

+distribution (with or without modification), making available to the

+public, and in some countries other activities as well.

+

+  To "convey" a work means any kind of propagation that enables other

+parties to make or receive copies.  Mere interaction with a user through

+a computer network, with no transfer of a copy, is not conveying.

+

+  An interactive user interface displays "Appropriate Legal Notices"

+to the extent that it includes a convenient and prominently visible

+feature that (1) displays an appropriate copyright notice, and (2)

+tells the user that there is no warranty for the work (except to the

+extent that warranties are provided), that licensees may convey the

+work under this License, and how to view a copy of this License.  If

+the interface presents a list of user commands or options, such as a

+menu, a prominent item in the list meets this criterion.

+

+  1. Source Code.

+

+  The "source code" for a work means the preferred form of the work

+for making modifications to it.  "Object code" means any non-source

+form of a work.

+

+  A "Standard Interface" means an interface that either is an official

+standard defined by a recognized standards body, or, in the case of

+interfaces specified for a particular programming language, one that

+is widely used among developers working in that language.

+

+  The "System Libraries" of an executable work include anything, other

+than the work as a whole, that (a) is included in the normal form of

+packaging a Major Component, but which is not part of that Major

+Component, and (b) serves only to enable use of the work with that

+Major Component, or to implement a Standard Interface for which an

+implementation is available to the public in source code form.  A

+"Major Component", in this context, means a major essential component

+(kernel, window system, and so on) of the specific operating system

+(if any) on which the executable work runs, or a compiler used to

+produce the work, or an object code interpreter used to run it.

+

+  The "Corresponding Source" for a work in object code form means all

+the source code needed to generate, install, and (for an executable

+work) run the object code and to modify the work, including scripts to

+control those activities.  However, it does not include the work's

+System Libraries, or general-purpose tools or generally available free

+programs which are used unmodified in performing those activities but

+which are not part of the work.  For example, Corresponding Source

+includes interface definition files associated with source files for

+the work, and the source code for shared libraries and dynamically

+linked subprograms that the work is specifically designed to require,

+such as by intimate data communication or control flow between those

+subprograms and other parts of the work.

+

+  The Corresponding Source need not include anything that users

+can regenerate automatically from other parts of the Corresponding

+Source.

+

+  The Corresponding Source for a work in source code form is that

+same work.

+

+  2. Basic Permissions.

+

+  All rights granted under this License are granted for the term of

+copyright on the Program, and are irrevocable provided the stated

+conditions are met.  This License explicitly affirms your unlimited

+permission to run the unmodified Program.  The output from running a

+covered work is covered by this License only if the output, given its

+content, constitutes a covered work.  This License acknowledges your

+rights of fair use or other equivalent, as provided by copyright law.

+

+  You may make, run and propagate covered works that you do not

+convey, without conditions so long as your license otherwise remains

+in force.  You may convey covered works to others for the sole purpose

+of having them make modifications exclusively for you, or provide you

+with facilities for running those works, provided that you comply with

+the terms of this License in conveying all material for which you do

+not control copyright.  Those thus making or running the covered works

+for you must do so exclusively on your behalf, under your direction

+and control, on terms that prohibit them from making any copies of

+your copyrighted material outside their relationship with you.

+

+  Conveying under any other circumstances is permitted solely under

+the conditions stated below.  Sublicensing is not allowed; section 10

+makes it unnecessary.

+

+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

+

+  No covered work shall be deemed part of an effective technological

+measure under any applicable law fulfilling obligations under article

+11 of the WIPO copyright treaty adopted on 20 December 1996, or

+similar laws prohibiting or restricting circumvention of such

+measures.

+

+  When you convey a covered work, you waive any legal power to forbid

+circumvention of technological measures to the extent such circumvention

+is effected by exercising rights under this License with respect to

+the covered work, and you disclaim any intention to limit operation or

+modification of the work as a means of enforcing, against the work's

+users, your or third parties' legal rights to forbid circumvention of

+technological measures.

+

+  4. Conveying Verbatim Copies.

+

+  You may convey verbatim copies of the Program's source code as you

+receive it, in any medium, provided that you conspicuously and

+appropriately publish on each copy an appropriate copyright notice;

+keep intact all notices stating that this License and any

+non-permissive terms added in accord with section 7 apply to the code;

+keep intact all notices of the absence of any warranty; and give all

+recipients a copy of this License along with the Program.

+

+  You may charge any price or no price for each copy that you convey,

+and you may offer support or warranty protection for a fee.

+

+  5. Conveying Modified Source Versions.

+

+  You may convey a work based on the Program, or the modifications to

+produce it from the Program, in the form of source code under the

+terms of section 4, provided that you also meet all of these conditions:

+

+    a) The work must carry prominent notices stating that you modified

+    it, and giving a relevant date.

+

+    b) The work must carry prominent notices stating that it is

+    released under this License and any conditions added under section

+    7.  This requirement modifies the requirement in section 4 to

+    "keep intact all notices".

+

+    c) You must license the entire work, as a whole, under this

+    License to anyone who comes into possession of a copy.  This

+    License will therefore apply, along with any applicable section 7

+    additional terms, to the whole of the work, and all its parts,

+    regardless of how they are packaged.  This License gives no

+    permission to license the work in any other way, but it does not

+    invalidate such permission if you have separately received it.

+

+    d) If the work has interactive user interfaces, each must display

+    Appropriate Legal Notices; however, if the Program has interactive

+    interfaces that do not display Appropriate Legal Notices, your

+    work need not make them do so.

+

+  A compilation of a covered work with other separate and independent

+works, which are not by their nature extensions of the covered work,

+and which are not combined with it such as to form a larger program,

+in or on a volume of a storage or distribution medium, is called an

+"aggregate" if the compilation and its resulting copyright are not

+used to limit the access or legal rights of the compilation's users

+beyond what the individual works permit.  Inclusion of a covered work

+in an aggregate does not cause this License to apply to the other

+parts of the aggregate.

+

+  6. Conveying Non-Source Forms.

+

+  You may convey a covered work in object code form under the terms

+of sections 4 and 5, provided that you also convey the

+machine-readable Corresponding Source under the terms of this License,

+in one of these ways:

+

+    a) Convey the object code in, or embodied in, a physical product

+    (including a physical distribution medium), accompanied by the

+    Corresponding Source fixed on a durable physical medium

+    customarily used for software interchange.

+

+    b) Convey the object code in, or embodied in, a physical product

+    (including a physical distribution medium), accompanied by a

+    written offer, valid for at least three years and valid for as

+    long as you offer spare parts or customer support for that product

+    model, to give anyone who possesses the object code either (1) a

+    copy of the Corresponding Source for all the software in the

+    product that is covered by this License, on a durable physical

+    medium customarily used for software interchange, for a price no

+    more than your reasonable cost of physically performing this

+    conveying of source, or (2) access to copy the

+    Corresponding Source from a network server at no charge.

+

+    c) Convey individual copies of the object code with a copy of the

+    written offer to provide the Corresponding Source.  This

+    alternative is allowed only occasionally and noncommercially, and

+    only if you received the object code with such an offer, in accord

+    with subsection 6b.

+

+    d) Convey the object code by offering access from a designated

+    place (gratis or for a charge), and offer equivalent access to the

+    Corresponding Source in the same way through the same place at no

+    further charge.  You need not require recipients to copy the

+    Corresponding Source along with the object code.  If the place to

+    copy the object code is a network server, the Corresponding Source

+    may be on a different server (operated by you or a third party)

+    that supports equivalent copying facilities, provided you maintain

+    clear directions next to the object code saying where to find the

+    Corresponding Source.  Regardless of what server hosts the

+    Corresponding Source, you remain obligated to ensure that it is

+    available for as long as needed to satisfy these requirements.

+

+    e) Convey the object code using peer-to-peer transmission, provided

+    you inform other peers where the object code and Corresponding

+    Source of the work are being offered to the general public at no

+    charge under subsection 6d.

+

+  A separable portion of the object code, whose source code is excluded

+from the Corresponding Source as a System Library, need not be

+included in conveying the object code work.

+

+  A "User Product" is either (1) a "consumer product", which means any

+tangible personal property which is normally used for personal, family,

+or household purposes, or (2) anything designed or sold for incorporation

+into a dwelling.  In determining whether a product is a consumer product,

+doubtful cases shall be resolved in favor of coverage.  For a particular

+product received by a particular user, "normally used" refers to a

+typical or common use of that class of product, regardless of the status

+of the particular user or of the way in which the particular user

+actually uses, or expects or is expected to use, the product.  A product

+is a consumer product regardless of whether the product has substantial

+commercial, industrial or non-consumer uses, unless such uses represent

+the only significant mode of use of the product.

+

+  "Installation Information" for a User Product means any methods,

+procedures, authorization keys, or other information required to install

+and execute modified versions of a covered work in that User Product from

+a modified version of its Corresponding Source.  The information must

+suffice to ensure that the continued functioning of the modified object

+code is in no case prevented or interfered with solely because

+modification has been made.

+

+  If you convey an object code work under this section in, or with, or

+specifically for use in, a User Product, and the conveying occurs as

+part of a transaction in which the right of possession and use of the

+User Product is transferred to the recipient in perpetuity or for a

+fixed term (regardless of how the transaction is characterized), the

+Corresponding Source conveyed under this section must be accompanied

+by the Installation Information.  But this requirement does not apply

+if neither you nor any third party retains the ability to install

+modified object code on the User Product (for example, the work has

+been installed in ROM).

+

+  The requirement to provide Installation Information does not include a

+requirement to continue to provide support service, warranty, or updates

+for a work that has been modified or installed by the recipient, or for

+the User Product in which it has been modified or installed.  Access to a

+network may be denied when the modification itself materially and

+adversely affects the operation of the network or violates the rules and

+protocols for communication across the network.

+

+  Corresponding Source conveyed, and Installation Information provided,

+in accord with this section must be in a format that is publicly

+documented (and with an implementation available to the public in

+source code form), and must require no special password or key for

+unpacking, reading or copying.

+

+  7. Additional Terms.

+

+  "Additional permissions" are terms that supplement the terms of this

+License by making exceptions from one or more of its conditions.

+Additional permissions that are applicable to the entire Program shall

+be treated as though they were included in this License, to the extent

+that they are valid under applicable law.  If additional permissions

+apply only to part of the Program, that part may be used separately

+under those permissions, but the entire Program remains governed by

+this License without regard to the additional permissions.

+

+  When you convey a copy of a covered work, you may at your option

+remove any additional permissions from that copy, or from any part of

+it.  (Additional permissions may be written to require their own

+removal in certain cases when you modify the work.)  You may place

+additional permissions on material, added by you to a covered work,

+for which you have or can give appropriate copyright permission.

+

+  Notwithstanding any other provision of this License, for material you

+add to a covered work, you may (if authorized by the copyright holders of

+that material) supplement the terms of this License with terms:

+

+    a) Disclaiming warranty or limiting liability differently from the

+    terms of sections 15 and 16 of this License; or

+

+    b) Requiring preservation of specified reasonable legal notices or

+    author attributions in that material or in the Appropriate Legal

+    Notices displayed by works containing it; or

+

+    c) Prohibiting misrepresentation of the origin of that material, or

+    requiring that modified versions of such material be marked in

+    reasonable ways as different from the original version; or

+

+    d) Limiting the use for publicity purposes of names of licensors or

+    authors of the material; or

+

+    e) Declining to grant rights under trademark law for use of some

+    trade names, trademarks, or service marks; or

+

+    f) Requiring indemnification of licensors and authors of that

+    material by anyone who conveys the material (or modified versions of

+    it) with contractual assumptions of liability to the recipient, for

+    any liability that these contractual assumptions directly impose on

+    those licensors and authors.

+

+  All other non-permissive additional terms are considered "further

+restrictions" within the meaning of section 10.  If the Program as you

+received it, or any part of it, contains a notice stating that it is

+governed by this License along with a term that is a further

+restriction, you may remove that term.  If a license document contains

+a further restriction but permits relicensing or conveying under this

+License, you may add to a covered work material governed by the terms

+of that license document, provided that the further restriction does

+not survive such relicensing or conveying.

+

+  If you add terms to a covered work in accord with this section, you

+must place, in the relevant source files, a statement of the

+additional terms that apply to those files, or a notice indicating

+where to find the applicable terms.

+

+  Additional terms, permissive or non-permissive, may be stated in the

+form of a separately written license, or stated as exceptions;

+the above requirements apply either way.

+

+  8. Termination.

+

+  You may not propagate or modify a covered work except as expressly

+provided under this License.  Any attempt otherwise to propagate or

+modify it is void, and will automatically terminate your rights under

+this License (including any patent licenses granted under the third

+paragraph of section 11).

+

+  However, if you cease all violation of this License, then your

+license from a particular copyright holder is reinstated (a)

+provisionally, unless and until the copyright holder explicitly and

+finally terminates your license, and (b) permanently, if the copyright

+holder fails to notify you of the violation by some reasonable means

+prior to 60 days after the cessation.

+

+  Moreover, your license from a particular copyright holder is

+reinstated permanently if the copyright holder notifies you of the

+violation by some reasonable means, this is the first time you have

+received notice of violation of this License (for any work) from that

+copyright holder, and you cure the violation prior to 30 days after

+your receipt of the notice.

+

+  Termination of your rights under this section does not terminate the

+licenses of parties who have received copies or rights from you under

+this License.  If your rights have been terminated and not permanently

+reinstated, you do not qualify to receive new licenses for the same

+material under section 10.

+

+  9. Acceptance Not Required for Having Copies.

+

+  You are not required to accept this License in order to receive or

+run a copy of the Program.  Ancillary propagation of a covered work

+occurring solely as a consequence of using peer-to-peer transmission

+to receive a copy likewise does not require acceptance.  However,

+nothing other than this License grants you permission to propagate or

+modify any covered work.  These actions infringe copyright if you do

+not accept this License.  Therefore, by modifying or propagating a

+covered work, you indicate your acceptance of this License to do so.

+

+  10. Automatic Licensing of Downstream Recipients.

+

+  Each time you convey a covered work, the recipient automatically

+receives a license from the original licensors, to run, modify and

+propagate that work, subject to this License.  You are not responsible

+for enforcing compliance by third parties with this License.

+

+  An "entity transaction" is a transaction transferring control of an

+organization, or substantially all assets of one, or subdividing an

+organization, or merging organizations.  If propagation of a covered

+work results from an entity transaction, each party to that

+transaction who receives a copy of the work also receives whatever

+licenses to the work the party's predecessor in interest had or could

+give under the previous paragraph, plus a right to possession of the

+Corresponding Source of the work from the predecessor in interest, if

+the predecessor has it or can get it with reasonable efforts.

+

+  You may not impose any further restrictions on the exercise of the

+rights granted or affirmed under this License.  For example, you may

+not impose a license fee, royalty, or other charge for exercise of

+rights granted under this License, and you may not initiate litigation

+(including a cross-claim or counterclaim in a lawsuit) alleging that

+any patent claim is infringed by making, using, selling, offering for

+sale, or importing the Program or any portion of it.

+

+  11. Patents.

+

+  A "contributor" is a copyright holder who authorizes use under this

+License of the Program or a work on which the Program is based.  The

+work thus licensed is called the contributor's "contributor version".

+

+  A contributor's "essential patent claims" are all patent claims

+owned or controlled by the contributor, whether already acquired or

+hereafter acquired, that would be infringed by some manner, permitted

+by this License, of making, using, or selling its contributor version,

+but do not include claims that would be infringed only as a

+consequence of further modification of the contributor version.  For

+purposes of this definition, "control" includes the right to grant

+patent sublicenses in a manner consistent with the requirements of

+this License.

+

+  Each contributor grants you a non-exclusive, worldwide, royalty-free

+patent license under the contributor's essential patent claims, to

+make, use, sell, offer for sale, import and otherwise run, modify and

+propagate the contents of its contributor version.

+

+  In the following three paragraphs, a "patent license" is any express

+agreement or commitment, however denominated, not to enforce a patent

+(such as an express permission to practice a patent or covenant not to

+sue for patent infringement).  To "grant" such a patent license to a

+party means to make such an agreement or commitment not to enforce a

+patent against the party.

+

+  If you convey a covered work, knowingly relying on a patent license,

+and the Corresponding Source of the work is not available for anyone

+to copy, free of charge and under the terms of this License, through a

+publicly available network server or other readily accessible means,

+then you must either (1) cause the Corresponding Source to be so

+available, or (2) arrange to deprive yourself of the benefit of the

+patent license for this particular work, or (3) arrange, in a manner

+consistent with the requirements of this License, to extend the patent

+license to downstream recipients.  "Knowingly relying" means you have

+actual knowledge that, but for the patent license, your conveying the

+covered work in a country, or your recipient's use of the covered work

+in a country, would infringe one or more identifiable patents in that

+country that you have reason to believe are valid.

+

+  If, pursuant to or in connection with a single transaction or

+arrangement, you convey, or propagate by procuring conveyance of, a

+covered work, and grant a patent license to some of the parties

+receiving the covered work authorizing them to use, propagate, modify

+or convey a specific copy of the covered work, then the patent license

+you grant is automatically extended to all recipients of the covered

+work and works based on it.

+

+  A patent license is "discriminatory" if it does not include within

+the scope of its coverage, prohibits the exercise of, or is

+conditioned on the non-exercise of one or more of the rights that are

+specifically granted under this License.  You may not convey a covered

+work if you are a party to an arrangement with a third party that is

+in the business of distributing software, under which you make payment

+to the third party based on the extent of your activity of conveying

+the work, and under which the third party grants, to any of the

+parties who would receive the covered work from you, a discriminatory

+patent license (a) in connection with copies of the covered work

+conveyed by you (or copies made from those copies), or (b) primarily

+for and in connection with specific products or compilations that

+contain the covered work, unless you entered into that arrangement,

+or that patent license was granted, prior to 28 March 2007.

+

+  Nothing in this License shall be construed as excluding or limiting

+any implied license or other defenses to infringement that may

+otherwise be available to you under applicable patent law.

+

+  12. No Surrender of Others' Freedom.

+

+  If conditions are imposed on you (whether by court order, agreement or

+otherwise) that contradict the conditions of this License, they do not

+excuse you from the conditions of this License.  If you cannot convey a

+covered work so as to satisfy simultaneously your obligations under this

+License and any other pertinent obligations, then as a consequence you may

+not convey it at all.  For example, if you agree to terms that obligate you

+to collect a royalty for further conveying from those to whom you convey

+the Program, the only way you could satisfy both those terms and this

+License would be to refrain entirely from conveying the Program.

+

+  13. Use with the GNU Affero General Public License.

+

+  Notwithstanding any other provision of this License, you have

+permission to link or combine any covered work with a work licensed

+under version 3 of the GNU Affero General Public License into a single

+combined work, and to convey the resulting work.  The terms of this

+License will continue to apply to the part which is the covered work,

+but the special requirements of the GNU Affero General Public License,

+section 13, concerning interaction through a network will apply to the

+combination as such.

+

+  14. Revised Versions of this License.

+

+  The Free Software Foundation may publish revised and/or new versions of

+the GNU General Public License from time to time.  Such new versions will

+be similar in spirit to the present version, but may differ in detail to

+address new problems or concerns.

+

+  Each version is given a distinguishing version number.  If the

+Program specifies that a certain numbered version of the GNU General

+Public License "or any later version" applies to it, you have the

+option of following the terms and conditions either of that numbered

+version or of any later version published by the Free Software

+Foundation.  If the Program does not specify a version number of the

+GNU General Public License, you may choose any version ever published

+by the Free Software Foundation.

+

+  If the Program specifies that a proxy can decide which future

+versions of the GNU General Public License can be used, that proxy's

+public statement of acceptance of a version permanently authorizes you

+to choose that version for the Program.

+

+  Later license versions may give you additional or different

+permissions.  However, no additional obligations are imposed on any

+author or copyright holder as a result of your choosing to follow a

+later version.

+

+  15. Disclaimer of Warranty.

+

+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY

+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT

+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY

+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,

+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM

+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF

+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

+

+  16. Limitation of Liability.

+

+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING

+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS

+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY

+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE

+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF

+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD

+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),

+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF

+SUCH DAMAGES.

+

+  17. Interpretation of Sections 15 and 16.

+

+  If the disclaimer of warranty and limitation of liability provided

+above cannot be given local legal effect according to their terms,

+reviewing courts shall apply local law that most closely approximates

+an absolute waiver of all civil liability in connection with the

+Program, unless a warranty or assumption of liability accompanies a

+copy of the Program in return for a fee.

+

+                     END OF TERMS AND CONDITIONS

+

+            How to Apply These Terms to Your New Programs

+

+  If you develop a new program, and you want it to be of the greatest

+possible use to the public, the best way to achieve this is to make it

+free software which everyone can redistribute and change under these terms.

+

+  To do so, attach the following notices to the program.  It is safest

+to attach them to the start of each source file to most effectively

+state the exclusion of warranty; and each file should have at least

+the "copyright" line and a pointer to where the full notice is found.

+

+    Java 1.5 japa.parser and Abstract Syntax Tree

+    Copyright (C) 2007  J�lio Vilmar Gesser

+

+    This program is free software: you can redistribute it and/or modify

+    it under the terms of the GNU General Public License as published by

+    the Free Software Foundation, either version 3 of the License, or

+    (at your option) any later version.

+

+    This program is distributed in the hope that it will be useful,

+    but WITHOUT ANY WARRANTY; without even the implied warranty of

+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+    GNU General Public License for more details.

+

+    You should have received a copy of the GNU General Public License

+    along with this program.  If not, see <http://www.gnu.org/licenses/>.

+

+Also add information on how to contact you by electronic and paper mail.

+

+  If the program does terminal interaction, make it output a short

+notice like this when it starts in an interactive mode:

+

+    Java 1.5 japa.parser and Abstract Syntax Tree  Copyright (C) 2007  J�lio Vilmar Gesser

+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.

+    This is free software, and you are welcome to redistribute it

+    under certain conditions; type `show c' for details.

+

+The hypothetical commands `show w' and `show c' should show the appropriate

+parts of the General Public License.  Of course, your program's commands

+might be different; for a GUI interface, you would use an "about box".

+

+  You should also get your employer (if you work as a programmer) or school,

+if any, to sign a "copyright disclaimer" for the program, if necessary.

+For more information on this, and how to apply and follow the GNU GPL, see

+<http://www.gnu.org/licenses/>.

+

+  The GNU General Public License does not permit incorporating your program

+into proprietary programs.  If your program is a subroutine library, you

+may consider it more useful to permit linking proprietary applications with

+the library.  If this is what you want to do, use the GNU Lesser General

+Public License instead of this License.  But first, please read

+<http://www.gnu.org/philosophy/why-not-lgpl.html>.

diff --git a/LICENSE.LGPL b/LICENSE.LGPL
new file mode 100644
index 0000000..b87303c
--- /dev/null
+++ b/LICENSE.LGPL
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE

+                       Version 3, 29 June 2007

+

+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>

+ Everyone is permitted to copy and distribute verbatim copies

+ of this license document, but changing it is not allowed.

+

+

+  This version of the GNU Lesser General Public License incorporates

+the terms and conditions of version 3 of the GNU General Public

+License, supplemented by the additional permissions listed below.

+

+  0. Additional Definitions. 

+

+  As used herein, "this License" refers to version 3 of the GNU Lesser

+General Public License, and the "GNU GPL" refers to version 3 of the GNU

+General Public License.

+

+  "The Library" refers to a covered work governed by this License,

+other than an Application or a Combined Work as defined below.

+

+  An "Application" is any work that makes use of an interface provided

+by the Library, but which is not otherwise based on the Library.

+Defining a subclass of a class defined by the Library is deemed a mode

+of using an interface provided by the Library.

+

+  A "Combined Work" is a work produced by combining or linking an

+Application with the Library.  The particular version of the Library

+with which the Combined Work was made is also called the "Linked

+Version".

+

+  The "Minimal Corresponding Source" for a Combined Work means the

+Corresponding Source for the Combined Work, excluding any source code

+for portions of the Combined Work that, considered in isolation, are

+based on the Application, and not on the Linked Version.

+

+  The "Corresponding Application Code" for a Combined Work means the

+object code and/or source code for the Application, including any data

+and utility programs needed for reproducing the Combined Work from the

+Application, but excluding the System Libraries of the Combined Work.

+

+  1. Exception to Section 3 of the GNU GPL.

+

+  You may convey a covered work under sections 3 and 4 of this License

+without being bound by section 3 of the GNU GPL.

+

+  2. Conveying Modified Versions.

+

+  If you modify a copy of the Library, and, in your modifications, a

+facility refers to a function or data to be supplied by an Application

+that uses the facility (other than as an argument passed when the

+facility is invoked), then you may convey a copy of the modified

+version:

+

+   a) under this License, provided that you make a good faith effort to

+   ensure that, in the event an Application does not supply the

+   function or data, the facility still operates, and performs

+   whatever part of its purpose remains meaningful, or

+

+   b) under the GNU GPL, with none of the additional permissions of

+   this License applicable to that copy.

+

+  3. Object Code Incorporating Material from Library Header Files.

+

+  The object code form of an Application may incorporate material from

+a header file that is part of the Library.  You may convey such object

+code under terms of your choice, provided that, if the incorporated

+material is not limited to numerical parameters, data structure

+layouts and accessors, or small macros, inline functions and templates

+(ten or fewer lines in length), you do both of the following:

+

+   a) Give prominent notice with each copy of the object code that the

+   Library is used in it and that the Library and its use are

+   covered by this License.

+

+   b) Accompany the object code with a copy of the GNU GPL and this license

+   document.

+

+  4. Combined Works.

+

+  You may convey a Combined Work under terms of your choice that,

+taken together, effectively do not restrict modification of the

+portions of the Library contained in the Combined Work and reverse

+engineering for debugging such modifications, if you also do each of

+the following:

+

+   a) Give prominent notice with each copy of the Combined Work that

+   the Library is used in it and that the Library and its use are

+   covered by this License.

+

+   b) Accompany the Combined Work with a copy of the GNU GPL and this license

+   document.

+

+   c) For a Combined Work that displays copyright notices during

+   execution, include the copyright notice for the Library among

+   these notices, as well as a reference directing the user to the

+   copies of the GNU GPL and this license document.

+

+   d) Do one of the following:

+

+       0) Convey the Minimal Corresponding Source under the terms of this

+       License, and the Corresponding Application Code in a form

+       suitable for, and under terms that permit, the user to

+       recombine or relink the Application with a modified version of

+       the Linked Version to produce a modified Combined Work, in the

+       manner specified by section 6 of the GNU GPL for conveying

+       Corresponding Source.

+

+       1) Use a suitable shared library mechanism for linking with the

+       Library.  A suitable mechanism is one that (a) uses at run time

+       a copy of the Library already present on the user's computer

+       system, and (b) will operate properly with a modified version

+       of the Library that is interface-compatible with the Linked

+       Version. 

+

+   e) Provide Installation Information, but only if you would otherwise

+   be required to provide such information under section 6 of the

+   GNU GPL, and only to the extent that such information is

+   necessary to install and execute a modified version of the

+   Combined Work produced by recombining or relinking the

+   Application with a modified version of the Linked Version. (If

+   you use option 4d0, the Installation Information must accompany

+   the Minimal Corresponding Source and Corresponding Application

+   Code. If you use option 4d1, you must provide the Installation

+   Information in the manner specified by section 6 of the GNU GPL

+   for conveying Corresponding Source.)

+

+  5. Combined Libraries.

+

+  You may place library facilities that are a work based on the

+Library side by side in a single library together with other library

+facilities that are not Applications and are not covered by this

+License, and convey such a combined library under terms of your

+choice, if you do both of the following:

+

+   a) Accompany the combined library with a copy of the same work based

+   on the Library, uncombined with any other library facilities,

+   conveyed under the terms of this License.

+

+   b) Give prominent notice with the combined library that part of it

+   is a work based on the Library, and explaining where to find the

+   accompanying uncombined form of the same work.

+

+  6. Revised Versions of the GNU Lesser General Public License.

+

+  The Free Software Foundation may publish revised and/or new versions

+of the GNU Lesser General Public License from time to time. Such new

+versions will be similar in spirit to the present version, but may

+differ in detail to address new problems or concerns.

+

+  Each version is given a distinguishing version number. If the

+Library as you received it specifies that a certain numbered version

+of the GNU Lesser General Public License "or any later version"

+applies to it, you have the option of following the terms and

+conditions either of that published version or of any later version

+published by the Free Software Foundation. If the Library as you

+received it does not specify a version number of the GNU Lesser

+General Public License, you may choose any version of the GNU Lesser

+General Public License ever published by the Free Software Foundation.

+

+  If the Library as you received it specifies that a proxy can decide

+whether future versions of the GNU Lesser General Public License shall

+apply, that proxy's public statement of acceptance of any version is

+permanent authorization for you to choose that version for the

+Library.

diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..f881bfc
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,23 @@
+version: '{build}'
+os: Windows Server 2012
+install:
+  - ps: |
+      Add-Type -AssemblyName System.IO.Compression.FileSystem
+      if (!(Test-Path -Path "C:\maven" )) {
+        (new-object System.Net.WebClient).DownloadFile(
+          'http://www.us.apache.org/dist/maven/maven-3/3.2.5/binaries/apache-maven-3.2.5-bin.zip',
+          'C:\maven-bin.zip'
+        )
+        [System.IO.Compression.ZipFile]::ExtractToDirectory("C:\maven-bin.zip", "C:\maven")
+      }
+  - cmd: SET PATH=C:\maven\apache-maven-3.2.5\bin;%JAVA_HOME%\bin;%PATH%
+  - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g
+  - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g
+  - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5
+build_script:
+  - mvn clean package --batch-mode -DskipTest
+test_script:
+  - mvn clean install --batch-mode
+cache:
+  - C:\maven\
+  - C:\Users\appveyor\.m2
\ No newline at end of file
diff --git a/changelog.md b/changelog.md
new file mode 100644
index 0000000..192f146
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,677 @@
+Version 3.5.15
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/78?closed=1)
+* Java 10 support is complete.
+* BREAKING: Java language level support has changed to make Java 10 support possible.
+[Here's a little article about it](https://matozoid.github.io/2017/04/11/enable-java-9-support.html)
+
+Version 3.5.14
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/77?closed=1)
+* Java 10's `var` can now be parsed and will be turned into a `VarType` node.
+It can not be resolved yet.
+* `NodeList` now has a pretty complete set of `...First` and `...Last` methods.
+Thanks stephenramthun !
+
+Version 3.5.13
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/76?closed=1)
+* The Javadoc parser has received a lot of attention.
+
+Version 3.5.12
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/75?closed=1)
+* Thanks to un0btanium for fixing the readme file!
+
+Version 3.5.11
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/74?closed=1)
+* BREAKING: `AssignExpr.Operator.AND` is now `AssignExpr.Operator.BINARY_AND`.
+* BREAKING: `AssignExpr.Operator.OR` is now `AssignExpr.Operator.BINARY_OR`.
+* `getPrimaryTypeName` and `getPrimaryType` give access to the type that has the same name as the file it came from.
+* Enums will now get their constants aligned vertically if there are more than five.
+* You can now convert between `AssignExpr.Operator` and `AssignExpr.Operator` if you like.
+
+Version 3.5.10
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/73?closed=1)
+* JavaSymbolSolver is now in the same project as JavaParser, meaning they get released together from now on.
+* LexicalPreservingPrinter has had a big speed optimization.
+
+Version 3.5.9
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/72?closed=1)
+* BREAKING: the very confusing constructor `NodeList(Node)` (which sets the parent) was removed.
+* To avoid using the int type for token kinds, use the new `JavaToken.Kind` enum.
+It can convert to and from the int kind. 
+
+Version 3.5.8
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/71?closed=1)
+* the module name is now set to com.github.javaparser.core
+
+Version 3.5.7
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/70?closed=1)
+
+Version 3.5.6
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/69?closed=1)
+* `toSomeType()` methods have been added for many types that give more functional access to a subtype.
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.5.5
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/68?closed=1)
+* SourceRoot is now silent by default - look at the Log class if you want to change that. 
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.5.4
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/67?closed=1)
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.5.3
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/66?closed=1)
+* Unicode escapes (`\u1234`) are now retained in the AST,
+    but they are now only allowed in comments, string and character literals, and identifiers. 
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.5.2
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/65?closed=1)
+* The pretty printer now cleans up Javadoc comments.
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.5.1
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/64?closed=1)
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.5.0
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/63?closed=1)
+* A functional visitor API has been added. See [PR 1195](https://github.com/javaparser/javaparser/pull/1195) for now.
+* Build is working again on Windows thanks to Leonardo Herrera.
+* The pretty printer now has an option to order imports, also thanks to Leonardo Herrera.
+* Receiver parameters are now well-supported instead of being a hack. See [issue 1194](https://github.com/javaparser/javaparser/pull/1194) for a description.
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.4.4
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/62?closed=1)
+* BETA: the below work on Java Symbol Solver is still ongoing.
+
+Version 3.4.3
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/61?closed=1)
+* BETA: we're still doing work to integrate parts of [Java Symbol Solver](https://github.com/javaparser/javasymbolsolver) to simplify its API.
+* `VisitorMap` is joined by `VisitorSet` and `VisitorList`, 
+for when you want to store `Node`s in collection but don't want its default equals/hascode behaviour
+
+Version 3.4.2
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/60?closed=1)
+* BETA: we're doing work to integrate parts of [Java Symbol Solver](https://github.com/javaparser/javasymbolsolver) to simplify its API.
+* JDK 9 will compile JavaParser now.
+* [An official sample Maven setup](https://github.com/javaparser/javaparser-maven-sample) was added.
+
+Version 3.4.1
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/59?closed=1)
+* Two visitors were added: `NoCommentEqualsVisitor` and `NoCommentHashCodeVisitor` - 
+as the name implies you can use these to compare nodes without considering comments.
+Thanks Ryan Beckett!
+* `isSomeType()` methods have been added for many types that help avoid `instanceof`.
+* `asSomeType()` methods have been added for many types that help avoid casting to that type.
+* `ifSomeType()` methods have been added for many types, giving a nice functional way of doing if-is-type-then-cast-to-type-then-use.
+* The `LexicalPreservingPrinter` had its API changed a little: setup and printing are now separate things,
+so you don't have to drag an instance of `LexicalPreservingPrinter` through your code anymore.  
+* `traverseScope` was added to all nodes with a scope, so you can travel through the scope without tripping over (non-)optionality.
+
+
+Version 3.4.0
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/58?closed=1)
+* BREAKING: We missed a Java 9 feature which is now on board: try with resources can now refer to a resource declared outside of the statement.
+This means that the node type you get for those resources is now `Expression` instead of `VariableDeclarationExpr`.
+For Java 8 and below you can simply cast it to `VariableDeclarationExpr` again.
+See also the Javadoc for `TryStmt`.
+* You can now inspect the AST by exporting it to XML, JSON, YAML, or a Graphviz's dot diagram, thanks to Ryan Beckett!
+* `GenericVisitorWithDefaults` and `VoidVisitorWithDefaults` were added which function like empty visitors, 
+but all the visit methods call a default method by default.
+* Annotation support was cleaned up, adding some obscure locations where you can have annotations.
+* `EnumDeclaration` regained its constructor builder methods. They were accidentally lost around 3.2.2.
+* `ArrayType` now has an `origin` field which indicates in which position the array brackets were found.
+
+Version 3.3.5
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/57?closed=1)
+
+Version 3.3.4
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/56?closed=1)
+* `SourceZip` has been added.
+Use it to read source code from jars or zip files.
+Thank you @ryan-beckett !
+* JavaCC was upgraded to 7.0.2
+* A new option for the pretty printer was added.
+You can now wrap-and-column-align parameters of method calls.
+Thank you @tarilabs !
+
+Version 3.3.3
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/55?closed=1)
+* Parsing a partial java file (like an expression or statement) no longer ignores trailing code.
+* New memory saving option: turn off token list.
+
+Version 3.3.2
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/54?closed=1)
+* `VisitorMap` lets you override hashcode/equals for nodes when used as a key for a map.
+
+Version 3.3.1
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/53?closed=1)
+* The token list is now mutable - see methods on `JavaToken`.
+This caused mild breakage - some fields have become `Optional`.
+
+Version 3.3.0
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/52?closed=1)
+* Breaking: `TryStmt::tryBlock` and `EnclosedExpr::inner` were optional for no good reason. Now they are required.
+* You can now ask a `JavaToken` for its category, which is useful for examining the token list or doing syntax highlighting or so.
+* `enum` and `strictfp` can now be used as identifiers on lower Java versions.
+
+Version 3.2.12
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/51?closed=1)
+
+Version 3.2.11
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/50?closed=1)
+* We're up to date with the latest Java 9 module system again.
+
+Version 3.2.10
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/49?closed=1)
+* `Node.replace(old, new)` was added, including property-specific `X.replaceY(newY)` methods
+
+Version 3.2.9
+------------------
+Scrapped due to release problem.
+
+Version 3.2.8
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/48?closed=1)
+* Added `isInnerClass()` that checks if a `ClassOrInterfaceDeclaration` is an inner class (note: this is different from a nested class!)
+* @ryan-beckett contributed a huge [Eclipse setup guide](https://github.com/javaparser/javaparser/wiki/Eclipse-Project-Setup-Guide)
+
+Version 3.2.7
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/47?closed=1)
+* We now recover from some parse errors! [Here is an article](https://matozoid.github.io/2017/06/11/parse-error-recovery.html)
+
+Version 3.2.6
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/46?closed=1)
+* `EmptyMemberDeclaration` is gone! 
+It was deprecated for a while because it it was in the AST, but doesn't have any meaning in a Java program. 
+`EmptyStmt` was also deprecated, but that has been reverted. 
+This node *does* have meaning.
+
+Version 3.2.5
+------------------
+[issues resolved](https://github.com/javaparser/javaparser/milestone/45?closed=1)
+* `NodeWithCondition` was added on all nodes containing a condition.
+* Lots of work on improving lexical preservation.
+* If a file was parsed from a file system, you can now get path information etc. from `CompilationUnit`
+* API BREAKING: every node now points to its start and end token.
+Some of the API has started returning `TokenRange` instead of `Range` - you can call `toRange` to get the old object type.
+We may still change the naming of some of this code in the following month.
+
+Version 3.2.4
+------------------
+New style changelog, no more issue numbers, but a link: 
+[issues resolved](https://github.com/javaparser/javaparser/milestone/44?closed=1)
+and any notable changes:
+* the new method `Node.removeForced()` by removing it, or removing the first parent that is optional.
+This is different from `Node.remove()`, `remove()` only tries to remove the node from the parent and fails if it can't.
+* `FieldAccessExpr.scope` is now a required property.
+You might find some `get()`s in your code that are no longer necessary.
+* `ReferenceType` no longer has a type parameter, so every `ReferenceType<?>` can be replaced by `ReferenceType` now.
+
+Version 3.2.3
+------------------
+* 907 906 905 903 911 910 909 908 smaller improvements and fixes
+
+Version 3.2.2
+------------------
+Beta: `TreeStructureVisitor`.
+
+* 770 902 904 901 smaller improvements and fixes
+
+Version 3.2.1
+------------------
+Beta: `TreeStructureVisitor`.
+
+* Maven dependencies were updated to their latest versions 
+* 890 the concept of "method signature" now exists in JavaParser
+* 896 891 889 887 882 789 smaller improvements and fixes
+
+Version 3.2.0
+------------------
+The lexical preservation code is stable!
+
+Beta: `TreeStructureVisitor`.
+
+* 885 884 879 878 smaller improvements and fixes
+
+Version 3.1.4
+------------------
+This is the first version to parse Java 9.
+
+Beta: `TreeStructureVisitor`, and `LexicalPreservingPrinter`.
+
+* 872 873 874 787 Remaining Java 9 work.
+
+Version 3.1.3
+------------------
+Beta: `TreeStructureVisitor`, and `LexicalPreservingPrinter`.
+
+A start has been made on source level support. The default level is Java 8.
+It can be set to Java 9 like this for a parser *instance*:
+```java
+private final JavaParser parser = new JavaParser(new ParserConfiguration().setValidator(new Java9Validator()));
+```
+and like this for the static parse methods:
+```java
+JavaParser.getStaticConfiguration().setValidator(new Java9Validator());
+```
+
+* 862 552 "_" is an illegal identifier on source level 9.
+* 869 867 109 855 857 smaller improvements and fixes
+
+Version 3.1.2
+------------------
+Beta: `TreeStructureVisitor`, `ConcreteSyntaxModel`, and `LexicalPreservingPrinter`.
+
+* 594 849 831 a validation framework was introduced to inform about problems in the AST without needing to change the grammar,
+and without requiring parsing code.
+It is open for extension by users.
+* 852 853 826 832 846 839 smaller improvements and fixes
+
+Version 3.1.1
+------------------
+Beta: `TreeStructureVisitor`, `ConcreteSyntaxModel`, and `LexicalPreservingPrinter`.
+
+* 654 124 lexical preservation (printing source code with the same formatting it had when parsing) has been added.
+    Thank you @ftomassetti for a lot of work! 
+* 554 800 first (big) step towards Java 9 support: JavaParser can read project Jigsaw module definitions.
+* 795 786 751 extend the TreeVisitor with more traversal options. Thanks @ryan-beckett!
+* 791 `GenericListVisitorAdapter` has been added which collects its results in a list. Thanks @Gottox!
+* 815 798 797 813 clean up Problem text
+* 819 818 817 816 441 809 808 807 fix various absurd annotation related issues. 
+* 777 805 802 796 790 792 793 781 784 785 783 782 779 357 799 763 smaller improvements and fixes
+
+Version 3.1.0
+------------------
+Beta: `TreeStructureVisitor` and `ConcreteSyntaxModel`.
+
+* 705 755 Add the concrete syntax model, which will give you information about the exact syntax a certain nodes matches.
+
+* 777 smaller improvements and fixes
+
+Version 3.1.0-beta.2
+------------------
+This version is a beta because `TreeStructureVisitor` is not in its definite state yet.
+
+* 762 761 772 merge `javaparser-metamodel` and `javaparser-generator-utils` into `javaparser-core`.
+* 766 the `ModifierVisitor` is now created by a code generator. Its behaviour has been made logical, and may give different results than before.
+* 755 `ConstructorDeclaration` and `MethodDeclaration` now share a parent: `CallableDeclaration`
+* 687 759 773 769 768 767 765 759 smaller improvements and fixes
+
+Version 3.1.0-beta.1
+------------------
+This version is a beta because there are a lot of new features that may still change.
+
+This version needs a minor version increase because of a backwards compatability issue: 
+* 719 `getJavadoc`, `getJavadocComment` and `getComment` could return null. Our promise was to return `Optional`, so that is what they do now.
+
+New:
+* 658 718 736 737 we have created a metamodel.
+It gives information about the structure of the various AST nodes, as if you are introspecting them.
+You can find it in `javaparser-metamodel`, the main class is `JavaParserMetaModel`
+* 353 365 visitors are no longer hand made, they are now generated from the metamodel. This should make them 100% reliable.
+Affected visitors are: `GenericVisitorAdapter`, `EqualsVisitor`, `VoidVisitorAdapter`, `VoidVisitor`, `GenericVisitor`, `HashCodeVisitor`, `CloneVisitor`.
+
+If you want to generate your own visitors, you can use the `VisitorGenerator` class from `javaparser-core-generators`
+
+If you want to reuse the code generation utilities, look at module `javaparser-generator-utils` - there is a very useful `SourceRoot` class in there that takes away a lot of file management troubles.
+* 538 735 `TreeStructureVisitor` has been added, which should be considered beta.
+* 220 733 717 749 745 750 743 748 666 732 746 734 733 smaller improvements and fixes
+
+Version 3.0.1
+------------------
+* 699 433 325 Javadoc can now be parsed
+* 703 696 added NodeWithOptionalScope
+* 702 FieldAccessExpr now implements NodeWithSimpleName, *which means that "field" has been renamed to "name"*
+* 707 706 improve range of array types and levels
+* 709 smaller improvements and fixes
+
+Version 3.0.0
+------------------
+* 695 697 689 680 693 691 682 690 677 679 688 684 683 smaller improvements and fixes
+
+Version 3.0.0-RC.4
+------------------
+* 668 669 TypeDeclarationStmt became LocalClassDeclarationStmt
+* 347 665 every node now has some documentation
+* 660 670 673 four types of import declaration have been merged back into the old ImportDeclaration
+* 659 The pretty printer can now take customized visitors 
+* 650 671 672 674 524 smaller improvements and fixes
+
+Version 3.0.0-RC.3
+------------------
+* 639 622 632 657 656 652 653 647 648 645 194 643 630 624 628 627 626 625 623 cleanups, small fixes, and general housekeeping
+
+Version 3.0.0-RC.2
+------------------
+* 593 EmptyImportDeclaration and NonEmptyImportDeclaration have been removed
+* 612 VariableDeclaratorId has been removed. It has been substituted by "SimpleName name"
+* 614 617 the list of tokens has been linearized and simplified
+* 615 support for arrays has once more been changed. See [the issue](https://github.com/javaparser/javaparser/issues/592) 
+* 580 453 380 618 580 611 610 424 608 smaller improvements and fixes
+
+Version 3.0.0-RC.1
+------------------
+* 499 601 renames many fields to be more consistent
+* 596 605 602 604 smaller improvements and fixes
+
+Version 3.0.0-alpha.11
+------------------
+* 547 595 Node.range is now using Optional instead of Range.UNKNOWN
+* 584 588 548 585 bug fixes and improvements
+
+Version 3.0.0-alpha.10
+------------------
+* 578 579 577 575 290 570 568 567 562 564 551 bug fixes and improvements
+
+Version 3.0.0-alpha.9
+------------------
+* 403 358 549 Make all names nodes: either SimpleName or Name. This makes every name in the AST visitable. NameExpr is now a wrapper to use SimpleName in an expression.
+* 516 536 use Optional<> for return values.
+* 556 557 558 550 small improvements and fixes.
+* 560 559 make nodes observable.
+
+Version 3.0.0-alpha.8
+------------------
+* 344 529 turn DumpVisitor into an official PrettyPrinter
+* 532 508 427 530 531 513 528 cleanups
+
+Version 3.0.0-alpha.7
+------------------
+* 515 roll back attempt at using Optional
+* 522 504 make NodeList not a Node (restores parent/children behaviour to before alpha.4)
+* 527 526 rename getChildrenNodes to getChildNodes
+* 525 495 520 bug fix
+
+Version 3.0.0-alpha.6
+------------------
+* 503 modified ImportDeclaration hierarchy to have getters for static and "asterisk" again
+* 506 bug fix
+
+Version 3.0.0-alpha.5
+------------------
+* 451 null is no longer allowed in the AST. [See last post in issue](https://github.com/javaparser/javaparser/issues/451)
+* 501 421 420 316 use a special type of list for nodes: NodeList. [See last post in issue](https://github.com/javaparser/javaparser/issues/421)
+
+Version 3.0.0-alpha.4
+------------------
+* 463 471 nodes can now be removed easily
+* 491 import handling changed. Instead of "ImportDeclaration", we now have the four types of import as described in the JLS. [See issue](https://github.com/javaparser/javaparser/pull/491)
+* 452 355 474 494 various improvements
+* 493 492 485 Simplify the JavaParser interface
+
+Version 3.0.0-alpha.3
+------------------
+* 112 237 466 465 461 460 458 457 fundamentally changes how we deal with arrays. [It is explained in the last post here](https://github.com/javaparser/javaparser/issues/237)
+* 472 456 makes the "data" field on every node more structured.
+* 477 468 refactor TypeArguments. You will find that TypeArguments is no longer a type, it is just a list in some nodes.
+* 482 adds the "nodeTypes" packages to the osgi export.
+* 479 476 makes all setters on nodes return this so they become chainable.
+* 473 437 clean up CloneVisitor.
+
+Version 3.0.0-alpha.2
+------------------
+* 157 a new parser frontend, check https://github.com/javaparser/javaparser/pull/447 for explanations
+* 435 more builder methods like 400 and 405
+* 111 440 443 444 445 446 bugs & cleanups
+
+Version 3.0.0-alpha.1
+------------------
+* 400 405 introduce many "builder" style methods for constructing code. Thanks DeepSnowNeeL!
+* 409 remove ASTHelper (methods are now on specific Node subclasses)
+* 414 JavaParser can now be instantiated and reused. InstanceJavaParser removed
+* 418 417 411 408 bugs
+* 367 420 407 402 various cleanups
+
+Version 2.5.1
+-------------
+* 394 OSGi manifest added
+* 391 fix ModifierVisitor NullPointerException bug
+* 385 a few new parse methods
+* 386 fix dumping an empty import (a single ; after the package declaration)
+
+Version 2.5.0
+-------------
+API breaking changes:
+
+* 191: moved TreeVisitor to visitor package
+* 368, 162, 303, 302, 360: use correct type in some places.
+* 371: code is now compiled with Java 8
+* 342, 331: ModifierVisitorAdapter detects and removes broken nodes
+* 328, 270: upgrade JavaCC (use TokenMgrException now)
+Other changes:
+
+* 297: enable access to tokens.
+* 341, 361: node positions are now OO
+* 211, 373: escaping of \n \r for string literals
+* 336, 276, 141: JavaDoc support now works
+* 337, 281: reorganize the stream reading code
+* 343, 309, 332, 57: take advantage of common interfaces
+* 329, 326, 327: deal with platform issues
+* 163, 236, 252, 296, 269, 339, 321, 322, 252, 253, 293, 295: various fixes
+* 310, 311, 313, 301, 294: some code clean-ups 
+
+Version 2.4.0
+-------------
+* several fixes in DumpVisitor for bugs due to lazy initialization
+* make TypeDeclaration implements DocumentableNode directly
+* TypedNode interface introduced
+* introduce MultiBoundType
+* refactored IntersectionType and UnionType
+* refactored CatchClause
+* parsing annotations in throws declarations
+* parse orphan semicolons in import statements
+* added PackageDeclaration.getPackageName
+* solved issue with newlines in string literals
+* fixed handling of UnknownType in EqualsVisitor
+* improvements to CommentsParser
+* removing old grammar
+
+Version 2.3.0
+-------------
+* ClassOrInterfaceType implements NamedNode
+* DumpVisitor can now be extended
+* Improved documentation
+* AST: lists are now lazy initialized
+
+Version 2.1.0
+-------------
+* Features
+  * [#75 performance improvement for `PositionUtils.sortByBeginPosition`](https://github.com/javaparser/javaparser/issues/75)
+  * [#64 In getDeclarationAsString parameter names should be optional](https://github.com/javaparser/javaparser/issues/64)
+* Bugfixes
+  * [#79 Fix NPE in `ConstructorDeclaration.getDeclarationAsString`](https://github.com/javaparser/javaparser/pull/79)
+  * [#86 Add missing functions to ModifierVisitorAdapter](https://github.com/javaparser/javaparser/pull/86)
+  * [#82 set LambdaExpr as parent of its child nodes](https://github.com/javaparser/javaparser/issues/82)
+  * [#87 implement `setJavadoc` and `getJavadoc` at various classes](https://github.com/javaparser/javaparser/issues/87)
+  * [#96 Fixed encoding issue in `Javaparser.parse`](https://github.com/javaparser/javaparser/pull/96)
+  * [#85 Casting a lambda expression causes a parsing failure](https://github.com/javaparser/javaparser/issues/85)
+  * [#88 `MethodReferenceExpr` and `TypeExpr` don't set themselves as parents](https://github.com/javaparser/javaparser/issues/88)
+* Internal
+  * [#89 CommentsParser.State contains unused fields](https://github.com/javaparser/javaparser/issues/89)
+  * Switched from drone.io to [Travis](https://travis-ci.org/javaparser/javaparser)
+  * [#105 Enforce compiling the library for a certain Java version](https://github.com/javaparser/javaparser/pull/105)
+
+[Code changes](https://github.com/javaparser/javaparser/compare/javaparser-parent-2.0.0...master)
+
+Version 2.0.0
+-------------
+* support Java 8
+
+Version 1.0.8 (2010-01-17)
+-------------
+* Fixed issues:
+	* Issue 17: A refactor suggestion for AnnotationExpr and its subclasses
+	* Issue 21: Java 5 JavaParser compiled JARs
+	* Issue 22: Please use java.lang.reflect.Modifier constants in japa.parser.ast.body.ModifierSet
+	* Issue 27: Implement the "equal" method
+	* Issue 30: equals and hashCode methods
+
+Version 1.0.7 (2009-04-12)
+-------------
+* Issue 19 fixed: 
+* Tests changed to run with junit 4 
+
+Version 1.0.6 (2009-01-11)
+-------------
+* Issue 11 fixed: changed method get/setPakage to get/setPackage in the class CompilationUnit
+* Created new visitor adapter to help AST modification: ModifierVisitorAdapter
+* Changed visitor adapters to abstract  
+
+Version 1.0.5 (2008-10-26)
+-------------
+* Created simplified constructors in the nodes of the AST (without positional arguments) 
+* Created ASTHelper class with some helpful methods (more methods are still needed)
+
+Version 1.0.4 (2008-10-07)
+-------------
+* Moved to javacc 4.1.
+* The java_1_5.jj can be build alone without compilation errors
+
+Version 1.0.3 (2008-09-06)
+-------------
+* Removed SuperMemberAccessExpr class, it was no longer used
+* Removed the methods get/setTypeArgs() from ArrayCreationExpr, this node shouldn't have these methods.
+* Fixed the bug with start/end position of the nodes IntegerLiteralMinValueExpr and LongLiteralMinValueExpr  
+* The methods get/setAnnotations() from all BodyDeclaration subclasses were pushed down to BodyDeclaration class 
+
+Version 1.0.2 (2008-07-20)
+-------------
+* Issue fixed: Issue 1: Add support for editing AST nodes or create new ones
+
+Version 1.0.1 (2008-07-01)
+-------------
+* Issue fixed: Issue 5: end line and end column equal to begin line and begin column
+
+Version 1.0.0 (2008-06-25)
+-------------
+* Changed version numbering, starting version 1.0.0
+* Javadoc done for packages:
+    * japa.parser
+    * japa.parser.ast
+* Corrected bug when parsing in multithread: 
+    * JavaParser.setCacheParser(false) must be called before to use the parser concurrent 
+
+2008-06-19
+-------------
+* No code changes, added binary distribution to download page 
+
+2008-06-11
+-------------
+* Bug corrected: NPE in VoidVisitorAdapter 
+	* http://code.google.com/p/javaparser/issues/detail?id=2
+
+2008-06-09
+-------------
+* Added Adapters for de visitors
+
+2008-05-28
+-------------
+* This project now is published at Google Code:
+	* http://code.google.com/p/javaparser/
+
+2008-05-25
+-------------
+* Added support for comments and javadoc to the tree. 
+	* Javadocs are stored directly to members (BodyDeclaration and all deriveds (classes, methods, fields, etc.)), accessible by the method getJavadoc().
+	* All comments are stored in the CompilationUnit, accessible by the method getComments().
+
+2008-04-01
+-------------
+* Changed all nodes public attributes to be private and created getters to access them
+* Changed the methods of the Node getLine e getColumn to getBeginLine and getBeginColumn
+* Added the methods getEndLine and getEndColumn to the Node class (works only in the BlockNode)
+
+2007-12-22
+-------------
+* Corrected ConditionalExpression bug
+
+2007-10-21
+-------------
+* Added LGPL License
+
+2007-10-21
+-------------
+* Bugs corrected:  
+  * Created PackageDeclaration member of CompilationUnit to add suport for annotations in the package declaration
+  * Parameterized anonymous constructor invocation
+  * Explicit constructor invotation Type Arguments
+  * ctrl+z ("\u001A") ar end of compilation unit
+
+2007-10-09
+-------------
+* EnumConstantDeclaration annotation support corrected
+* Parssing Java Unicode escape characters suport added
+
+2007-10-03
+-------------
+* Bug corrected: "MotifComboPopup.this.super()" statement was generating parser error
+	                    
+2007-10-01
+-------------
+* Bug corrected: Casting signed primitive values
+```
+	double d = (double) -1;
+	                    ^
+```
+2007-08-06
+-------------
+* Bug with the single line comments in the final of the unit corrected
+
+2007-07-31
+-------------
+* Fixed the bug with the following expression:  `Class c = (int.class);`
+
+2007-06-26
+-------------
+* Bug fixes from Leon Poyyayil work
+	* suport for hex floating point
+	* unicode digits in indentifier 
+	* MemberValueArrayInitializer
+
+2007-03-09
+-------------
+* Long and Integer literal MIN_VALUE bug	
+
+2007-02-24
+-------------
+* '\0' bug fixed	
+
+2007-02-01
+-------------
+* Many bug fixes
+* Added line/column to nodes
diff --git a/dev-files/JavaParser-eclipse.xml b/dev-files/JavaParser-eclipse.xml
new file mode 100644
index 0000000..853811c
--- /dev/null
+++ b/dev-files/JavaParser-eclipse.xml
@@ -0,0 +1,295 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<profiles version="12">
+<profile kind="CodeFormatterProfile" name="JavaParser" version="12">
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="119"/>
+<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="18"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
+<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="18"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="false"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
+<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="120"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
+<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
+</profile>
+</profiles>
diff --git a/dev-files/JavaParser-idea.xml b/dev-files/JavaParser-idea.xml
new file mode 100644
index 0000000..9745dc8
--- /dev/null
+++ b/dev-files/JavaParser-idea.xml
@@ -0,0 +1,38 @@
+<code_scheme name="JavaParser">
+  <option name="OTHER_INDENT_OPTIONS">
+    <value>
+      <option name="INDENT_SIZE" value="4" />
+      <option name="CONTINUATION_INDENT_SIZE" value="8" />
+      <option name="TAB_SIZE" value="4" />
+      <option name="USE_TAB_CHARACTER" value="true" />
+      <option name="SMART_TABS" value="true" />
+      <option name="LABEL_INDENT_SIZE" value="0" />
+      <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+      <option name="USE_RELATIVE_INDENTS" value="false" />
+    </value>
+  </option>
+  <option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
+  <option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
+  <option name="WRAP_COMMENTS" value="true" />
+  <XML>
+    <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+  </XML>
+  <codeStyleSettings language="JAVA">
+    <option name="RIGHT_MARGIN" value="120" />
+    <indentOptions>
+      <option name="SMART_TABS" value="true" />
+    </indentOptions>
+  </codeStyleSettings>
+  <codeStyleSettings language="Scala">
+    <indentOptions>
+      <option name="USE_TAB_CHARACTER" value="true" />
+      <option name="SMART_TABS" value="true" />
+    </indentOptions>
+  </codeStyleSettings>
+  <codeStyleSettings language="XML">
+    <indentOptions>
+      <option name="USE_TAB_CHARACTER" value="true" />
+      <option name="SMART_TABS" value="true" />
+    </indentOptions>
+  </codeStyleSettings>
+</code_scheme>
\ No newline at end of file
diff --git a/javaparser-core-generators/javaparser-core-generators.iml b/javaparser-core-generators/javaparser-core-generators.iml
new file mode 100644
index 0000000..7843639
--- /dev/null
+++ b/javaparser-core-generators/javaparser-core-generators.iml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="javaparser-core" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-core-generators/pom.xml b/javaparser-core-generators/pom.xml
new file mode 100644
index 0000000..58eecf8
--- /dev/null
+++ b/javaparser-core-generators/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>javaparser-parent</artifactId>
+        <groupId>com.github.javaparser</groupId>
+        <version>3.5.16-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-core-generators</artifactId>
+    <description>A code generator framework, and the generators for javaparser-core</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>run-core-generators</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>generate-javaparser-core</id>
+                                <phase>test</phase>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <classpathScope>test</classpathScope>
+                            <mainClass>com.github.javaparser.generator.core.CoreGenerator</mainClass>
+                            <arguments>
+                                <argument>${project.basedir}</argument>
+                            </arguments>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/Generator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/Generator.java
new file mode 100644
index 0000000..f7860b0
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/Generator.java
@@ -0,0 +1,104 @@
+package com.github.javaparser.generator;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.CallableDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.utils.SourceRoot;
+
+import javax.annotation.Generated;
+import java.util.List;
+
+import static com.github.javaparser.ast.NodeList.toNodeList;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * A general pattern that the generators in this module will follow.
+ */
+public abstract class Generator {
+    protected final SourceRoot sourceRoot;
+
+    protected Generator(SourceRoot sourceRoot) {
+        this.sourceRoot = sourceRoot;
+    }
+
+    public abstract void generate() throws Exception;
+
+    protected <T extends Node & NodeWithAnnotations<?>> void annotateGenerated(T node) {
+        annotate(node, Generated.class, new StringLiteralExpr(getClass().getName()));
+    }
+
+    protected <T extends Node & NodeWithAnnotations<?>> void annotateSuppressWarnings(T node) {
+        annotate(node, SuppressWarnings.class, new StringLiteralExpr("unchecked"));
+    }
+
+    protected void annotateOverridden(MethodDeclaration method) {
+        annotate(method, Override.class, null);
+    }
+
+    private <T extends Node & NodeWithAnnotations<?>> void annotate(T node, Class<?> annotation, Expression content) {
+        node.setAnnotations(
+                node.getAnnotations().stream()
+                        .filter(a -> !a.getNameAsString().equals(annotation.getSimpleName()))
+                        .collect(toNodeList()));
+
+        if (content != null) {
+            node.addSingleMemberAnnotation(annotation.getSimpleName(), content);
+        } else {
+            node.addMarkerAnnotation(annotation.getSimpleName());
+        }
+        node.tryAddImportToParentCompilationUnit(annotation);
+    }
+
+    /**
+     * Utility method that looks for a method or constructor with an identical signature as "callable" and replaces it
+     * with callable. If not found, adds callable. When the new callable has no javadoc, any old javadoc will be kept.
+     */
+    protected void addOrReplaceWhenSameSignature(ClassOrInterfaceDeclaration containingClassOrInterface, CallableDeclaration<?> callable) {
+        addMethod(containingClassOrInterface, callable, () -> containingClassOrInterface.addMember(callable));
+    }
+
+    /**
+     * Utility method that looks for a method or constructor with an identical signature as "callable" and replaces it
+     * with callable. If not found, fails. When the new callable has no javadoc, any old javadoc will be kept. The
+     * method or constructor is annotated with the generator class.
+     */
+    protected void replaceWhenSameSignature(ClassOrInterfaceDeclaration containingClassOrInterface, CallableDeclaration<?> callable) {
+        addMethod(containingClassOrInterface, callable,
+                () -> {
+                    throw new AssertionError(f("Wanted to regenerate a method with signature %s in %s, but it wasn't there.", callable.getSignature(), containingClassOrInterface.getNameAsString()));
+                });
+    }
+
+    private void addMethod(
+            ClassOrInterfaceDeclaration containingClassOrInterface,
+            CallableDeclaration<?> callable,
+            Runnable onNoExistingMethod) {
+        List<CallableDeclaration<?>> existingCallables = containingClassOrInterface.getCallablesWithSignature(callable.getSignature());
+        if (existingCallables.isEmpty()) {
+            onNoExistingMethod.run();
+            return;
+        }
+        if (existingCallables.size() > 1) {
+            throw new AssertionError(f("Wanted to regenerate a method with signature %s in %s, but found more than one.", callable.getSignature(), containingClassOrInterface.getNameAsString()));
+        }
+        final CallableDeclaration<?> existingCallable = existingCallables.get(0);
+        callable.setJavadocComment(callable.getJavadocComment().orElse(existingCallable.getJavadocComment().orElse(null)));
+        annotateGenerated(callable);
+        containingClassOrInterface.getMembers().replace(existingCallable, callable);
+    }
+
+    /**
+     * Removes all methods from containingClassOrInterface that have the same signature as callable. This is not used by
+     * any code, but it is useful when changing a generator and you need to get rid of a set of outdated methods.
+     */
+    protected void removeMethodWithSameSignature(ClassOrInterfaceDeclaration containingClassOrInterface, CallableDeclaration<?> callable) {
+        for (CallableDeclaration<?> existingCallable : containingClassOrInterface.getCallablesWithSignature(callable.getSignature())) {
+            containingClassOrInterface.remove(existingCallable);
+        }
+    }
+
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/NodeGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/NodeGenerator.java
new file mode 100644
index 0000000..18ab60d
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/NodeGenerator.java
@@ -0,0 +1,46 @@
+package com.github.javaparser.generator;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.CallableDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.utils.Log;
+import com.github.javaparser.utils.Pair;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.io.IOException;
+import java.util.List;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Makes it easier to generate code in the core AST nodes. The generateNode method will get every node type passed to
+ * it, ready for modification.
+ */
+public abstract class NodeGenerator extends Generator {
+    protected NodeGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    public final void generate() throws Exception {
+        Log.info("Running %s", getClass().getSimpleName());
+        for (BaseNodeMetaModel nodeMetaModel : JavaParserMetaModel.getNodeMetaModels()) {
+            Pair<CompilationUnit, ClassOrInterfaceDeclaration> result = parseNode(nodeMetaModel);
+            generateNode(nodeMetaModel, result.a, result.b);
+        }
+        after();
+    }
+
+    protected Pair<CompilationUnit, ClassOrInterfaceDeclaration> parseNode(BaseNodeMetaModel nodeMetaModel) {
+        CompilationUnit nodeCu = sourceRoot.parse(nodeMetaModel.getPackageName(), nodeMetaModel.getTypeName() + ".java");
+        ClassOrInterfaceDeclaration nodeCoid = nodeCu.getClassByName(nodeMetaModel.getTypeName()).orElseThrow(() -> new AssertionError("Can't find class"));
+        return new Pair<>(nodeCu, nodeCoid);
+    }
+
+    protected void after() throws Exception {
+
+    }
+
+    protected abstract void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) throws Exception;
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/VisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/VisitorGenerator.java
new file mode 100644
index 0000000..16b5ef4
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/VisitorGenerator.java
@@ -0,0 +1,82 @@
+package com.github.javaparser.generator;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.utils.Log;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.util.Optional;
+
+import static com.github.javaparser.ast.Modifier.PUBLIC;
+
+/**
+ * Makes it easier to generate visitor classes.
+ * It will create missing visit methods on the fly,
+ * and will ask you to fill in the bodies of the visit methods.
+ */
+public abstract class VisitorGenerator extends Generator {
+    private final String pkg;
+    private final String visitorClassName;
+    private final String returnType;
+    private final String argumentType;
+    private final boolean createMissingVisitMethods;
+
+    protected VisitorGenerator(SourceRoot sourceRoot, String pkg, String visitorClassName, String returnType, String argumentType, boolean createMissingVisitMethods) {
+        super(sourceRoot);
+        this.pkg = pkg;
+        this.visitorClassName = visitorClassName;
+        this.returnType = returnType;
+        this.argumentType = argumentType;
+        this.createMissingVisitMethods = createMissingVisitMethods;
+    }
+
+    public final void generate() throws Exception {
+        Log.info("Running %s", getClass().getSimpleName());
+
+        final CompilationUnit compilationUnit = sourceRoot.tryToParse(pkg, visitorClassName + ".java").getResult().get();
+
+        Optional<ClassOrInterfaceDeclaration> visitorClassOptional = compilationUnit.getClassByName(visitorClassName);
+        if (!visitorClassOptional.isPresent()) {
+            visitorClassOptional = compilationUnit.getInterfaceByName(visitorClassName);
+        }
+        final ClassOrInterfaceDeclaration visitorClass = visitorClassOptional.get();
+
+        JavaParserMetaModel.getNodeMetaModels().stream()
+                .filter((baseNodeMetaModel) -> !baseNodeMetaModel.isAbstract())
+                .forEach(node -> generateVisitMethodForNode(node, visitorClass, compilationUnit));
+        after();
+    }
+
+    protected void after() throws Exception {
+
+    }
+
+    private void generateVisitMethodForNode(BaseNodeMetaModel node, ClassOrInterfaceDeclaration visitorClass, CompilationUnit compilationUnit) {
+        final Optional<MethodDeclaration> existingVisitMethod = visitorClass.getMethods().stream()
+                .filter(m -> m.getNameAsString().equals("visit"))
+                .filter(m -> m.getParameter(0).getType().toString().equals(node.getTypeName()))
+                .findFirst();
+
+        if (existingVisitMethod.isPresent()) {
+            generateVisitMethodBody(node, existingVisitMethod.get(), compilationUnit);
+        } else if (createMissingVisitMethods) {
+            MethodDeclaration newVisitMethod = visitorClass.addMethod("visit")
+                    .addParameter(node.getTypeNameGenerified(), "n")
+                    .addParameter(argumentType, "arg")
+                    .setType(returnType);
+            if (!visitorClass.isInterface()) {
+                newVisitMethod
+                        .addAnnotation(new MarkerAnnotationExpr(new Name("Override")))
+                        .addModifier(PUBLIC);
+            }
+            generateVisitMethodBody(node, newVisitMethod, compilationUnit);
+        }
+    }
+
+    protected abstract void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit);
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/CoreGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/CoreGenerator.java
new file mode 100644
index 0000000..c1aa5f9
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/CoreGenerator.java
@@ -0,0 +1,73 @@
+package com.github.javaparser.generator.core;
+
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.generator.core.node.*;
+import com.github.javaparser.generator.core.other.TokenKindGenerator;
+import com.github.javaparser.generator.core.visitor.*;
+import com.github.javaparser.utils.Log;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Generates all generated visitors in the javaparser-core module.
+ * Suggested usage is by running the run_core_generators.sh script.
+ * You may want to run_metamodel_generator.sh before that.
+ */
+public class CoreGenerator {
+    private static final ParserConfiguration parserConfiguration = new ParserConfiguration()
+//                                .setStoreTokens(false)
+//                                .setAttributeComments(false)
+//                                .setLexicalPreservationEnabled(true)
+            ;
+
+    public static void main(String[] args) throws Exception {
+        if (args.length != 1) {
+            throw new RuntimeException("Need 1 parameter: the JavaParser source checkout root directory.");
+        }
+        Log.setAdapter(new Log.StandardOutStandardErrorAdapter());
+        final Path root = Paths.get(args[0], "..", "javaparser-core", "src", "main", "java");
+        final SourceRoot sourceRoot = new SourceRoot(root, parserConfiguration)
+//                .setPrinter(LexicalPreservingPrinter::print)
+                ;
+
+        final Path generatedJavaCcRoot = Paths.get(args[0], "..", "javaparser-core", "target", "generated-sources", "javacc");
+        final SourceRoot generatedJavaCcSourceRoot = new SourceRoot(generatedJavaCcRoot, parserConfiguration)
+//                .setPrinter(LexicalPreservingPrinter::print)
+                ;
+
+        new CoreGenerator().run(sourceRoot, generatedJavaCcSourceRoot);
+
+        sourceRoot.saveAll();
+    }
+
+    private void run(SourceRoot sourceRoot, SourceRoot generatedJavaCcSourceRoot) throws Exception {
+        new TypeCastingGenerator(sourceRoot).generate();
+        new GenericListVisitorAdapterGenerator(sourceRoot).generate();
+        new GenericVisitorAdapterGenerator(sourceRoot).generate();
+        new GenericVisitorWithDefaultsGenerator(sourceRoot).generate();
+        new EqualsVisitorGenerator(sourceRoot).generate();
+        new ObjectIdentityEqualsVisitorGenerator(sourceRoot).generate();
+        new NoCommentEqualsVisitorGenerator(sourceRoot).generate();
+        new VoidVisitorAdapterGenerator(sourceRoot).generate();
+        new VoidVisitorGenerator(sourceRoot).generate();
+        new VoidVisitorWithDefaultsGenerator(sourceRoot).generate();
+        new GenericVisitorGenerator(sourceRoot).generate();
+        new HashCodeVisitorGenerator(sourceRoot).generate();
+        new ObjectIdentityHashCodeVisitorGenerator(sourceRoot).generate();
+        new NoCommentHashCodeVisitorGenerator(sourceRoot).generate();
+        new CloneVisitorGenerator(sourceRoot).generate();
+        new ModifierVisitorGenerator(sourceRoot).generate();
+
+        new PropertyGenerator(sourceRoot).generate();
+        new RemoveMethodGenerator(sourceRoot).generate();
+        new ReplaceMethodGenerator(sourceRoot).generate();
+        new CloneGenerator(sourceRoot).generate();
+        new GetMetaModelGenerator(sourceRoot).generate();
+        new MainConstructorGenerator(sourceRoot).generate();
+        new FinalGenerator(sourceRoot).generate();
+        new AcceptGenerator(sourceRoot).generate();
+        new TokenKindGenerator(sourceRoot, generatedJavaCcSourceRoot).generate();
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/AcceptGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/AcceptGenerator.java
new file mode 100644
index 0000000..9ab2bf3
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/AcceptGenerator.java
@@ -0,0 +1,34 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+import static com.github.javaparser.JavaParser.parseBodyDeclaration;
+
+public class AcceptGenerator extends NodeGenerator {
+    private final MethodDeclaration genericAccept;
+    private final MethodDeclaration voidAccept;
+
+    public AcceptGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+        genericAccept = parseBodyDeclaration("@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) { return v.visit(this, arg); }").asMethodDeclaration();
+        voidAccept = parseBodyDeclaration("@Override public <A> void accept(final VoidVisitor<A> v, final A arg) { v.visit(this, arg); }").asMethodDeclaration();
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        if(nodeMetaModel.isAbstract()){
+            return;
+        }
+        nodeCu.addImport(GenericVisitor.class);
+        nodeCu.addImport(VoidVisitor.class);
+        addOrReplaceWhenSameSignature(nodeCoid, genericAccept);
+        addOrReplaceWhenSameSignature(nodeCoid, voidAccept);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/CloneGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/CloneGenerator.java
new file mode 100644
index 0000000..6a788b4
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/CloneGenerator.java
@@ -0,0 +1,29 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+import static com.github.javaparser.JavaParser.parseBodyDeclaration;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+public class CloneGenerator extends NodeGenerator {
+    public CloneGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        nodeCu.addImport(CloneVisitor.class);
+        MethodDeclaration cloneMethod = (MethodDeclaration) parseBodyDeclaration(f(
+                "@Override public %s clone() { return (%s) accept(new CloneVisitor(), null); }",
+                nodeMetaModel.getTypeNameGenerified(),
+                nodeMetaModel.getTypeNameGenerified()
+        ));
+        addOrReplaceWhenSameSignature(nodeCoid, cloneMethod);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/FinalGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/FinalGenerator.java
new file mode 100644
index 0000000..8e8cef2
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/FinalGenerator.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+public class FinalGenerator extends NodeGenerator {
+    public FinalGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        nodeCoid.setFinal(!nodeMetaModel.isAbstract());
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/GetMetaModelGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/GetMetaModelGenerator.java
new file mode 100644
index 0000000..750c52b
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/GetMetaModelGenerator.java
@@ -0,0 +1,30 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+import static com.github.javaparser.JavaParser.parseBodyDeclaration;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+public class GetMetaModelGenerator extends NodeGenerator {
+    public GetMetaModelGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        final MethodDeclaration getMetaModelMethod = (MethodDeclaration) parseBodyDeclaration(f("%s public %s getMetaModel() { return JavaParserMetaModel.%s; }",
+                nodeMetaModel.isRootNode() ? "" : "@Override",
+                nodeMetaModel.getClass().getSimpleName(),
+                nodeMetaModel.getMetaModelFieldName()));
+
+        addOrReplaceWhenSameSignature(nodeCoid, getMetaModelMethod);
+        nodeCu.addImport(nodeMetaModel.getClass().getName());
+        nodeCu.addImport(JavaParserMetaModel.class);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/MainConstructorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/MainConstructorGenerator.java
new file mode 100644
index 0000000..8f71589
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/MainConstructorGenerator.java
@@ -0,0 +1,54 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+import com.github.javaparser.utils.SeparatedItemStringBuilder;
+import com.github.javaparser.utils.SourceRoot;
+
+import static com.github.javaparser.JavaParser.parseExplicitConstructorInvocationStmt;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+public class MainConstructorGenerator extends NodeGenerator {
+    public MainConstructorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        if (nodeMetaModel.is(Node.class)) {
+            return;
+        }
+        ConstructorDeclaration constructor = new ConstructorDeclaration()
+                .setPublic(true)
+                .setName(nodeCoid.getNameAsString())
+                .addParameter(TokenRange.class, "tokenRange")
+                .setJavadocComment("\n     * This constructor is used by the parser and is considered private.\n     ");
+
+        BlockStmt body = constructor.getBody();
+
+        SeparatedItemStringBuilder superCall = new SeparatedItemStringBuilder("super(", ", ", ");");
+        superCall.append("tokenRange");
+        for (PropertyMetaModel parameter : nodeMetaModel.getConstructorParameters()) {
+            constructor.addParameter(parameter.getTypeNameForSetter(), parameter.getName());
+            if (nodeMetaModel.getDeclaredPropertyMetaModels().contains(parameter)) {
+                body.addStatement(f("%s(%s);", parameter.getSetterMethodName(), parameter.getName()));
+            } else {
+                superCall.append(parameter.getName());
+            }
+        }
+
+        body.getStatements().addFirst(parseExplicitConstructorInvocationStmt(superCall.toString()));
+
+        body.addStatement("customInitialization();");
+
+        addOrReplaceWhenSameSignature(nodeCoid, constructor);
+        nodeCu.addImport(TokenRange.class);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/PropertyGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/PropertyGenerator.java
new file mode 100644
index 0000000..9ac69ed
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/PropertyGenerator.java
@@ -0,0 +1,145 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.util.*;
+
+import static com.github.javaparser.JavaParser.parseType;
+import static com.github.javaparser.ast.Modifier.FINAL;
+import static com.github.javaparser.ast.Modifier.PUBLIC;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.Utils.camelCaseToScreaming;
+
+public class PropertyGenerator extends NodeGenerator {
+
+    private final Map<String, PropertyMetaModel> declaredProperties = new HashMap<>();
+    private final Map<String, PropertyMetaModel> derivedProperties = new HashMap<>();
+
+    public PropertyGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        for (PropertyMetaModel property : nodeMetaModel.getDeclaredPropertyMetaModels()) {
+            generateGetter(nodeMetaModel, nodeCoid, property);
+            generateSetter(nodeMetaModel, nodeCoid, property);
+        }
+        nodeMetaModel.getDerivedPropertyMetaModels().forEach(p -> derivedProperties.put(p.getName(), p));
+    }
+
+    private void generateSetter(BaseNodeMetaModel nodeMetaModel, ClassOrInterfaceDeclaration nodeCoid, PropertyMetaModel property) {
+        final String name = property.getName();
+        // Fill body
+        final String observableName = camelCaseToScreaming(name.startsWith("is") ? name.substring(2) : name);
+        declaredProperties.put(observableName, property);
+
+        if (property == JavaParserMetaModel.nodeMetaModel.commentPropertyMetaModel) {
+            // Node.comment has a very specific setter that we shouldn't overwrite.
+            return;
+        }
+
+        final MethodDeclaration setter = new MethodDeclaration(EnumSet.of(PUBLIC), parseType(property.getContainingNodeMetaModel().getTypeNameGenerified()), property.getSetterMethodName());
+        if (property.getContainingNodeMetaModel().hasWildcard()) {
+            setter.setType(parseType("T"));
+        }
+        setter.addAndGetParameter(property.getTypeNameForSetter(), property.getName())
+                .addModifier(FINAL);
+
+        final BlockStmt body = setter.getBody().get();
+        body.getStatements().clear();
+
+        if (property.isRequired()) {
+            Class<?> type = property.getType();
+            if (property.isNonEmpty() && property.isSingular()) {
+                body.addStatement(f("assertNonEmpty(%s);", name));
+            } else if (type != boolean.class && type != int.class) {
+                body.addStatement(f("assertNotNull(%s);", name));
+            }
+        }
+        body.addStatement(f("if (%s == this.%s) { return (%s) this; }", name, name, setter.getType()));
+
+        body.addStatement(f("notifyPropertyChange(ObservableProperty.%s, this.%s, %s);", observableName, name, name));
+        if (property.isNode()) {
+            body.addStatement(f("if (this.%s != null) this.%s.setParentNode(null);", name, name));
+        }
+        body.addStatement(f("this.%s = %s;", name, name));
+        if (property.isNode()) {
+            body.addStatement(f("setAsParentNodeOf(%s);", name));
+        }
+        if (property.getContainingNodeMetaModel().hasWildcard()) {
+            body.addStatement(f("return (T) this;"));
+        } else {
+            body.addStatement(f("return this;"));
+        }
+        replaceWhenSameSignature(nodeCoid, setter);
+        if (property.getContainingNodeMetaModel().hasWildcard()) {
+            annotateSuppressWarnings(setter);
+        }
+    }
+
+    private void generateGetter(BaseNodeMetaModel nodeMetaModel, ClassOrInterfaceDeclaration nodeCoid, PropertyMetaModel property) {
+        final MethodDeclaration getter = new MethodDeclaration(EnumSet.of(PUBLIC), parseType(property.getTypeNameForGetter()), property.getGetterMethodName());
+        final BlockStmt body = getter.getBody().get();
+        body.getStatements().clear();
+        if (property.isOptional()) {
+            body.addStatement(f("return Optional.ofNullable(%s);", property.getName()));
+        } else {
+            body.addStatement(f("return %s;", property.getName()));
+        }
+        replaceWhenSameSignature(nodeCoid, getter);
+    }
+
+    private void generateObservableProperty(EnumDeclaration observablePropertyEnum, PropertyMetaModel property, boolean derived) {
+        boolean isAttribute = !Node.class.isAssignableFrom(property.getType());
+        String name = property.getName();
+        String constantName = camelCaseToScreaming(name.startsWith("is") ? name.substring(2) : name);
+        EnumConstantDeclaration enumConstantDeclaration = observablePropertyEnum.addEnumConstant(constantName);
+        if (isAttribute) {
+            if (property.isEnumSet()) {
+                enumConstantDeclaration.addArgument("Type.MULTIPLE_ATTRIBUTE");
+            } else {
+                enumConstantDeclaration.addArgument("Type.SINGLE_ATTRIBUTE");
+            }
+        } else {
+            if (property.isNodeList()) {
+                enumConstantDeclaration.addArgument("Type.MULTIPLE_REFERENCE");
+            } else {
+                enumConstantDeclaration.addArgument("Type.SINGLE_REFERENCE");
+            }
+        }
+        if (derived) {
+            enumConstantDeclaration.addArgument("true");
+        }
+    }
+
+    @Override
+    protected void after() throws Exception {
+        CompilationUnit observablePropertyCu = sourceRoot.tryToParse("com.github.javaparser.ast.observer", "ObservableProperty.java").getResult().get();
+        EnumDeclaration observablePropertyEnum = observablePropertyCu.getEnumByName("ObservableProperty").get();
+        observablePropertyEnum.getEntries().clear();
+        List<String> observablePropertyNames = new LinkedList<>(declaredProperties.keySet());
+        observablePropertyNames.sort(String::compareTo);
+        for (String propName : observablePropertyNames) {
+            generateObservableProperty(observablePropertyEnum, declaredProperties.get(propName), false);
+        }
+        List<String> derivedPropertyNames = new LinkedList<>(derivedProperties.keySet());
+        derivedPropertyNames.sort(String::compareTo);
+        for (String propName : derivedPropertyNames) {
+            generateObservableProperty(observablePropertyEnum, derivedProperties.get(propName), true);
+        }
+        observablePropertyEnum.addEnumConstant("RANGE");
+        observablePropertyEnum.addEnumConstant("COMMENTED_NODE");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/RemoveMethodGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/RemoveMethodGenerator.java
new file mode 100644
index 0000000..64d5898
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/RemoveMethodGenerator.java
@@ -0,0 +1,87 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.Utils.capitalize;
+
+
+public class RemoveMethodGenerator extends NodeGenerator {
+    public RemoveMethodGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        MethodDeclaration removeNodeMethod = (MethodDeclaration) parseBodyDeclaration("public boolean remove(Node node) {}");
+        nodeCu.addImport(Node.class);
+        nodeMetaModel.getSuperNodeMetaModel().ifPresent(s -> annotateOverridden(removeNodeMethod));
+
+        final BlockStmt body = removeNodeMethod.getBody().get();
+
+        body.addStatement("if (node == null) return false;");
+
+        for (PropertyMetaModel property : nodeMetaModel.getDeclaredPropertyMetaModels()) {
+            if (!property.isNode()) {
+                continue;
+            }
+            String check;
+            if (property.isNodeList()) {
+                check = nodeListCheck(property);
+            } else {
+                if (property.isRequired()) {
+                    continue;
+                }
+                String removeAttributeMethodName = generateRemoveMethodForAttribute(nodeCoid, nodeMetaModel, property);
+                check = attributeCheck(property, removeAttributeMethodName);
+            }
+            if (property.isOptional()) {
+                check = f("if (%s != null) { %s }", property.getName(), check);
+            }
+            body.addStatement(check);
+        }
+        if (nodeMetaModel.getSuperNodeMetaModel().isPresent()) {
+            body.addStatement("return super.remove(node);");
+        } else {
+            body.addStatement("return false;");
+        }
+        
+        addOrReplaceWhenSameSignature(nodeCoid, removeNodeMethod);
+    }
+
+    private String attributeCheck(PropertyMetaModel property, String removeAttributeMethodName) {
+        return f("if (node == %s) {" +
+                "    %s();" +
+                "    return true;\n" +
+                "}", property.getName(), removeAttributeMethodName);
+    }
+
+    private String nodeListCheck(PropertyMetaModel property) {
+        return f("for (int i = 0; i < %s.size(); i++) {" +
+                "  if (%s.get(i) == node) {" +
+                "    %s.remove(i);" +
+                "    return true;" +
+                "  }" +
+                "}", property.getName(), property.getName(), property.getName());
+    }
+
+    private String generateRemoveMethodForAttribute(ClassOrInterfaceDeclaration nodeCoid, BaseNodeMetaModel nodeMetaModel, PropertyMetaModel property) {
+        final String methodName = "remove" + capitalize(property.getName());
+        final MethodDeclaration removeMethod = (MethodDeclaration) parseBodyDeclaration(f("public %s %s() {}", nodeMetaModel.getTypeName(), methodName));
+
+        final BlockStmt block = removeMethod.getBody().get();
+        block.addStatement(f("return %s((%s) null);", property.getSetterMethodName(), property.getTypeNameForSetter()));
+
+        addOrReplaceWhenSameSignature(nodeCoid, removeMethod);
+        return methodName;
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/ReplaceMethodGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/ReplaceMethodGenerator.java
new file mode 100644
index 0000000..f1f9d3f
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/ReplaceMethodGenerator.java
@@ -0,0 +1,71 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+import static com.github.javaparser.JavaParser.parseBodyDeclaration;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.Utils.capitalize;
+
+public class ReplaceMethodGenerator extends NodeGenerator {
+    public ReplaceMethodGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
+        MethodDeclaration replaceNodeMethod = (MethodDeclaration) parseBodyDeclaration("public boolean replace(Node node, Node replacementNode) {}");
+        nodeCu.addImport(Node.class);
+        nodeMetaModel.getSuperNodeMetaModel().ifPresent(s -> annotateOverridden(replaceNodeMethod));
+
+        final BlockStmt body = replaceNodeMethod.getBody().get();
+
+        body.addStatement("if (node == null) return false;");
+
+        for (PropertyMetaModel property : nodeMetaModel.getDeclaredPropertyMetaModels()) {
+            if (!property.isNode()) {
+                continue;
+            }
+            String check;
+            if (property.isNodeList()) {
+                check = nodeListCheck(property);
+            } else {
+                check = attributeCheck(property, property.getSetterMethodName());
+            }
+            if (property.isOptional()) {
+                check = f("if (%s != null) { %s }", property.getName(), check);
+            }
+            body.addStatement(check);
+        }
+        if (nodeMetaModel.getSuperNodeMetaModel().isPresent()) {
+            body.addStatement("return super.replace(node, replacementNode);");
+        } else {
+            body.addStatement("return false;");
+        }
+        
+        addOrReplaceWhenSameSignature(nodeCoid, replaceNodeMethod);
+    }
+
+    private String attributeCheck(PropertyMetaModel property, String attributeSetterName) {
+        return f("if (node == %s) {" +
+                "    %s((%s) replacementNode);" +
+                "    return true;\n" +
+                "}", property.getName(), attributeSetterName, property.getTypeName());
+    }
+
+    private String nodeListCheck(PropertyMetaModel property) {
+        return f("for (int i = 0; i < %s.size(); i++) {" +
+                "  if (%s.get(i) == node) {" +
+                "    %s.set(i, (%s) replacementNode);" +
+                "    return true;" +
+                "  }" +
+                "}", property.getName(), property.getName(), property.getName(), property.getTypeName());
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/TypeCastingGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/TypeCastingGenerator.java
new file mode 100644
index 0000000..3a611f4
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/node/TypeCastingGenerator.java
@@ -0,0 +1,97 @@
+package com.github.javaparser.generator.core.node;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.generator.NodeGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.utils.Pair;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Consumer;
+
+import static com.github.javaparser.JavaParser.parseBodyDeclaration;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.Utils.set;
+
+public class TypeCastingGenerator extends NodeGenerator {
+    private final Set<BaseNodeMetaModel> baseNodes = set(
+            JavaParserMetaModel.statementMetaModel,
+            JavaParserMetaModel.expressionMetaModel,
+            JavaParserMetaModel.typeMetaModel,
+            JavaParserMetaModel.moduleStmtMetaModel,
+            JavaParserMetaModel.bodyDeclarationMetaModel,
+            JavaParserMetaModel.commentMetaModel
+    );
+
+    public TypeCastingGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot);
+    }
+
+    @Override
+    protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) throws Exception {
+        Pair<CompilationUnit, ClassOrInterfaceDeclaration> baseCode = null;
+        for (BaseNodeMetaModel baseNode : baseNodes) {
+            if(nodeMetaModel == baseNode) {
+                // We adjust the base models from the child nodes,
+                // so we don't do anything when we *are* the base model.
+                return;
+            }
+            if (nodeMetaModel.isInstanceOfMetaModel(baseNode)) {
+                baseCode = parseNode(baseNode);
+            }
+        }
+
+        if (baseCode == null) {
+            // Node is not a child of one of the base nodes, so we don't want to generate this method for it.
+            return;
+        }
+
+        final String typeName = nodeMetaModel.getTypeName();
+        final ClassOrInterfaceDeclaration baseCoid = baseCode.b;
+        final CompilationUnit baseCu = baseCode.a;
+        
+        generateIsType(baseCu, nodeCoid, baseCoid, typeName);
+        generateAsType(baseCu, nodeCoid, baseCoid, typeName);
+        generateToType(nodeCu, baseCu, nodeCoid, baseCoid, typeName);
+        generateIfType(nodeCu, baseCu, nodeCoid, baseCoid, typeName);
+    }
+
+    private void generateAsType(CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
+        final MethodDeclaration asTypeBaseMethod = (MethodDeclaration) parseBodyDeclaration(f("public %s as%s() { throw new IllegalStateException(f(\"%%s is not an %s\", this)); }", typeName, typeName, typeName));
+        final MethodDeclaration asTypeNodeMethod = (MethodDeclaration) parseBodyDeclaration(f("@Override public %s as%s() { return this; }", typeName, typeName));
+        addOrReplaceWhenSameSignature(baseCoid, asTypeBaseMethod);
+        addOrReplaceWhenSameSignature(nodeCoid, asTypeNodeMethod);
+        baseCu.addImport("com.github.javaparser.utils.CodeGenerationUtils.f", true, false);
+    }
+
+    private void generateToType(CompilationUnit nodeCu, CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
+        baseCu.addImport(Optional.class);
+        nodeCu.addImport(Optional.class);
+        final MethodDeclaration asTypeBaseMethod = (MethodDeclaration) parseBodyDeclaration(f("public Optional<%s> to%s() { return Optional.empty(); }", typeName, typeName, typeName));
+        final MethodDeclaration asTypeNodeMethod = (MethodDeclaration) parseBodyDeclaration(f("@Override public Optional<%s> to%s() { return Optional.of(this); }", typeName, typeName));
+        addOrReplaceWhenSameSignature(baseCoid, asTypeBaseMethod);
+        addOrReplaceWhenSameSignature(nodeCoid, asTypeNodeMethod);
+    }
+
+    private void generateIfType(CompilationUnit nodeCu, CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
+        final MethodDeclaration ifTypeBaseMethod = (MethodDeclaration) parseBodyDeclaration(f("public void if%s(Consumer<%s> action) { }", typeName, typeName));
+        final MethodDeclaration ifTypeNodeMethod = (MethodDeclaration) parseBodyDeclaration(f("public void if%s(Consumer<%s> action) { action.accept(this); }", typeName, typeName));
+        addOrReplaceWhenSameSignature(baseCoid, ifTypeBaseMethod);
+        addOrReplaceWhenSameSignature(nodeCoid, ifTypeNodeMethod);
+
+        baseCu.addImport(Consumer.class);
+        nodeCu.addImport(Consumer.class);
+    }
+
+    private void generateIsType(CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
+        final MethodDeclaration baseIsTypeMethod = (MethodDeclaration) parseBodyDeclaration(f("public boolean is%s() { return false; }", typeName));
+        final MethodDeclaration overriddenIsTypeMethod = (MethodDeclaration) parseBodyDeclaration(f("@Override public boolean is%s() { return true; }", typeName));
+
+        addOrReplaceWhenSameSignature(nodeCoid, overriddenIsTypeMethod);
+        addOrReplaceWhenSameSignature(baseCoid, baseIsTypeMethod);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/other/GrammarLetterGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/other/GrammarLetterGenerator.java
new file mode 100644
index 0000000..9d50bc6
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/other/GrammarLetterGenerator.java
@@ -0,0 +1,53 @@
+package com.github.javaparser.generator.core.other;
+
+import java.util.function.Function;
+
+/**
+ * Prints the LETTER and PART_LETTER tokens. They should be inserted into the grammar manually.
+ */
+public class GrammarLetterGenerator {
+    public static void main(String[] args) {
+        generate("LETTER", c -> Character.isJavaIdentifierStart(c) || Character.isHighSurrogate((char) (int) c) || Character.isLowSurrogate((char) (int) c));
+        generate("PART_LETTER", c -> Character.isJavaIdentifierPart(c) || Character.isHighSurrogate((char) (int) c) || Character.isLowSurrogate((char) (int) c));
+    }
+
+    private static void generate(String tokenName, Function<Integer, Boolean> f) {
+        final String indent = "         ";
+        System.out.println("  < #" + tokenName + ": [");
+        System.out.print(indent);
+        int nltime = 0;
+        int i = 0;
+        while (i < 0x10000) {
+            while (!f.apply(i) && i < 0x10000) {
+                i++;
+            }
+            String start = format(i);
+            while (f.apply(i) && i < 0x10000) {
+                i++;
+            }
+            String end = format(i - 1);
+            if (i >= 0x10000) {
+                break;
+            }
+            if (start.equals(end)) {
+                nltime++;
+                System.out.print(start + ",  ");
+            } else {
+                nltime += 2;
+                System.out.print(start + "-" + end + ",  ");
+            }
+            if (nltime >= 10) {
+                nltime = 0;
+                System.out.println();
+                System.out.print(indent);
+            }
+        }
+        // Too lazy to remove the final illegal comma.
+        System.out.println("]");
+        System.out.println("  >");
+    }
+
+    private static String format(int i) {
+        return String.format("\"\\u%04x\"", i);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/other/TokenKindGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/other/TokenKindGenerator.java
new file mode 100644
index 0000000..5088bc3
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/other/TokenKindGenerator.java
@@ -0,0 +1,71 @@
+package com.github.javaparser.generator.core.other;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.generator.Generator;
+import com.github.javaparser.utils.Log;
+import com.github.javaparser.utils.SourceRoot;
+
+/**
+ * Generates the TokenKind enum from {@link com.github.javaparser.GeneratedJavaParserConstants}
+ */
+public class TokenKindGenerator extends Generator {
+    private final SourceRoot generatedJavaCcSourceRoot;
+
+    public TokenKindGenerator(SourceRoot sourceRoot, SourceRoot generatedJavaCcSourceRoot) {
+        super(sourceRoot);
+        this.generatedJavaCcSourceRoot = generatedJavaCcSourceRoot;
+    }
+
+    @Override
+    public void generate() {
+        Log.info("Running %s", getClass().getSimpleName());
+        
+        final CompilationUnit javaTokenCu = sourceRoot.parse("com.github.javaparser", "JavaToken.java");
+        final ClassOrInterfaceDeclaration javaToken = javaTokenCu.getClassByName("JavaToken").orElseThrow(() -> new AssertionError("Can't find class in java file."));
+        final EnumDeclaration kindEnum = javaToken.findFirst(EnumDeclaration.class, e -> e.getNameAsString().equals("Kind")).orElseThrow(() -> new AssertionError("Can't find class in java file."));
+
+        kindEnum.getEntries().clear();
+        annotateGenerated(kindEnum);
+
+        final SwitchStmt valueOfSwitch = kindEnum.findFirst(SwitchStmt.class).orElseThrow(() -> new AssertionError("Can't find valueOf switch."));
+        valueOfSwitch.findAll(SwitchEntryStmt.class).stream().filter(e -> e.getLabel().isPresent()).forEach(Node::remove);
+
+        final CompilationUnit constantsCu = generatedJavaCcSourceRoot.parse("com.github.javaparser", "GeneratedJavaParserConstants.java");
+        final ClassOrInterfaceDeclaration constants = constantsCu.getInterfaceByName("GeneratedJavaParserConstants").orElseThrow(() -> new AssertionError("Can't find class in java file."));
+        for (BodyDeclaration<?> member : constants.getMembers()) {
+            member.toFieldDeclaration()
+                    .filter(field -> {
+                        String javadoc = field.getJavadocComment().get().getContent();
+                        return javadoc.contains("RegularExpression Id") || javadoc.contains("End of File");
+                    })
+                    .map(field -> field.getVariable(0))
+                    .ifPresent(var -> {
+                        final String name = var.getNameAsString();
+                        final IntegerLiteralExpr kind = var.getInitializer().get().asIntegerLiteralExpr();
+                        generateEnumEntry(kindEnum, name, kind);
+                        generateValueOfEntry(valueOfSwitch, name, kind);
+                    });
+        }
+    }
+
+    private void generateValueOfEntry(SwitchStmt valueOfSwitch, String name, IntegerLiteralExpr kind) {
+        final SwitchEntryStmt entry = new SwitchEntryStmt(kind, new NodeList<>(new ReturnStmt(name)));
+        valueOfSwitch.getEntries().addFirst(entry);
+    }
+
+    private void generateEnumEntry(EnumDeclaration kindEnum, String name, IntegerLiteralExpr kind) {
+        final EnumConstantDeclaration enumEntry = new EnumConstantDeclaration(name);
+        enumEntry.getArguments().add(kind);
+        kindEnum.addEntry(enumEntry);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/CloneVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/CloneVisitorGenerator.java
new file mode 100644
index 0000000..44a7e9f
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/CloneVisitorGenerator.java
@@ -0,0 +1,59 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.utils.SeparatedItemStringBuilder;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Generates JavaParser's CloneVisitor.
+ */
+public class CloneVisitorGenerator extends VisitorGenerator {
+    public CloneVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "CloneVisitor", "Visitable", "Object", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        for (PropertyMetaModel field : node.getAllPropertyMetaModels()) {
+            final String getter = field.getGetterMethodName() + "()";
+            if (field.getNodeReference().isPresent()) {
+                if (field.isOptional() && field.isNodeList()) {
+                    body.addStatement(f("NodeList<%s> %s = cloneList(n.%s.orElse(null), arg);", field.getTypeNameGenerified(), field.getName(), getter));
+                } else if (field.isNodeList()) {
+                    body.addStatement(f("NodeList<%s> %s = cloneList(n.%s, arg);", field.getTypeNameGenerified(), field.getName(), getter));
+                } else {
+                    body.addStatement(f("%s %s = cloneNode(n.%s, arg);", field.getTypeNameGenerified(), field.getName(), getter));
+                }
+            }
+        }
+
+        SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder(f("%s r = new %s(", node.getTypeNameGenerified(), node.getTypeNameGenerified()), ",", ");");
+        builder.append("n.getTokenRange().orElse(null)");
+        for (PropertyMetaModel field : node.getConstructorParameters()) {
+            if (field.getName().equals("comment")) {
+                continue;
+            }
+            if (field.getNodeReference().isPresent()) {
+                builder.append(field.getName());
+            } else {
+                builder.append(f("n.%s()", field.getGetterMethodName()));
+            }
+        }
+
+        body.addStatement(builder.toString());
+        body.addStatement("r.setComment(comment);");
+        body.addStatement("return r;");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/EqualsVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/EqualsVisitorGenerator.java
new file mode 100644
index 0000000..7517f8e
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/EqualsVisitorGenerator.java
@@ -0,0 +1,48 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Generates JavaParser's EqualsVisitor.
+ */
+public class EqualsVisitorGenerator extends VisitorGenerator {
+    public EqualsVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "EqualsVisitor", "Boolean", "Visitable", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        body.addStatement(f("final %s n2 = (%s) arg;", node.getTypeName(), node.getTypeName()));
+
+        for (PropertyMetaModel field : node.getAllPropertyMetaModels()) {
+            final String getter = field.getGetterMethodName() + "()";
+            if (field.getNodeReference().isPresent()) {
+                if (field.isNodeList()) {
+                    body.addStatement(f("if (!nodesEquals(n.%s, n2.%s)) return false;", getter, getter));
+                } else {
+                    body.addStatement(f("if (!nodeEquals(n.%s, n2.%s)) return false;", getter, getter));
+                }
+            } else {
+                body.addStatement(f("if (!objEquals(n.%s, n2.%s)) return false;", getter, getter));
+            }
+        }
+        if (body.getStatements().size() == 1) {
+            // Only the cast line was added, but nothing is using it, so remove it again.
+            body.getStatements().clear();
+        }
+        body.addStatement("return true;");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericListVisitorAdapterGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericListVisitorAdapterGenerator.java
new file mode 100644
index 0000000..f910108
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericListVisitorAdapterGenerator.java
@@ -0,0 +1,56 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Generates JavaParser's GenericListVisitorAdapter.
+ */
+public class GenericListVisitorAdapterGenerator extends VisitorGenerator {
+    public GenericListVisitorAdapterGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "GenericListVisitorAdapter", "List<R>", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+        body.addStatement("List<R> result = new ArrayList<>();");
+        body.addStatement("List<R> tmp;");
+
+        final String resultCheck = "if (tmp != null) result.addAll(tmp);";
+
+        for (PropertyMetaModel field : node.getAllPropertyMetaModels()) {
+            final String getter = field.getGetterMethodName() + "()";
+            if (field.getNodeReference().isPresent()) {
+                if (field.isOptional()) {
+                    body.addStatement(f("if (n.%s.isPresent()) {" +
+                            "   tmp = n.%s.get().accept(this, arg);" +
+                            "   %s" +
+                            "}", getter, getter, resultCheck));
+                } else {
+                    body.addStatement(f("{ tmp = n.%s.accept(this, arg); %s }", getter, resultCheck));
+                }
+            }
+        }
+        body.addStatement("return result;");
+        Arrays.stream(new Class<?>[] {List.class, ArrayList.class}).filter(c ->
+                compilationUnit.getImports().stream().noneMatch(
+                        i -> c.getName().equals(i.getName().asString())
+                )
+        ).forEach(compilationUnit::addImport);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorAdapterGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorAdapterGenerator.java
new file mode 100644
index 0000000..72f563d
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorAdapterGenerator.java
@@ -0,0 +1,47 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Generates JavaParser's VoidVisitorAdapter.
+ */
+public class GenericVisitorAdapterGenerator extends VisitorGenerator {
+    public GenericVisitorAdapterGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "GenericVisitorAdapter", "R", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+        
+        body.addStatement("R result;");
+
+        final String resultCheck = "if (result != null) return result;";
+
+        for (PropertyMetaModel field : node.getAllPropertyMetaModels()) {
+            final String getter = field.getGetterMethodName() + "()";
+            if (field.getNodeReference().isPresent()) {
+                if (field.isOptional()) {
+                    body.addStatement(f("if (n.%s.isPresent()) {" +
+                            "   result = n.%s.get().accept(this, arg);" +
+                            "   %s" +
+                            "}", getter, getter, resultCheck));
+                } else {
+                    body.addStatement(f("{ result = n.%s.accept(this, arg); %s }", getter, resultCheck));
+                }
+            }
+        }
+        body.addStatement("return null;");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorGenerator.java
new file mode 100644
index 0000000..e71aeb1
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorGenerator.java
@@ -0,0 +1,23 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+
+/**
+ * Generates JavaParser's GenericVisitor.
+ */
+public class GenericVisitorGenerator extends VisitorGenerator {
+    public GenericVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "GenericVisitor", "R", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(false));
+        
+        visitMethod.setBody(null);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorWithDefaultsGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorWithDefaultsGenerator.java
new file mode 100644
index 0000000..a6a2151
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/GenericVisitorWithDefaultsGenerator.java
@@ -0,0 +1,27 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+/**
+ * Generates JavaParser's GenericVisitorWithDefaults.
+ */
+public class GenericVisitorWithDefaultsGenerator extends VisitorGenerator {
+    public GenericVisitorWithDefaultsGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "GenericVisitorWithDefaults", "R", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        body.addStatement("return defaultAction(n, arg);");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/HashCodeVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/HashCodeVisitorGenerator.java
new file mode 100644
index 0000000..554dc8d
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/HashCodeVisitorGenerator.java
@@ -0,0 +1,59 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.utils.SeparatedItemStringBuilder;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import java.util.List;
+
+import static com.github.javaparser.JavaParser.parseStatement;
+
+/**
+ * Generates JavaParser's HashCodeVisitor.
+ */
+public class HashCodeVisitorGenerator extends VisitorGenerator {
+    public HashCodeVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "HashCodeVisitor", "Integer", "Void", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        final BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        final SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder("return ", "* 31 +", ";");
+        final List<PropertyMetaModel> propertyMetaModels= node.getAllPropertyMetaModels();
+        if (propertyMetaModels.isEmpty()) {
+            builder.append("0");
+        } else {
+            for (PropertyMetaModel field : propertyMetaModels) {
+                final String getter = field.getGetterMethodName() + "()";
+                // Is this field another AST node? Visit it.
+                if (field.getNodeReference().isPresent()) {
+                    if (field.isOptional()) {
+                        builder.append("(n.%s.isPresent()? n.%s.get().accept(this, arg):0)", getter, getter);
+                    } else {
+                        builder.append("(n.%s.accept(this, arg))", getter);
+                    }
+                } else {
+                    Class<?> type = field.getType();
+                    if (type.equals(boolean.class)) {
+                        builder.append("(n.%s?1:0)", getter);
+                    } else if (type.equals(int.class)) {
+                        builder.append("n.%s", getter);
+                    } else {
+                        builder.append("(n.%s.hashCode())", getter);
+                    }
+                }
+            }
+        }
+        body.addStatement(parseStatement(builder.toString()));
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ModifierVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ModifierVisitorGenerator.java
new file mode 100644
index 0000000..4c2f711
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ModifierVisitorGenerator.java
@@ -0,0 +1,78 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+import com.github.javaparser.utils.SeparatedItemStringBuilder;
+import com.github.javaparser.utils.SourceRoot;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+public class ModifierVisitorGenerator extends VisitorGenerator {
+    public ModifierVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "ModifierVisitor", "Visitable", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        for (PropertyMetaModel property : node.getAllPropertyMetaModels()) {
+            if (property.isNode()) {
+                if (property.isNodeList()) {
+                    body.addStatement(f("NodeList<%s> %s = modifyList(n.%s(), arg);",
+                            property.getTypeNameGenerified(),
+                            property.getName(),
+                            property.getGetterMethodName()));
+                } else if (property.isOptional()) {
+                    body.addStatement(f("%s %s = n.%s().map(s -> (%s) s.accept(this, arg)).orElse(null);",
+                            property.getTypeNameGenerified(),
+                            property.getName(),
+                            property.getGetterMethodName(),
+                            property.getTypeNameGenerified()));
+                } else {
+                    body.addStatement(f("%s %s = (%s) n.%s().accept(this, arg);",
+                            property.getTypeNameGenerified(),
+                            property.getName(),
+                            property.getTypeNameGenerified(),
+                            property.getGetterMethodName()));
+                }
+            }
+        }
+
+        if(node.is(BinaryExpr.class)){
+            body.addStatement("if (left == null) return right;");
+            body.addStatement("if (right == null) return left;");
+        }else {
+            final SeparatedItemStringBuilder collapseCheck = new SeparatedItemStringBuilder("if(", "||", ") return null;");
+            for (PropertyMetaModel property : node.getAllPropertyMetaModels()) {
+                if (property.isRequired() && property.isNode()) {
+                    if (property.isNodeList()) {
+                        if(property.isNonEmpty()){
+                            collapseCheck.append(f("%s.isEmpty()", property.getName()));
+                        }
+                    } else {
+                        collapseCheck.append(f("%s==null", property.getName()));
+                    }
+                }
+            }
+            if (collapseCheck.hasItems()) {
+                body.addStatement(collapseCheck.toString());
+            }
+        }
+
+        for (PropertyMetaModel property : node.getAllPropertyMetaModels()) {
+            if (property.isNode()) {
+                body.addStatement(f("n.%s(%s);", property.getSetterMethodName(), property.getName()));
+            }
+        }
+        body.addStatement("return n;");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/NoCommentEqualsVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/NoCommentEqualsVisitorGenerator.java
new file mode 100644
index 0000000..f6174c4
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/NoCommentEqualsVisitorGenerator.java
@@ -0,0 +1,76 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.generator.core.visitor;

+

+import static com.github.javaparser.utils.CodeGenerationUtils.f;

+

+import com.github.javaparser.ast.CompilationUnit;

+import com.github.javaparser.ast.body.MethodDeclaration;

+import com.github.javaparser.ast.stmt.BlockStmt;

+import com.github.javaparser.generator.VisitorGenerator;

+import com.github.javaparser.metamodel.BaseNodeMetaModel;

+import com.github.javaparser.metamodel.JavaParserMetaModel;

+import com.github.javaparser.metamodel.PropertyMetaModel;

+import com.github.javaparser.utils.SourceRoot;

+

+public class NoCommentEqualsVisitorGenerator extends VisitorGenerator {

+

+    public NoCommentEqualsVisitorGenerator(SourceRoot sourceRoot) {

+        super(sourceRoot, "com.github.javaparser.ast.visitor", "NoCommentEqualsVisitor", "Boolean", "Visitable", true);

+    }

+

+    @Override

+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod,

+                                           CompilationUnit compilationUnit) {

+        visitMethod.getParameters().forEach(p -> p.setFinal(true));

+

+        BlockStmt body = visitMethod.getBody().get();

+        body.getStatements().clear();

+

+        if (!(node.equals(JavaParserMetaModel.lineCommentMetaModel)

+                || node.equals(JavaParserMetaModel.blockCommentMetaModel)

+                || node.equals(JavaParserMetaModel.javadocCommentMetaModel))) {

+

+            body.addStatement(f("final %s n2 = (%s) arg;", node.getTypeName(), node.getTypeName()));

+

+            for (PropertyMetaModel field : node.getAllPropertyMetaModels()) {

+                final String getter = field.getGetterMethodName() + "()";

+                if (field.equals(JavaParserMetaModel.nodeMetaModel.commentPropertyMetaModel))

+                    continue;

+                if (field.getNodeReference().isPresent()) {

+                    if (field.isNodeList()) {

+                        body.addStatement(f("if (!nodesEquals(n.%s, n2.%s)) return false;", getter, getter));

+                    } else {

+                        body.addStatement(f("if (!nodeEquals(n.%s, n2.%s)) return false;", getter, getter));

+                    }

+                } else {

+                    body.addStatement(f("if (!objEquals(n.%s, n2.%s)) return false;", getter, getter));

+                }

+            }

+            if (body.getStatements().size() == 1) {

+                // Only the cast line was added, but nothing is using it, so remove it again.

+                body.getStatements().clear();

+            }

+        }

+        body.addStatement("return true;");

+    }

+}
\ No newline at end of file
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/NoCommentHashCodeVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/NoCommentHashCodeVisitorGenerator.java
new file mode 100644
index 0000000..b36d259
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/NoCommentHashCodeVisitorGenerator.java
@@ -0,0 +1,89 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.generator.core.visitor;

+

+import static com.github.javaparser.JavaParser.parseStatement;

+

+import java.util.List;

+

+import com.github.javaparser.ast.CompilationUnit;

+import com.github.javaparser.ast.body.MethodDeclaration;

+import com.github.javaparser.ast.stmt.BlockStmt;

+import com.github.javaparser.generator.VisitorGenerator;

+import com.github.javaparser.metamodel.BaseNodeMetaModel;

+import com.github.javaparser.metamodel.JavaParserMetaModel;

+import com.github.javaparser.metamodel.PropertyMetaModel;

+import com.github.javaparser.utils.SeparatedItemStringBuilder;

+import com.github.javaparser.utils.SourceRoot;

+

+public class NoCommentHashCodeVisitorGenerator extends VisitorGenerator {

+

+    public NoCommentHashCodeVisitorGenerator(SourceRoot sourceRoot) {

+        super(sourceRoot, "com.github.javaparser.ast.visitor", "NoCommentHashCodeVisitor", "Integer", "Void", true);

+    }

+

+    @Override

+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod,

+                                           CompilationUnit compilationUnit) {

+        visitMethod.getParameters().forEach(p -> p.setFinal(true));

+

+        final BlockStmt body = visitMethod.getBody().get();

+        body.getStatements().clear();

+

+        final SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder("return ", "* 31 +", ";");

+        final List<PropertyMetaModel> propertyMetaModels = node.getAllPropertyMetaModels();

+        if (node.equals(JavaParserMetaModel.lineCommentMetaModel)

+                || node.equals(JavaParserMetaModel.blockCommentMetaModel)

+                || node.equals(JavaParserMetaModel.javadocCommentMetaModel) || propertyMetaModels.isEmpty()) {

+            builder.append("0");

+        } else {

+            for (PropertyMetaModel field : propertyMetaModels) {

+                final String getter = field.getGetterMethodName() + "()";

+                if (field.equals(JavaParserMetaModel.nodeMetaModel.commentPropertyMetaModel)) {

+                    if (propertyMetaModels.size() == 1) {

+                        builder.append("0");

+                        break;

+                    } else

+                        continue;

+                }

+                // Is this field another AST node? Visit it.

+                if (field.getNodeReference().isPresent()) {

+                    if (field.isOptional()) {

+                        builder.append("(n.%s.isPresent()? n.%s.get().accept(this, arg):0)", getter, getter);

+                    } else {

+                        builder.append("(n.%s.accept(this, arg))", getter);

+                    }

+                } else {

+                    Class<?> type = field.getType();

+                    if (type.equals(boolean.class)) {

+                        builder.append("(n.%s?1:0)", getter);

+                    } else if (type.equals(int.class)) {

+                        builder.append("n.%s", getter);

+                    } else {

+                        builder.append("(n.%s.hashCode())", getter);

+                    }

+                }

+            }

+        }

+        body.addStatement(parseStatement(builder.toString()));

+    }

+}

diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ObjectIdentityEqualsVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ObjectIdentityEqualsVisitorGenerator.java
new file mode 100644
index 0000000..3c182fc
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ObjectIdentityEqualsVisitorGenerator.java
@@ -0,0 +1,30 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Generates JavaParser's ObjectIdentityEqualsVisitor.
+ */
+public class ObjectIdentityEqualsVisitorGenerator extends VisitorGenerator {
+    public ObjectIdentityEqualsVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "ObjectIdentityEqualsVisitor", "Boolean", "Visitable", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        body.addStatement("return n == arg;");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ObjectIdentityHashCodeVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ObjectIdentityHashCodeVisitorGenerator.java
new file mode 100644
index 0000000..88eb3e7
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ObjectIdentityHashCodeVisitorGenerator.java
@@ -0,0 +1,32 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+import com.github.javaparser.utils.SeparatedItemStringBuilder;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.util.List;
+
+import static com.github.javaparser.JavaParser.parseStatement;
+
+/**
+ * Generates JavaParser's ObjectIdentityHashCodeVisitor.
+ */
+public class ObjectIdentityHashCodeVisitorGenerator extends VisitorGenerator {
+    public ObjectIdentityHashCodeVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "ObjectIdentityHashCodeVisitor", "Integer", "Void", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        final BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+        body.addStatement("return n.hashCode();");
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorAdapterGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorAdapterGenerator.java
new file mode 100644
index 0000000..937ea7e
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorAdapterGenerator.java
@@ -0,0 +1,43 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Generates JavaParser's VoidVisitorAdapter.
+ */
+public class VoidVisitorAdapterGenerator extends VisitorGenerator {
+    public VoidVisitorAdapterGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "VoidVisitorAdapter", "void", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        for (PropertyMetaModel field : node.getAllPropertyMetaModels()) {
+            final String getter = field.getGetterMethodName() + "()";
+            if (field.getNodeReference().isPresent()) {
+                if (field.isOptional() && field.isNodeList()) {
+                    body.addStatement(f("n.%s.ifPresent( l -> l.forEach( v -> v.accept(this, arg)));", getter));
+                } else if (field.isOptional()) {
+                    body.addStatement(f("n.%s.ifPresent(l -> l.accept(this, arg));", getter));
+                } else if (field.isNodeList()) {
+                    body.addStatement(f("n.%s.forEach(p -> p.accept(this, arg));", getter));
+                } else {
+                    body.addStatement(f("n.%s.accept(this, arg);", getter));
+                }
+            }
+        }
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorGenerator.java
new file mode 100644
index 0000000..e3326d3
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorGenerator.java
@@ -0,0 +1,23 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+/**
+ * Generates JavaParser's VoidVisitor.
+ */
+public class VoidVisitorGenerator extends VisitorGenerator {
+    public VoidVisitorGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "VoidVisitor", "void", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(false));
+
+        visitMethod.setBody(null);
+    }
+}
diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorWithDefaultsGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorWithDefaultsGenerator.java
new file mode 100644
index 0000000..4089061
--- /dev/null
+++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/VoidVisitorWithDefaultsGenerator.java
@@ -0,0 +1,27 @@
+package com.github.javaparser.generator.core.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.generator.VisitorGenerator;
+import com.github.javaparser.metamodel.BaseNodeMetaModel;
+import com.github.javaparser.utils.SourceRoot;
+
+/**
+ * Generates JavaParser's VoidVisitorWithDefaults.
+ */
+public class VoidVisitorWithDefaultsGenerator extends VisitorGenerator {
+    public VoidVisitorWithDefaultsGenerator(SourceRoot sourceRoot) {
+        super(sourceRoot, "com.github.javaparser.ast.visitor", "VoidVisitorWithDefaults", "void", "A", true);
+    }
+
+    @Override
+    protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) {
+        visitMethod.getParameters().forEach(p -> p.setFinal(true));
+
+        BlockStmt body = visitMethod.getBody().get();
+        body.getStatements().clear();
+
+        body.addStatement("defaultAction(n, arg);");
+    }
+}
diff --git a/javaparser-core/bnd.bnd b/javaparser-core/bnd.bnd
new file mode 100644
index 0000000..9f43eea
--- /dev/null
+++ b/javaparser-core/bnd.bnd
@@ -0,0 +1,33 @@
+# Make the Bundle-SymbolicName fully qualified, not just the artifact id
+Bundle-SymbolicName: com.github.javaparser.javaparser-core
+
+# Export all packages except impl
+-exportcontents: \
+    com.github.javaparser, \
+    com.github.javaparser.javadoc, \
+    com.github.javaparser.javadoc.description, \
+    com.github.javaparser.metamodel, \
+    com.github.javaparser.printer, \
+    com.github.javaparser.printer.concretesyntaxmodel, \
+    com.github.javaparser.resolution, \
+    com.github.javaparser.resolution.declarations, \
+    com.github.javaparser.resolution.types, \
+    com.github.javaparser.resolution.types.parametrization, \
+    com.github.javaparser.utils, \
+    com.github.javaparser.ast, \
+    com.github.javaparser.ast.body, \
+    com.github.javaparser.ast.imports, \
+    com.github.javaparser.ast.comments, \
+    com.github.javaparser.ast.modules, \
+    com.github.javaparser.ast.nodeTypes, \
+    com.github.javaparser.ast.nodeTypes.modifiers, \
+    com.github.javaparser.ast.expr, \
+    com.github.javaparser.ast.stmt, \
+    com.github.javaparser.ast.type, \
+    com.github.javaparser.ast.visitor, \
+    com.github.javaparser.ast.validator, \
+    com.github.javaparser.ast.observer
+
+# Don't use the project's version for the packages
+# We prefer not setting a version as we don't follow OSGi version semantics
+-nodefaultversion: true
diff --git a/javaparser-core/javaparser-core.iml b/javaparser-core/javaparser-core.iml
new file mode 100644
index 0000000..055eff4
--- /dev/null
+++ b/javaparser-core/javaparser-core.iml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/javacc-support" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/java-templates" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/javacc" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/target/generated-sources/license" isTestSource="false" generated="true" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-core/pom.xml b/javaparser-core/pom.xml
new file mode 100644
index 0000000..356b13d
--- /dev/null
+++ b/javaparser-core/pom.xml
@@ -0,0 +1,173 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>javaparser-parent</artifactId>
+        <groupId>com.github.javaparser</groupId>
+        <version>3.5.16-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-core</artifactId>
+    <packaging>jar</packaging>
+    <description>The core parser functionality. This may be all you need.</description>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
+            <distribution>repo</distribution>
+        </license>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <build.timestamp>${maven.build.timestamp}</build.timestamp>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.helger.maven</groupId>
+                <artifactId>ph-javacc-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>javacc</id>
+                        <goals>
+                            <goal>javacc</goal>
+                        </goals>
+                        <configuration>
+                            <grammarEncoding>${project.build.sourceEncoding}</grammarEncoding>
+                            <jdkVersion>${java.version}</jdkVersion>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>animal-sniffer-maven-plugin</artifactId>
+                <configuration>
+                    <signature>
+                        <!-- Make sure only the API of this JDK is used -->
+                        <groupId>org.codehaus.mojo.signature</groupId>
+                        <artifactId>java18</artifactId>
+                        <version>1.0</version>
+                    </signature>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>animal-sniffer</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>enforce-versions</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <!-- Make sure a compiler of this version is used -->
+                                    <version>${java.version}</version>
+                                </requireJavaVersion>
+                                <enforceBytecodeVersion>
+                                    <!-- Make sure the dependencies are compiled for our Java version -->
+                                    <maxJdkVersion>${java.version}</maxJdkVersion>
+                                </enforceBytecodeVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>extra-enforcer-rules</artifactId>
+                        <version>1.0-beta-6</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <!-- Generate an OSGi-enabled MANIFEST during the build -->
+            <plugin>
+                <groupId>biz.aQute.bnd</groupId>
+                <artifactId>bnd-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>bnd-process</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <!-- Make sure the bnd-generated manifest is picked up, see MJAR-193 -->
+                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
+                        <!-- Set module name -->
+                        <manifestEntries>
+                            <Automatic-Module-Name>com.github.javaparser.core</Automatic-Module-Name>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <compilerArgs>
+                        <!-- This stores method parameter names in the class file, which are used by the metamodel generator -->
+                        <arg>-parameters</arg>
+                    </compilerArgs>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>add-source</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>src/main/javacc-support</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>templating-maven-plugin</artifactId>
+                <version>1.0.0</version>
+                <executions>
+                    <execution>
+                        <id>filter-src</id>
+                        <goals>
+                            <goal>filter-sources</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/javaparser-core/src/main/java-templates/com/github/javaparser/JavaParserBuild.java b/javaparser-core/src/main/java-templates/com/github/javaparser/JavaParserBuild.java
new file mode 100644
index 0000000..2e0ee9c
--- /dev/null
+++ b/javaparser-core/src/main/java-templates/com/github/javaparser/JavaParserBuild.java
@@ -0,0 +1,19 @@
+package com.github.javaparser;
+
+/**
+ * Some information that was available when this library was built by Maven.
+ */
+public class JavaParserBuild {
+    public static final String PROJECT_VERSION = "${project.version}";
+    public static final String PROJECT_NAME = "${project.name}";
+    public static final String PROJECT_BUILD_FINAL_NAME = "${project.build.finalName}";
+    public static final String MAVEN_VERSION = "${maven.version}";
+    public static final String MAVEN_BUILD_VERSION = "${maven.build.version}";
+    public static final String MAVEN_BUILD_TIMESTAMP = "${build.timestamp}";
+    public static final String JAVA_VENDOR ="${java.vendor}";
+    public static final String JAVA_VENDOR_URL ="${java.vendor.url}";
+    public static final String JAVA_VERSION ="${java.version}";
+    public static final String OS_ARCH ="${os.arch}";
+    public static final String OS_NAME ="${os.name}";
+    public static final String OS_VERSION ="${os.version}";
+}
\ No newline at end of file
diff --git a/javaparser-core/src/main/java/com/github/javaparser/CommentsInserter.java b/javaparser-core/src/main/java/com/github/javaparser/CommentsInserter.java
new file mode 100644
index 0000000..869883c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/CommentsInserter.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.utils.PositionUtils;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.ast.Node.NODE_BY_BEGIN_POSITION;
+
+/**
+ * Assigns comments to nodes of the AST.
+ *
+ * @author Sebastian Kuerten
+ * @author Júlio Vilmar Gesser
+ */
+class CommentsInserter {
+    private final ParserConfiguration configuration;
+
+    CommentsInserter(ParserConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    /**
+     * Comments are attributed to the thing they comment and are removed from
+     * the comments.
+     */
+    private void insertComments(CompilationUnit cu, TreeSet<Comment> comments) {
+        if (comments.isEmpty())
+            return;
+
+        /* I should sort all the direct children and the comments, if a comment
+         is the first thing then it
+         a comment to the CompilationUnit */
+
+        // FIXME if there is no package it could be also a comment to the following class...
+        // so I could use some heuristics in these cases to distinguish the two
+        // cases
+
+        List<Node> children = cu.getChildNodes();
+
+        Comment firstComment = comments.iterator().next();
+        if (cu.getPackageDeclaration().isPresent()
+                && (children.isEmpty() || PositionUtils.areInOrder(
+                firstComment, cu.getPackageDeclaration().get()))) {
+            cu.setComment(firstComment);
+            comments.remove(firstComment);
+        }
+    }
+
+    /**
+     * This method try to attributes the nodes received to child of the node. It
+     * returns the node that were not attributed.
+     */
+    void insertComments(Node node, TreeSet<Comment> commentsToAttribute) {
+        if (commentsToAttribute.isEmpty())
+            return;
+
+        if (node instanceof CompilationUnit) {
+            insertComments((CompilationUnit) node, commentsToAttribute);
+        }
+
+        // the comments can:
+        // 1) Inside one of the child, then it is the child that have to
+        // associate them
+        // 2) If they are not inside a child they could be preceeding nothing, a
+        // comment or a child
+        // if they preceed a child they are assigned to it, otherweise they
+        // remain "orphans"
+
+        List<Node> children = node.getChildNodes();
+
+        for (Node child : children) {
+            TreeSet<Comment> commentsInsideChild = new TreeSet<>(NODE_BY_BEGIN_POSITION);
+            commentsInsideChild.addAll(
+                    commentsToAttribute.stream()
+                            .filter(c -> c.getRange().isPresent())
+                            .filter(c -> PositionUtils.nodeContains(child, c,
+                                    configuration.isDoNotConsiderAnnotationsAsNodeStartForCodeAttribution())).collect(Collectors.toList()));
+            commentsToAttribute.removeAll(commentsInsideChild);
+            insertComments(child, commentsInsideChild);
+        }
+
+        attributeLineCommentsOnSameLine(commentsToAttribute, children);
+
+        /* at this point I create an ordered list of all remaining comments and
+         children */
+        Comment previousComment = null;
+        final List<Comment> attributedComments = new LinkedList<>();
+        List<Node> childrenAndComments = new LinkedList<>();
+        // Avoid attributing comments to a meaningless container.
+        childrenAndComments.addAll(children);
+        commentsToAttribute.removeAll(attributedComments);
+
+        childrenAndComments.addAll(commentsToAttribute);
+        PositionUtils.sortByBeginPosition(childrenAndComments,
+                configuration.isDoNotConsiderAnnotationsAsNodeStartForCodeAttribution());
+
+        for (Node thing : childrenAndComments) {
+            if (thing instanceof Comment) {
+                previousComment = (Comment) thing;
+                if (!previousComment.isOrphan()) {
+                    previousComment = null;
+                }
+            } else {
+                if (previousComment != null && !thing.getComment().isPresent()) {
+                    if (!configuration.isDoNotAssignCommentsPrecedingEmptyLines()
+                            || !thereAreLinesBetween(previousComment, thing)) {
+                        thing.setComment(previousComment);
+                        attributedComments.add(previousComment);
+                        previousComment = null;
+                    }
+                }
+            }
+        }
+
+        commentsToAttribute.removeAll(attributedComments);
+
+        // all the remaining are orphan nodes
+        for (Comment c : commentsToAttribute) {
+            if (c.isOrphan()) {
+                node.addOrphanComment(c);
+            }
+        }
+    }
+
+    private void attributeLineCommentsOnSameLine(TreeSet<Comment> commentsToAttribute, List<Node> children) {
+        /* I can attribute in line comments to elements preceeding them, if
+         there is something contained in their line */
+        List<Comment> attributedComments = new LinkedList<>();
+        commentsToAttribute.stream()
+                .filter(comment -> comment.getRange().isPresent())
+                .filter(Comment::isLineComment)
+                .forEach(comment -> children.stream()
+                        .filter(child -> child.getRange().isPresent())
+                        .forEach(child -> {
+                            Range commentRange = comment.getRange().get();
+                            Range childRange = child.getRange().get();
+                            if (childRange.end.line == commentRange.begin.line
+                                    && attributeLineCommentToNodeOrChild(child,
+                                    comment.asLineComment())) {
+                                attributedComments.add(comment);
+                            }
+                        }));
+        commentsToAttribute.removeAll(attributedComments);
+    }
+
+    private boolean attributeLineCommentToNodeOrChild(Node node, LineComment lineComment) {
+        if (!node.getRange().isPresent() || !lineComment.getRange().isPresent()) {
+            return false;
+        }
+        
+        // The node start and end at the same line as the comment,
+        // let's give to it the comment
+        if (node.getBegin().get().line == lineComment.getBegin().get().line
+                && !node.getComment().isPresent()) {
+            if (!(node instanceof Comment)) {
+                node.setComment(lineComment);
+            }
+            return true;
+        } else {
+            // try with all the children, sorted by reverse position (so the
+            // first one is the nearest to the comment
+            List<Node> children = new LinkedList<>();
+            children.addAll(node.getChildNodes());
+            PositionUtils.sortByBeginPosition(children);
+            Collections.reverse(children);
+
+            for (Node child : children) {
+                if (attributeLineCommentToNodeOrChild(child, lineComment)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+    private boolean thereAreLinesBetween(Node a, Node b) {
+        if (!a.getRange().isPresent() || !b.getRange().isPresent()) {
+            return true;
+        }
+        if (!PositionUtils.areInOrder(a, b)) {
+            return thereAreLinesBetween(b, a);
+        }
+        int endOfA = a.getEnd().get().line;
+        return b.getBegin().get().line > endOfA + 1;
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/HasParentNode.java b/javaparser-core/src/main/java/com/github/javaparser/HasParentNode.java
new file mode 100644
index 0000000..03df0d6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/HasParentNode.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.Observable;
+
+import java.util.Optional;
+
+/**
+ * An object that has a parent node.
+ */
+public interface HasParentNode<T> extends Observable {
+
+    /**
+     * Return the parent node or null, if no parent is set.
+     */
+    Optional<Node> getParentNode();
+
+    /**
+     * Set the parent node.
+     *
+     * @param parentNode the parent node or null, to set no parent
+     * @return return <i>this</i>
+     */
+    T setParentNode(Node parentNode);
+
+    /**
+     * <i>this</i> for everything except NodeLists. NodeLists use their parent as their children parent.
+     */
+    Node getParentNodeForChildren();
+
+    /**
+     * Get the ancestor of the node having the given type, or null if no ancestor of the given type is found.
+     */
+    default <N> Optional<N> getAncestorOfType(Class<N> classType) {
+        Node parent = getParentNode().orElse(null);
+        while (parent != null) {
+            if (classType.isAssignableFrom(parent.getClass())) {
+                return Optional.of(classType.cast(parent));
+            }
+            parent = parent.getParentNode().orElse(null);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/JavaParser.java b/javaparser-core/src/main/java/com/github/javaparser/JavaParser.java
new file mode 100644
index 0000000..7b8ee87
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/JavaParser.java
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.javadoc.Javadoc;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+
+import static com.github.javaparser.ParseStart.*;
+import static com.github.javaparser.Problem.PROBLEM_BY_BEGIN_POSITION;
+import static com.github.javaparser.Providers.*;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Parse Java source code and creates Abstract Syntax Trees.
+ *
+ * @author Júlio Vilmar Gesser
+ */
+public final class JavaParser {
+    private final ParserConfiguration configuration;
+
+    private GeneratedJavaParser astParser = null;
+    private static ParserConfiguration staticConfiguration = new ParserConfiguration();
+
+    /**
+     * Instantiate the parser with default configuration. Note that parsing can also be done with the static methods on
+     * this class.
+     * Creating an instance will reduce setup time between parsing files.
+     */
+    public JavaParser() {
+        this(new ParserConfiguration());
+    }
+
+    /**
+     * Instantiate the parser. Note that parsing can also be done with the static methods on this class.
+     * Creating an instance will reduce setup time between parsing files.
+     */
+    public JavaParser(ParserConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    /**
+     * Get the configuration for the static parse... methods.
+     * This is a STATIC field, so modifying it will directly change how all static parse... methods work!
+     */
+    public static ParserConfiguration getStaticConfiguration() {
+        return staticConfiguration;
+    }
+
+    /**
+     * Set the configuration for the static parse... methods.
+     * This is a STATIC field, so modifying it will directly change how all static parse... methods work!
+     */
+    public static void setStaticConfiguration(ParserConfiguration staticConfiguration) {
+        JavaParser.staticConfiguration = staticConfiguration;
+    }
+
+    /**
+     * Get the non-static configuration for this parser.
+     *
+     * @return The non-static configuration for this parser.
+     */
+    public ParserConfiguration getParserConfiguration() {
+        return this.configuration;
+    }
+
+    private GeneratedJavaParser getParserForProvider(Provider provider) {
+        if (astParser == null) {
+            astParser = new GeneratedJavaParser(provider);
+        } else {
+            astParser.reset(provider);
+        }
+        astParser.setTabSize(configuration.getTabSize());
+        astParser.setStoreTokens(configuration.isStoreTokens());
+        return astParser;
+    }
+
+    /**
+     * Parses source code.
+     * It takes the source code from a Provider.
+     * The start indicates what can be found in the source code (compilation unit, block, import...)
+     *
+     * @param start refer to the constants in ParseStart to see what can be parsed.
+     * @param provider refer to Providers to see how you can read source. The provider will be closed after parsing.
+     * @param <N> the subclass of Node that is the result of parsing in the start.
+     * @return the parse result, a collection of encountered problems, and some extra data.
+     */
+    public <N extends Node> ParseResult<N> parse(ParseStart<N> start, Provider provider) {
+        assertNotNull(start);
+        assertNotNull(provider);
+        final GeneratedJavaParser parser = getParserForProvider(provider);
+        try {
+            N resultNode = start.parse(parser);
+            ParseResult<N> result = new ParseResult<>(resultNode, parser.problems, parser.getTokens(),
+                    parser.getCommentsCollection());
+
+            configuration.getPostProcessors().forEach(postProcessor ->
+                    postProcessor.process(result, configuration));
+
+            result.getProblems().sort(PROBLEM_BY_BEGIN_POSITION);
+
+            return result;
+        } catch (Exception e) {
+            final String message = e.getMessage() == null ? "Unknown error" : e.getMessage();
+            parser.problems.add(new Problem(message, null, e));
+            return new ParseResult<>(null, parser.problems, parser.getTokens(), parser.getCommentsCollection());
+        } finally {
+            try {
+                provider.close();
+            } catch (IOException e) {
+                // Since we're done parsing and have our result, we don't care about any errors.
+            }
+        }
+    }
+
+    /**
+     * Parses the Java code contained in the {@link InputStream} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param in {@link InputStream} containing Java source code. It will be closed after parsing.
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final InputStream in, Charset encoding) {
+        return simplifiedParse(COMPILATION_UNIT, provider(in, encoding));
+    }
+
+    /**
+     * Parses the Java code contained in the {@link InputStream} and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param in {@link InputStream} containing Java source code. It will be closed after parsing.
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final InputStream in) {
+        return parse(in, UTF8);
+    }
+
+    /**
+     * Parses the Java code contained in a {@link File} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param file {@link File} containing Java source code. It will be closed after parsing.
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws FileNotFoundException the file was not found
+     */
+    public static CompilationUnit parse(final File file, final Charset encoding) throws FileNotFoundException {
+        return simplifiedParse(COMPILATION_UNIT, provider(file, encoding)).setStorage(file.toPath());
+    }
+
+    /**
+     * Parses the Java code contained in a {@link File} and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param file {@link File} containing Java source code. It will be closed after parsing.
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws FileNotFoundException the file was not found
+     */
+    public static CompilationUnit parse(final File file) throws FileNotFoundException {
+        return simplifiedParse(COMPILATION_UNIT, provider(file)).setStorage(file.toPath());
+    }
+
+    /**
+     * Parses the Java code contained in a file and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param path path to a file containing Java source code
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws IOException the path could not be accessed
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final Path path, final Charset encoding) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, provider(path, encoding)).setStorage(path);
+    }
+
+    /**
+     * Parses the Java code contained in a file and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param path path to a file containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parse(final Path path) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, provider(path)).setStorage(path);
+    }
+
+    /**
+     * Parses the Java code contained in a resource and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param path path to a resource containing Java source code. As resource is accessed through a class loader, a
+     * leading "/" is not allowed in pathToResource
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parseResource(final String path) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, resourceProvider(path));
+    }
+
+    /**
+     * Parses the Java code contained in a resource and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     *
+     * @param path path to a resource containing Java source code. As resource is accessed through a class loader, a
+     * leading "/" is not allowed in pathToResource
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parseResource(final String path, Charset encoding) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, resourceProvider(path, encoding));
+    }
+
+    /**
+     * Parses the Java code contained in a resource and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     *
+     * @param classLoader the classLoader that is asked to load the resource
+     * @param path path to a resource containing Java source code. As resource is accessed through a class loader, a
+     * leading "/" is not allowed in pathToResource
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parseResource(final ClassLoader classLoader, final String path, Charset encoding) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, resourceProvider(classLoader, path, encoding));
+    }
+
+    /**
+     * Parses Java code from a Reader and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     *
+     * @param reader the reader containing Java source code. It will be closed after parsing.
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final Reader reader) {
+        return simplifiedParse(COMPILATION_UNIT, provider(reader));
+    }
+
+    /**
+     * Parses the Java code contained in code and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param code Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(String code) {
+        return simplifiedParse(COMPILATION_UNIT, provider(code));
+    }
+
+    /**
+     * Parses the Java block contained in a {@link String} and returns a
+     * {@link BlockStmt} that represents it.
+     *
+     * @param blockStatement {@link String} containing Java block code
+     * @return BlockStmt representing the Java block
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static BlockStmt parseBlock(final String blockStatement) {
+        return simplifiedParse(BLOCK, provider(blockStatement));
+    }
+
+    /**
+     * Parses the Java statement contained in a {@link String} and returns a
+     * {@link Statement} that represents it.
+     *
+     * @param statement {@link String} containing Java statement code
+     * @return Statement representing the Java statement
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static Statement parseStatement(final String statement) {
+        return simplifiedParse(STATEMENT, provider(statement));
+    }
+
+    private static <T extends Node> T simplifiedParse(ParseStart<T> context, Provider provider) {
+        ParseResult<T> result = new JavaParser(staticConfiguration).parse(context, provider);
+        if (result.isSuccessful()) {
+            return result.getResult().get();
+        }
+        throw new ParseProblemException(result.getProblems());
+    }
+
+    /**
+     * Parses the Java import contained in a {@link String} and returns a
+     * {@link ImportDeclaration} that represents it.
+     *
+     * @param importDeclaration {@link String} containing Java import code
+     * @return ImportDeclaration representing the Java import declaration
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static ImportDeclaration parseImport(final String importDeclaration) {
+        return simplifiedParse(IMPORT_DECLARATION, provider(importDeclaration));
+    }
+
+    /**
+     * Parses the Java expression contained in a {@link String} and returns a
+     * {@link Expression} that represents it.
+     *
+     * @param expression {@link String} containing Java expression
+     * @return Expression representing the Java expression
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    @SuppressWarnings("unchecked")
+    public static <T extends Expression> T parseExpression(final String expression) {
+        return (T) simplifiedParse(EXPRESSION, provider(expression));
+    }
+
+    /**
+     * Parses the Java annotation contained in a {@link String} and returns a
+     * {@link AnnotationExpr} that represents it.
+     *
+     * @param annotation {@link String} containing Java annotation
+     * @return AnnotationExpr representing the Java annotation
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static AnnotationExpr parseAnnotation(final String annotation) {
+        return simplifiedParse(ANNOTATION, provider(annotation));
+    }
+
+    /**
+     * Parses the Java annotation body declaration(e.g fields or methods) contained in a
+     * {@link String} and returns a {@link BodyDeclaration} that represents it.
+     *
+     * @param body {@link String} containing Java body declaration
+     * @return BodyDeclaration representing the Java annotation
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static BodyDeclaration<?> parseAnnotationBodyDeclaration(final String body) {
+        return simplifiedParse(ANNOTATION_BODY, provider(body));
+    }
+
+    /**
+     * Parses a Java class body declaration(e.g fields or methods) and returns a
+     * {@link BodyDeclaration} that represents it.
+     *
+     * @param body the body of a class
+     * @return BodyDeclaration representing the Java class body
+     * @throws ParseProblemException if the source code has parser errors
+     * @deprecated just use parseBodyDeclaration now.
+     */
+    @Deprecated
+    public static BodyDeclaration<?> parseClassBodyDeclaration(String body) {
+        return parseBodyDeclaration(body);
+    }
+
+    /**
+     * Parses a Java interface body declaration(e.g fields or methods) and returns a
+     * {@link BodyDeclaration} that represents it.
+     *
+     * @param body the body of an interface
+     * @return BodyDeclaration representing the Java interface body
+     * @throws ParseProblemException if the source code has parser errors
+     * @deprecated just use parseBodyDeclaration now.
+     */
+    @Deprecated
+    public static BodyDeclaration<?> parseInterfaceBodyDeclaration(String body) {
+        return parseBodyDeclaration(body);
+    }
+
+    /**
+     * Parses a Java class or interface body declaration(e.g fields or methods) and returns a
+     * {@link BodyDeclaration} that represents it.
+     *
+     * @param body the body of a class or interface
+     * @return BodyDeclaration representing the Java interface body
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static BodyDeclaration<?> parseBodyDeclaration(String body) {
+        return simplifiedParse(CLASS_BODY, provider(body));
+    }
+
+    /**
+     * Parses a Java class or interface type name and returns a {@link ClassOrInterfaceType} that represents it.
+     *
+     * @param type the type name like a.b.c.X or Y
+     * @return ClassOrInterfaceType representing the type
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static ClassOrInterfaceType parseClassOrInterfaceType(String type) {
+        return simplifiedParse(CLASS_OR_INTERFACE_TYPE, provider(type));
+    }
+
+    /**
+     * Parses a Java type name and returns a {@link Type} that represents it.
+     *
+     * @param type the type name like a.b.c.X, Y, or int
+     * @return ClassOrInterfaceType representing the type
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static Type parseType(String type) {
+        return simplifiedParse(TYPE, provider(type));
+    }
+
+    /**
+     * Parses a variable declaration expression and returns a {@link com.github.javaparser.ast.expr.VariableDeclarationExpr}
+     * that represents it.
+     *
+     * @param declaration a variable declaration like <code>int x=2;</code>
+     * @return VariableDeclarationExpr representing the type
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static VariableDeclarationExpr parseVariableDeclarationExpr(String declaration) {
+        return simplifiedParse(VARIABLE_DECLARATION_EXPR, provider(declaration));
+    }
+
+    /**
+     * Parses the content of a JavadocComment and returns a {@link com.github.javaparser.javadoc.Javadoc} that
+     * represents it.
+     *
+     * @param content a variable declaration like <code>content of my javadoc\n * second line\n * third line</code>
+     * @return Javadoc representing the content of the comment
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static Javadoc parseJavadoc(String content) {
+        return JavadocParser.parse(content);
+    }
+
+    /**
+     * Parses the this(...) and super(...) statements that may occur at the start of a constructor.
+     *
+     * @param statement a statement like super("hello");
+     * @return the AST for the statement.
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static ExplicitConstructorInvocationStmt parseExplicitConstructorInvocationStmt(String statement) {
+        return simplifiedParse(EXPLICIT_CONSTRUCTOR_INVOCATION_STMT, provider(statement));
+    }
+
+    /**
+     * Parses a qualified name (one that can have "."s in it) and returns it as a Name.
+     *
+     * @param qualifiedName a name like "com.laamella.parameter_source"
+     * @return the AST for the name
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static Name parseName(String qualifiedName) {
+        return simplifiedParse(NAME, provider(qualifiedName));
+    }
+
+    /**
+     * Parses a simple name (one that can NOT have "."s in it) and returns it as a SimpleName.
+     *
+     * @param name a name like "parameter_source"
+     * @return the AST for the name
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static SimpleName parseSimpleName(String name) {
+        return simplifiedParse(SIMPLE_NAME, provider(name));
+    }
+
+    /**
+     * Parses a single parameter (a type and a name) and returns it as a Parameter.
+     *
+     * @param parameter a parameter like "int[] x"
+     * @return the AST for the parameter
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static Parameter parseParameter(String parameter) {
+        return simplifiedParse(PARAMETER, provider(parameter));
+    }
+
+
+    /**
+     * Parses a package declaration and returns it as a PackageDeclaration.
+     *
+     * @param packageDeclaration a declaration like "package com.microsoft.java;"
+     * @return the AST for the parameter
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static PackageDeclaration parsePackageDeclaration(String packageDeclaration) {
+        return simplifiedParse(PACKAGE_DECLARATION, provider(packageDeclaration));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java
new file mode 100644
index 0000000..ad56ff5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/JavaToken.java
@@ -0,0 +1,796 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser;
+
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.Utils.EOL;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+
+/**
+ * A token from a parsed source file.
+ * (Awkwardly named "Java"Token since JavaCC already generates an internal class Token.)
+ * It is a node in a double linked list called token list.
+ */
+public class JavaToken {
+
+    public static final JavaToken INVALID = new JavaToken();
+
+    private Range range;
+
+    private int kind;
+
+    private String text;
+
+    private JavaToken previousToken = null;
+
+    private JavaToken nextToken = null;
+
+    private JavaToken() {
+        this(null, 0, "INVALID", null, null);
+    }
+
+    public JavaToken(int kind, String text) {
+        this(null, kind, text, null, null);
+    }
+
+    JavaToken(Token token, List<JavaToken> tokens) {
+        // You could be puzzled by the following lines
+        // 
+        // The reason why these lines are necessary is the fact that Java is ambiguous. There are cases where the
+        // sequence of characters ">>>" and ">>" should be recognized as the single tokens ">>>" and ">>". In other
+        // cases however we want to split those characters in single GT tokens (">").
+        // 
+        // For example, in expressions ">>" and ">>>" are valid, while when defining types we could have this:
+        // 
+        // List<List<Set<String>>>>
+        // 
+        // You can see that the sequence ">>>>" should be interpreted as four consecutive ">" tokens closing a type
+        // parameter list.
+        // 
+        // The JavaCC handle this case by first recognizing always the longest token, and then depending on the context
+        // putting back the unused chars in the stream. However in those cases the token provided is invalid: it has an
+        // image corresponding to the text originally recognized, without considering that after some characters could
+        // have been put back into the stream.
+        // 
+        // So in the case of:
+        // 
+        // List<List<Set<String>>>>
+        // ___   -> recognized as ">>>", then ">>" put back in the stream but Token(type=GT, image=">>>") passed to this class
+        // ___  -> recognized as ">>>", then ">>" put back in the stream but Token(type=GT, image=">>>") passed to this class
+        // __  -> recognized as ">>", then ">" put back in the stream but Token(type=GT, image=">>") passed to this class
+        // _  -> Token(type=GT, image=">") good!
+        // 
+        // So given the image could be wrong but the type is correct, we look at the type of the token and we fix
+        // the image. Everybody is happy and we can keep this horrible thing as our little secret.
+        Range range = Range.range(token.beginLine, token.beginColumn, token.endLine, token.endColumn);
+        String text = token.image;
+        if (token.kind == GeneratedJavaParserConstants.GT) {
+            range = Range.range(token.beginLine, token.beginColumn, token.endLine, token.beginColumn);
+            text = ">";
+        } else if (token.kind == GeneratedJavaParserConstants.RSIGNEDSHIFT) {
+            range = Range.range(token.beginLine, token.beginColumn, token.endLine, token.beginColumn + 1);
+            text = ">>";
+        }
+        this.range = range;
+        this.kind = token.kind;
+        this.text = text;
+        if (!tokens.isEmpty()) {
+            final JavaToken previousToken = tokens.get(tokens.size() - 1);
+            this.previousToken = previousToken;
+            previousToken.nextToken = this;
+        } else {
+            previousToken = null;
+        }
+    }
+
+    /**
+     * Create a token of a certain kind.
+     */
+    public JavaToken(int kind) {
+        String content = GeneratedJavaParserConstants.tokenImage[kind];
+        if (content.startsWith("\"")) {
+            content = content.substring(1, content.length() - 1);
+        }
+        if (TokenTypes.isEndOfLineToken(kind)) {
+            content = EOL;
+        } else if (TokenTypes.isWhitespace(kind)) {
+            content = " ";
+        }
+        this.kind = kind;
+        this.text = content;
+    }
+
+    public JavaToken(Range range, int kind, String text, JavaToken previousToken, JavaToken nextToken) {
+        assertNotNull(text);
+        this.range = range;
+        this.kind = kind;
+        this.text = text;
+        this.previousToken = previousToken;
+        this.nextToken = nextToken;
+    }
+
+    public Optional<Range> getRange() {
+        return Optional.ofNullable(range);
+    }
+
+    public int getKind() {
+        return kind;
+    }
+
+    void setKind(int kind) {
+        this.kind = kind;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public Optional<JavaToken> getNextToken() {
+        return Optional.ofNullable(nextToken);
+    }
+
+    public Optional<JavaToken> getPreviousToken() {
+        return Optional.ofNullable(previousToken);
+    }
+
+    public void setRange(Range range) {
+        this.range = range;
+    }
+
+    public void setText(String text) {
+        this.text = text;
+    }
+
+    public String asString() {
+        return text;
+    }
+
+    /**
+     * @return the token range that goes from the beginning to the end of the token list this token is a part of.
+     */
+    public TokenRange toTokenRange() {
+        return new TokenRange(findFirstToken(), findLastToken());
+    }
+
+    @Override
+    public String toString() {
+        String text = getText().replace("\n", "\\n").replace("\r", "\\r").replace("\r\n", "\\r\\n").replace("\t", "\\t");
+        return f("\"%s\"   <%s>   %s", text, getKind(), getRange().map(Range::toString).orElse("(?)-(?)"));
+    }
+
+    /**
+     * Used by the parser while constructing nodes. No tokens should be invalid when the parser is done.
+     */
+    public boolean valid() {
+        return !invalid();
+    }
+
+    /**
+     * Used by the parser while constructing nodes. No tokens should be invalid when the parser is done.
+     */
+    public boolean invalid() {
+        return this == INVALID;
+    }
+
+    public enum Category {
+
+        WHITESPACE_NO_EOL,
+        EOL,
+        COMMENT,
+        IDENTIFIER,
+        KEYWORD,
+        LITERAL,
+        SEPARATOR,
+        OPERATOR;
+
+        public boolean isWhitespaceOrComment() {
+            return isWhitespace() || this == COMMENT;
+        }
+
+        public boolean isWhitespace() {
+            return this == WHITESPACE_NO_EOL || this == EOL;
+        }
+
+        public boolean isEndOfLine() {
+            return this == EOL;
+        }
+
+        public boolean isComment() {
+            return this == COMMENT;
+        }
+
+        public boolean isWhitespaceButNotEndOfLine() {
+            return this == WHITESPACE_NO_EOL;
+        }
+
+        public boolean isIdentifier() {
+            return this == IDENTIFIER;
+        }
+
+        public boolean isKeyword() {
+            return this == KEYWORD;
+        }
+
+        public boolean isLiteral() {
+            return this == LITERAL;
+        }
+
+        public boolean isSeparator() {
+            return this == SEPARATOR;
+        }
+
+        public boolean isOperator() {
+            return this == OPERATOR;
+        }
+    }
+
+    @Generated("com.github.javaparser.generator.core.other.TokenKindGenerator")
+    public enum Kind {
+
+        EOF(0),
+        SPACE(1),
+        WINDOWS_EOL(2),
+        UNIX_EOL(3),
+        OLD_MAC_EOL(4),
+        SINGLE_LINE_COMMENT(5),
+        ENTER_JAVADOC_COMMENT(6),
+        ENTER_MULTILINE_COMMENT(7),
+        JAVADOC_COMMENT(8),
+        MULTI_LINE_COMMENT(9),
+        COMMENT_CONTENT(10),
+        ABSTRACT(11),
+        ASSERT(12),
+        BOOLEAN(13),
+        BREAK(14),
+        BYTE(15),
+        CASE(16),
+        CATCH(17),
+        CHAR(18),
+        CLASS(19),
+        CONST(20),
+        CONTINUE(21),
+        _DEFAULT(22),
+        DO(23),
+        DOUBLE(24),
+        ELSE(25),
+        ENUM(26),
+        EXTENDS(27),
+        FALSE(28),
+        FINAL(29),
+        FINALLY(30),
+        FLOAT(31),
+        FOR(32),
+        GOTO(33),
+        IF(34),
+        IMPLEMENTS(35),
+        IMPORT(36),
+        INSTANCEOF(37),
+        INT(38),
+        INTERFACE(39),
+        LONG(40),
+        NATIVE(41),
+        NEW(42),
+        NULL(43),
+        PACKAGE(44),
+        PRIVATE(45),
+        PROTECTED(46),
+        PUBLIC(47),
+        RETURN(48),
+        SHORT(49),
+        STATIC(50),
+        STRICTFP(51),
+        SUPER(52),
+        SWITCH(53),
+        SYNCHRONIZED(54),
+        THIS(55),
+        THROW(56),
+        THROWS(57),
+        TRANSIENT(58),
+        TRUE(59),
+        TRY(60),
+        VOID(61),
+        VOLATILE(62),
+        WHILE(63),
+        REQUIRES(64),
+        TO(65),
+        WITH(66),
+        OPEN(67),
+        OPENS(68),
+        USES(69),
+        MODULE(70),
+        EXPORTS(71),
+        PROVIDES(72),
+        TRANSITIVE(73),
+        LONG_LITERAL(74),
+        INTEGER_LITERAL(75),
+        DECIMAL_LITERAL(76),
+        HEX_LITERAL(77),
+        OCTAL_LITERAL(78),
+        BINARY_LITERAL(79),
+        FLOATING_POINT_LITERAL(80),
+        DECIMAL_FLOATING_POINT_LITERAL(81),
+        DECIMAL_EXPONENT(82),
+        HEXADECIMAL_FLOATING_POINT_LITERAL(83),
+        HEXADECIMAL_EXPONENT(84),
+        HEX_DIGITS(85),
+        UNICODE_ESCAPE(86),
+        CHARACTER_LITERAL(87),
+        STRING_LITERAL(88),
+        IDENTIFIER(89),
+        LETTER(90),
+        PART_LETTER(91),
+        LPAREN(92),
+        RPAREN(93),
+        LBRACE(94),
+        RBRACE(95),
+        LBRACKET(96),
+        RBRACKET(97),
+        SEMICOLON(98),
+        COMMA(99),
+        DOT(100),
+        AT(101),
+        ASSIGN(102),
+        LT(103),
+        BANG(104),
+        TILDE(105),
+        HOOK(106),
+        COLON(107),
+        EQ(108),
+        LE(109),
+        GE(110),
+        NE(111),
+        SC_OR(112),
+        SC_AND(113),
+        INCR(114),
+        DECR(115),
+        PLUS(116),
+        MINUS(117),
+        STAR(118),
+        SLASH(119),
+        BIT_AND(120),
+        BIT_OR(121),
+        XOR(122),
+        REM(123),
+        LSHIFT(124),
+        PLUSASSIGN(125),
+        MINUSASSIGN(126),
+        STARASSIGN(127),
+        SLASHASSIGN(128),
+        ANDASSIGN(129),
+        ORASSIGN(130),
+        XORASSIGN(131),
+        REMASSIGN(132),
+        LSHIFTASSIGN(133),
+        RSIGNEDSHIFTASSIGN(134),
+        RUNSIGNEDSHIFTASSIGN(135),
+        ELLIPSIS(136),
+        ARROW(137),
+        DOUBLECOLON(138),
+        RUNSIGNEDSHIFT(139),
+        RSIGNEDSHIFT(140),
+        GT(141),
+        CTRL_Z(142);
+
+        private final int kind;
+
+        Kind(int kind) {
+            this.kind = kind;
+        }
+
+        public static Kind valueOf(int kind) {
+            switch(kind) {
+                case 142:
+                    return CTRL_Z;
+                case 141:
+                    return GT;
+                case 140:
+                    return RSIGNEDSHIFT;
+                case 139:
+                    return RUNSIGNEDSHIFT;
+                case 138:
+                    return DOUBLECOLON;
+                case 137:
+                    return ARROW;
+                case 136:
+                    return ELLIPSIS;
+                case 135:
+                    return RUNSIGNEDSHIFTASSIGN;
+                case 134:
+                    return RSIGNEDSHIFTASSIGN;
+                case 133:
+                    return LSHIFTASSIGN;
+                case 132:
+                    return REMASSIGN;
+                case 131:
+                    return XORASSIGN;
+                case 130:
+                    return ORASSIGN;
+                case 129:
+                    return ANDASSIGN;
+                case 128:
+                    return SLASHASSIGN;
+                case 127:
+                    return STARASSIGN;
+                case 126:
+                    return MINUSASSIGN;
+                case 125:
+                    return PLUSASSIGN;
+                case 124:
+                    return LSHIFT;
+                case 123:
+                    return REM;
+                case 122:
+                    return XOR;
+                case 121:
+                    return BIT_OR;
+                case 120:
+                    return BIT_AND;
+                case 119:
+                    return SLASH;
+                case 118:
+                    return STAR;
+                case 117:
+                    return MINUS;
+                case 116:
+                    return PLUS;
+                case 115:
+                    return DECR;
+                case 114:
+                    return INCR;
+                case 113:
+                    return SC_AND;
+                case 112:
+                    return SC_OR;
+                case 111:
+                    return NE;
+                case 110:
+                    return GE;
+                case 109:
+                    return LE;
+                case 108:
+                    return EQ;
+                case 107:
+                    return COLON;
+                case 106:
+                    return HOOK;
+                case 105:
+                    return TILDE;
+                case 104:
+                    return BANG;
+                case 103:
+                    return LT;
+                case 102:
+                    return ASSIGN;
+                case 101:
+                    return AT;
+                case 100:
+                    return DOT;
+                case 99:
+                    return COMMA;
+                case 98:
+                    return SEMICOLON;
+                case 97:
+                    return RBRACKET;
+                case 96:
+                    return LBRACKET;
+                case 95:
+                    return RBRACE;
+                case 94:
+                    return LBRACE;
+                case 93:
+                    return RPAREN;
+                case 92:
+                    return LPAREN;
+                case 91:
+                    return PART_LETTER;
+                case 90:
+                    return LETTER;
+                case 89:
+                    return IDENTIFIER;
+                case 88:
+                    return STRING_LITERAL;
+                case 87:
+                    return CHARACTER_LITERAL;
+                case 86:
+                    return UNICODE_ESCAPE;
+                case 85:
+                    return HEX_DIGITS;
+                case 84:
+                    return HEXADECIMAL_EXPONENT;
+                case 83:
+                    return HEXADECIMAL_FLOATING_POINT_LITERAL;
+                case 82:
+                    return DECIMAL_EXPONENT;
+                case 81:
+                    return DECIMAL_FLOATING_POINT_LITERAL;
+                case 80:
+                    return FLOATING_POINT_LITERAL;
+                case 79:
+                    return BINARY_LITERAL;
+                case 78:
+                    return OCTAL_LITERAL;
+                case 77:
+                    return HEX_LITERAL;
+                case 76:
+                    return DECIMAL_LITERAL;
+                case 75:
+                    return INTEGER_LITERAL;
+                case 74:
+                    return LONG_LITERAL;
+                case 73:
+                    return TRANSITIVE;
+                case 72:
+                    return PROVIDES;
+                case 71:
+                    return EXPORTS;
+                case 70:
+                    return MODULE;
+                case 69:
+                    return USES;
+                case 68:
+                    return OPENS;
+                case 67:
+                    return OPEN;
+                case 66:
+                    return WITH;
+                case 65:
+                    return TO;
+                case 64:
+                    return REQUIRES;
+                case 63:
+                    return WHILE;
+                case 62:
+                    return VOLATILE;
+                case 61:
+                    return VOID;
+                case 60:
+                    return TRY;
+                case 59:
+                    return TRUE;
+                case 58:
+                    return TRANSIENT;
+                case 57:
+                    return THROWS;
+                case 56:
+                    return THROW;
+                case 55:
+                    return THIS;
+                case 54:
+                    return SYNCHRONIZED;
+                case 53:
+                    return SWITCH;
+                case 52:
+                    return SUPER;
+                case 51:
+                    return STRICTFP;
+                case 50:
+                    return STATIC;
+                case 49:
+                    return SHORT;
+                case 48:
+                    return RETURN;
+                case 47:
+                    return PUBLIC;
+                case 46:
+                    return PROTECTED;
+                case 45:
+                    return PRIVATE;
+                case 44:
+                    return PACKAGE;
+                case 43:
+                    return NULL;
+                case 42:
+                    return NEW;
+                case 41:
+                    return NATIVE;
+                case 40:
+                    return LONG;
+                case 39:
+                    return INTERFACE;
+                case 38:
+                    return INT;
+                case 37:
+                    return INSTANCEOF;
+                case 36:
+                    return IMPORT;
+                case 35:
+                    return IMPLEMENTS;
+                case 34:
+                    return IF;
+                case 33:
+                    return GOTO;
+                case 32:
+                    return FOR;
+                case 31:
+                    return FLOAT;
+                case 30:
+                    return FINALLY;
+                case 29:
+                    return FINAL;
+                case 28:
+                    return FALSE;
+                case 27:
+                    return EXTENDS;
+                case 26:
+                    return ENUM;
+                case 25:
+                    return ELSE;
+                case 24:
+                    return DOUBLE;
+                case 23:
+                    return DO;
+                case 22:
+                    return _DEFAULT;
+                case 21:
+                    return CONTINUE;
+                case 20:
+                    return CONST;
+                case 19:
+                    return CLASS;
+                case 18:
+                    return CHAR;
+                case 17:
+                    return CATCH;
+                case 16:
+                    return CASE;
+                case 15:
+                    return BYTE;
+                case 14:
+                    return BREAK;
+                case 13:
+                    return BOOLEAN;
+                case 12:
+                    return ASSERT;
+                case 11:
+                    return ABSTRACT;
+                case 10:
+                    return COMMENT_CONTENT;
+                case 9:
+                    return MULTI_LINE_COMMENT;
+                case 8:
+                    return JAVADOC_COMMENT;
+                case 7:
+                    return ENTER_MULTILINE_COMMENT;
+                case 6:
+                    return ENTER_JAVADOC_COMMENT;
+                case 5:
+                    return SINGLE_LINE_COMMENT;
+                case 4:
+                    return OLD_MAC_EOL;
+                case 3:
+                    return UNIX_EOL;
+                case 2:
+                    return WINDOWS_EOL;
+                case 1:
+                    return SPACE;
+                case 0:
+                    return EOF;
+                default:
+                    throw new IllegalArgumentException(f("Token kind %i is unknown.", kind));
+            }
+        }
+
+        public int getKind() {
+            return kind;
+        }
+    }
+
+    public JavaToken.Category getCategory() {
+        return TokenTypes.getCategory(kind);
+    }
+
+    /**
+     * Inserts newToken into the token list just before this token.
+     */
+    public void insert(JavaToken newToken) {
+        assertNotNull(newToken);
+        getPreviousToken().ifPresent(p -> {
+            p.nextToken = newToken;
+            newToken.previousToken = p;
+        });
+        previousToken = newToken;
+        newToken.nextToken = this;
+    }
+
+    /**
+     * Inserts newToken into the token list just after this token.
+     */
+    public void insertAfter(JavaToken newToken) {
+        assertNotNull(newToken);
+        getNextToken().ifPresent(n -> {
+            n.previousToken = newToken;
+            newToken.nextToken = n;
+        });
+        nextToken = newToken;
+        newToken.previousToken = this;
+    }
+
+    /**
+     * Links the tokens around the current token together, making the current token disappear from the list.
+     */
+    public void deleteToken() {
+        final Optional<JavaToken> nextToken = getNextToken();
+        final Optional<JavaToken> previousToken = getPreviousToken();
+        previousToken.ifPresent(p -> p.nextToken = nextToken.orElse(null));
+        nextToken.ifPresent(n -> n.previousToken = previousToken.orElse(null));
+    }
+
+    /**
+     * Replaces the current token with newToken.
+     */
+    public void replaceToken(JavaToken newToken) {
+        assertNotNull(newToken);
+        getPreviousToken().ifPresent(p -> {
+            p.nextToken = newToken;
+            newToken.previousToken = p;
+        });
+        getNextToken().ifPresent(n -> {
+            n.previousToken = newToken;
+            newToken.nextToken = n;
+        });
+    }
+
+    /**
+     * @return the last token in the token list.
+     */
+    public JavaToken findLastToken() {
+        JavaToken current = this;
+        while (current.getNextToken().isPresent()) {
+            current = current.getNextToken().get();
+        }
+        return current;
+    }
+
+    /**
+     * @return the first token in the token list.
+     */
+    public JavaToken findFirstToken() {
+        JavaToken current = this;
+        while (current.getPreviousToken().isPresent()) {
+            current = current.getPreviousToken().get();
+        }
+        return current;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = kind;
+        result = 31 * result + text.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        JavaToken javaToken = (JavaToken) o;
+        if (kind != javaToken.kind)
+            return false;
+        if (!text.equals(javaToken.text))
+            return false;
+        return true;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/JavadocParser.java b/javaparser-core/src/main/java/com/github/javaparser/JavadocParser.java
new file mode 100644
index 0000000..bbe9797
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/JavadocParser.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.javadoc.Javadoc;
+import com.github.javaparser.javadoc.JavadocBlockTag;
+import com.github.javaparser.javadoc.description.JavadocDescription;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.utils.Utils.*;
+import static com.github.javaparser.utils.Utils.nextWord;
+
+/**
+ * The class responsible for parsing the content of JavadocComments and produce JavadocDocuments.
+ */
+class JavadocParser {
+
+    private static String BLOCK_TAG_PREFIX = "@";
+    private static Pattern BLOCK_PATTERN = Pattern.compile("^" + BLOCK_TAG_PREFIX, Pattern.MULTILINE);
+
+    public static Javadoc parse(JavadocComment comment) {
+        return parse(comment.getContent());
+    }
+
+    public static Javadoc parse(String commentContent) {
+        List<String> cleanLines = cleanLines(normalizeEolInTextBlock(commentContent, EOL));
+        int indexOfFirstBlockTag = cleanLines.stream()
+                .filter(JavadocParser::isABlockLine)
+                .map(cleanLines::indexOf)
+                .findFirst()
+                .orElse(-1);
+        List<String> blockLines;
+        String descriptionText;
+        if (indexOfFirstBlockTag == -1) {
+            descriptionText = trimRight(String.join(EOL, cleanLines));
+            blockLines = Collections.emptyList();
+        } else {
+            descriptionText = trimRight(String.join(EOL, cleanLines.subList(0, indexOfFirstBlockTag)));
+
+            //Combine cleaned lines, but only starting with the first block tag till the end
+            //In this combined string it is easier to handle multiple lines which actually belong together
+            String tagBlock = cleanLines.subList(indexOfFirstBlockTag, cleanLines.size())
+                .stream()
+                .collect(Collectors.joining(EOL));
+
+            //Split up the entire tag back again, considering now that some lines belong to the same block tag.
+            //The pattern splits the block at each new line starting with the '@' symbol, thus the symbol
+            //then needs to be added again so that the block parsers handles everything correctly.
+            blockLines = BLOCK_PATTERN
+                .splitAsStream(tagBlock)
+                .filter(STRING_NOT_EMPTY)
+                .map(s -> BLOCK_TAG_PREFIX + s)
+                .collect(Collectors.toList());
+        }
+        Javadoc document = new Javadoc(JavadocDescription.parseText(descriptionText));
+        blockLines.forEach(l -> document.addBlockTag(parseBlockTag(l)));
+        return document;
+    }
+
+    private static JavadocBlockTag parseBlockTag(String line) {
+        line = line.trim().substring(1);
+        String tagName = nextWord(line);
+        String rest = line.substring(tagName.length()).trim();
+        return new JavadocBlockTag(tagName, rest);
+    }
+
+    private static boolean isABlockLine(String line) {
+        return line.trim().startsWith(BLOCK_TAG_PREFIX);
+    }
+
+    private static String trimRight(String string) {
+        while (!string.isEmpty() && Character.isWhitespace(string.charAt(string.length() - 1))) {
+            string = string.substring(0, string.length() - 1);
+        }
+        return string;
+    }
+
+    private static List<String> cleanLines(String content) {
+        String[] lines = content.split(EOL);
+        List<String> cleanedLines = Arrays.stream(lines).map(l -> {
+            int asteriskIndex = startsWithAsterisk(l);
+            if (asteriskIndex == -1) {
+                return l;
+            } else {
+                // if a line starts with space followed by an asterisk drop to the asterisk
+                // if there is a space immediately after the asterisk drop it also
+                if (l.length() > (asteriskIndex + 1)) {
+
+                    char c = l.charAt(asteriskIndex + 1);
+                    if (c == ' ' || c == '\t') {
+                        return l.substring(asteriskIndex + 2);
+                    }
+                }
+                return l.substring(asteriskIndex + 1);
+            }
+        }).collect(Collectors.toList());
+        // lines containing only whitespace are normalized to empty lines
+        cleanedLines = cleanedLines.stream().map(l -> l.trim().isEmpty() ? "" : l).collect(Collectors.toList());
+        // if the first starts with a space, remove it
+        if (!cleanedLines.get(0).isEmpty() && (cleanedLines.get(0).charAt(0) == ' ' || cleanedLines.get(0).charAt(0) == '\t')) {
+            cleanedLines.set(0, cleanedLines.get(0).substring(1));
+        }
+        // drop empty lines at the beginning and at the end
+        while (cleanedLines.size() > 0 && cleanedLines.get(0).trim().isEmpty()) {
+            cleanedLines = cleanedLines.subList(1, cleanedLines.size());
+        }
+        while (cleanedLines.size() > 0 && cleanedLines.get(cleanedLines.size() - 1).trim().isEmpty()) {
+            cleanedLines = cleanedLines.subList(0, cleanedLines.size() - 1);
+        }
+        return cleanedLines;
+    }
+
+    // Visible for testing
+    static int startsWithAsterisk(String line) {
+        if (line.startsWith("*")) {
+            return 0;
+        } else if ((line.startsWith(" ") || line.startsWith("\t")) && line.length() > 1) {
+            int res = startsWithAsterisk(line.substring(1));
+            if (res == -1) {
+                return -1;
+            } else {
+                return 1 + res;
+            }
+        } else {
+            return -1;
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ParseProblemException.java b/javaparser-core/src/main/java/com/github/javaparser/ParseProblemException.java
new file mode 100644
index 0000000..50064dc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ParseProblemException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.Collections.singletonList;
+
+/**
+ * Thrown when parsing problems occur during parsing with the static methods on JavaParser.
+ */
+public class ParseProblemException extends RuntimeException {
+    /**
+     * The problems that were encountered during parsing
+     */
+    private final List<Problem> problems;
+
+    public ParseProblemException(List<Problem> problems) {
+        super(createMessage(assertNotNull(problems)));
+        this.problems = problems;
+    }
+
+    public ParseProblemException(Throwable throwable) {
+        this(singletonList(new Problem(throwable.getMessage(), null, throwable)));
+    }
+
+    private static String createMessage(List<Problem> problems) {
+        StringBuilder message = new StringBuilder();
+        for (Problem problem : problems) {
+            message.append(problem.toString()).append(EOL);
+        }
+        return message.toString();
+    }
+
+    public List<Problem> getProblems() {
+        return problems;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ParseResult.java b/javaparser-core/src/main/java/com/github/javaparser/ParseResult.java
new file mode 100644
index 0000000..4edc79a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ParseResult.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.CommentsCollection;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+import static com.github.javaparser.utils.Utils.EOL;
+
+/**
+ * The results given when parsing with an instance of JavaParser.
+ */
+public class ParseResult<T> {
+    private final T result;
+    private final List<Problem> problems;
+    private final List<JavaToken> tokens;
+    private final CommentsCollection commentsCollection;
+
+    /**
+     * General constructor.
+     *
+     * @param result the AST, or empty if it wasn't created.
+     * @param problems a list of encountered parsing problems.
+     * @param tokens the complete list of tokens that were parsed, or empty if parsing failed completely.
+     */
+    public ParseResult(T result, List<Problem> problems, List<JavaToken> tokens, CommentsCollection commentsCollection) {
+        this.commentsCollection = commentsCollection;
+        this.result = result;
+        this.problems = problems;
+        this.tokens = tokens;
+    }
+
+    /**
+     * @return if parsing was successful, meaning no errors of any kind were encountered.
+     */
+    public boolean isSuccessful() {
+        return problems.isEmpty() && result != null;
+    }
+
+    /**
+     * Calls the consumer with the result if parsing was succesful.
+     */
+    public void ifSuccessful(Consumer<T> consumer) {
+        if (isSuccessful()) {
+            consumer.accept(result);
+        }
+    }
+
+    /**
+     * @return the list of encountered parsing problems. Empty when no problems were encountered.
+     */
+    public List<Problem> getProblems() {
+        return problems;
+    }
+
+    /**
+     * @return the <code>i</code>'th encountered parsing problem. May throw <code>IndexOutOfBoundsException</code>.
+     */
+    public Problem getProblem(int i) {
+        return getProblems().get(i);
+    }
+
+    /**
+     * @return the complete list of tokens that were parsed, or empty if parsing failed completely.
+     * @deprecated lists of tokens are now kept in every node.
+     * Calling this method is comparable to calling getResult().get().getTokenRange().get()
+     */
+    @Deprecated
+    public Optional<List<JavaToken>> getTokens() {
+        return Optional.ofNullable(tokens);
+    }
+
+    /**
+     * @return the complete collection of comments encountered while parsing.
+     */
+    public Optional<CommentsCollection> getCommentsCollection() {
+        return Optional.ofNullable(commentsCollection);
+    }
+
+    /**
+     * @return the AST of the parsed source code, or empty if parsing failed completely.
+     */
+    public Optional<T> getResult() {
+        return Optional.ofNullable(result);
+    }
+
+    @Override
+    public String toString() {
+        if (isSuccessful()) {
+            return "Parsing successful";
+        }
+        StringBuilder message = new StringBuilder("Parsing failed:").append(EOL);
+        for (Problem problem : problems) {
+            message.append(problem.toString()).append(EOL);
+        }
+        return message.toString();
+    }
+
+    /**
+     * A post processor that can be added to ParserConfiguration to add some processing right after parsing.
+     */
+    public interface PostProcessor {
+        void process(ParseResult<? extends Node> result, ParserConfiguration configuration);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ParseStart.java b/javaparser-core/src/main/java/com/github/javaparser/ParseStart.java
new file mode 100644
index 0000000..ecb562c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ParseStart.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+
+/**
+ * The start production for JavaParser.
+ * Tells JavaParser what piece of Java code it can expect.
+ * For example,
+ * COMPILATION_UNIT indicates a complete Java file,
+ * and CLASS_BODY would indicate the part of a class that is within { and }.
+ *
+ * @see JavaParser#parse(ParseStart, Provider)
+ */
+@FunctionalInterface
+public interface ParseStart<R> {
+    ParseStart<CompilationUnit> COMPILATION_UNIT = GeneratedJavaParser::CompilationUnit;
+    ParseStart<BlockStmt> BLOCK = GeneratedJavaParser::BlockParseStart;
+    ParseStart<Statement> STATEMENT = GeneratedJavaParser::BlockStatementParseStart;
+    ParseStart<ImportDeclaration> IMPORT_DECLARATION = GeneratedJavaParser::ImportDeclarationParseStart;
+    ParseStart<Expression> EXPRESSION = GeneratedJavaParser::ExpressionParseStart;
+    ParseStart<AnnotationExpr> ANNOTATION = GeneratedJavaParser::AnnotationParseStart;
+    ParseStart<BodyDeclaration<?>> ANNOTATION_BODY = GeneratedJavaParser::AnnotationBodyDeclarationParseStart;
+    ParseStart<BodyDeclaration<?>> CLASS_BODY = GeneratedJavaParser::ClassOrInterfaceBodyDeclarationParseStart;
+    ParseStart<ClassOrInterfaceType> CLASS_OR_INTERFACE_TYPE = GeneratedJavaParser::ClassOrInterfaceTypeParseStart;
+    ParseStart<Type> TYPE = GeneratedJavaParser::ResultTypeParseStart;
+    ParseStart<VariableDeclarationExpr> VARIABLE_DECLARATION_EXPR = GeneratedJavaParser::VariableDeclarationExpressionParseStart;
+    ParseStart<ExplicitConstructorInvocationStmt> EXPLICIT_CONSTRUCTOR_INVOCATION_STMT = GeneratedJavaParser::ExplicitConstructorInvocationParseStart;
+    ParseStart<Name> NAME = GeneratedJavaParser::NameParseStart;
+    ParseStart<SimpleName> SIMPLE_NAME = GeneratedJavaParser::SimpleNameParseStart;
+    ParseStart<Parameter> PARAMETER = GeneratedJavaParser::ParameterParseStart;
+    ParseStart<PackageDeclaration> PACKAGE_DECLARATION = GeneratedJavaParser::PackageDeclarationParseStart;
+
+    R parse(GeneratedJavaParser parser) throws ParseException;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ParserConfiguration.java b/javaparser-core/src/main/java/com/github/javaparser/ParserConfiguration.java
new file mode 100644
index 0000000..e5be2b8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ParserConfiguration.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.validator.*;
+import com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter;
+import com.github.javaparser.resolution.SymbolResolver;
+import com.github.javaparser.version.Java10PostProcessor;
+import com.github.javaparser.version.Java11PostProcessor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * The configuration that is used by the parser.
+ * Note that this can be changed even when reusing the same JavaParser instance.
+ * It will pick up the changes.
+ */
+public class ParserConfiguration {
+    public enum LanguageLevel {
+        /** Does no post processing or validation. Only for people wanting the fastest parsing. */
+        RAW(null, null),
+        /** The most used Java version. */
+        POPULAR(new Java8Validator(), null),
+        /** The latest Java version that is available. */
+        CURRENT(new Java8Validator(), null),
+        /** The newest Java features supported. */
+        BLEEDING_EDGE(new Java11Validator(), new Java11PostProcessor()),
+        /** Java 1.0 */
+        JAVA_1_0(new Java1_0Validator(), null),
+        /** Java 1.1 */
+        JAVA_1_1(new Java1_1Validator(), null),
+        /** Java 1.2 */
+        JAVA_1_2(new Java1_2Validator(), null),
+        /** Java 1.3 */
+        JAVA_1_3(new Java1_3Validator(), null),
+        /** Java 1.4 */
+        JAVA_1_4(new Java1_4Validator(), null),
+        /** Java 5 */
+        JAVA_5(new Java5Validator(), null),
+        /** Java 6 */
+        JAVA_6(new Java6Validator(), null),
+        /** Java 7 */
+        JAVA_7(new Java7Validator(), null),
+        /** Java 8 */
+        JAVA_8(new Java8Validator(), null),
+        /** Java 9 */
+        JAVA_9(new Java9Validator(), null),
+        /** Java 10 */
+        JAVA_10(new Java10Validator(), new Java10PostProcessor()),
+        /** Java 11 (work in progress) */
+        JAVA_11_PREVIEW(new Java11Validator(), new Java11PostProcessor());
+
+        final Validator validator;
+        final ParseResult.PostProcessor postProcessor;
+
+        LanguageLevel(Validator validator, ParseResult.PostProcessor postProcessor) {
+            this.validator = validator;
+            this.postProcessor = postProcessor;
+        }
+    }
+
+    private boolean storeTokens = true;
+    private boolean attributeComments = true;
+    private boolean doNotAssignCommentsPrecedingEmptyLines = true;
+    private boolean doNotConsiderAnnotationsAsNodeStartForCodeAttribution = false;
+    private boolean lexicalPreservationEnabled = false;
+    private SymbolResolver symbolResolver = null;
+    private int tabSize = 1;
+    private LanguageLevel languageLevel = CURRENT;
+
+    private final List<ParseResult.PostProcessor> postProcessors = new ArrayList<>();
+
+    public ParserConfiguration() {
+        postProcessors.add((result, configuration) -> {
+            if (configuration.isLexicalPreservationEnabled()) {
+                if (configuration.isLexicalPreservationEnabled()) {
+                    result.ifSuccessful(LexicalPreservingPrinter::setup);
+                }
+            }
+        });
+        postProcessors.add((result, configuration) -> {
+            if (configuration.isAttributeComments()) {
+                result.ifSuccessful(resultNode -> result
+                        .getCommentsCollection().ifPresent(comments ->
+                                new CommentsInserter(configuration).insertComments(resultNode, comments.copy().getComments())));
+            }
+        });
+        postProcessors.add((result, configuration) -> {
+            LanguageLevel languageLevel = getLanguageLevel();
+            if (languageLevel.postProcessor != null) {
+                languageLevel.postProcessor.process(result, configuration);
+            }
+            if (languageLevel.validator != null) {
+                languageLevel.validator.accept(result.getResult().get(), new ProblemReporter(newProblem -> result.getProblems().add(newProblem)));
+            }
+        });
+        postProcessors.add((result, configuration) -> configuration.getSymbolResolver().ifPresent(symbolResolver ->
+                result.ifSuccessful(resultNode -> {
+                    if (resultNode instanceof CompilationUnit) {
+                        resultNode.setData(Node.SYMBOL_RESOLVER_KEY, symbolResolver);
+                    }
+                })
+        ));
+    }
+
+    public boolean isAttributeComments() {
+        return attributeComments;
+    }
+
+    /**
+     * Whether to run CommentsInserter, which will put the comments that were found in the source code into the comment
+     * and javadoc fields of the nodes it thinks they refer to.
+     */
+    public ParserConfiguration setAttributeComments(boolean attributeComments) {
+        this.attributeComments = attributeComments;
+        return this;
+    }
+
+    public boolean isDoNotAssignCommentsPrecedingEmptyLines() {
+        return doNotAssignCommentsPrecedingEmptyLines;
+    }
+
+    public ParserConfiguration setDoNotAssignCommentsPrecedingEmptyLines(boolean doNotAssignCommentsPrecedingEmptyLines) {
+        this.doNotAssignCommentsPrecedingEmptyLines = doNotAssignCommentsPrecedingEmptyLines;
+        return this;
+    }
+
+    public boolean isDoNotConsiderAnnotationsAsNodeStartForCodeAttribution() {
+        return doNotConsiderAnnotationsAsNodeStartForCodeAttribution;
+    }
+
+    public ParserConfiguration setDoNotConsiderAnnotationsAsNodeStartForCodeAttribution(boolean doNotConsiderAnnotationsAsNodeStartForCodeAttribution) {
+        this.doNotConsiderAnnotationsAsNodeStartForCodeAttribution = doNotConsiderAnnotationsAsNodeStartForCodeAttribution;
+        return this;
+    }
+
+    public ParserConfiguration setStoreTokens(boolean storeTokens) {
+        this.storeTokens = storeTokens;
+        if (!storeTokens) {
+            setAttributeComments(false);
+        }
+        return this;
+    }
+
+    public boolean isStoreTokens() {
+        return storeTokens;
+    }
+
+    public int getTabSize() {
+        return tabSize;
+    }
+
+    /**
+     * When a TAB character is encountered during parsing, the column position will be increased by this value.
+     * By default it is 1.
+     */
+    public ParserConfiguration setTabSize(int tabSize) {
+        this.tabSize = tabSize;
+        return this;
+    }
+
+    /**
+     * @deprecated use getLanguageLevel
+     */
+    @Deprecated
+    public Optional<Validator> getValidator() {
+        throw new IllegalStateException("method is deprecated");
+    }
+
+    /**
+     * @deprecated use setLanguageLevel, or getPostProcessors if you use a custom validator.
+     */
+    @Deprecated
+    public ParserConfiguration setValidator(Validator validator) {
+        // This whole method is a backwards compatability hack.
+        if (validator instanceof Java10Validator) {
+            setLanguageLevel(JAVA_10);
+        } else if (validator instanceof Java9Validator) {
+            setLanguageLevel(JAVA_9);
+        } else if (validator instanceof Java8Validator) {
+            setLanguageLevel(JAVA_8);
+        } else if (validator instanceof Java7Validator) {
+            setLanguageLevel(JAVA_7);
+        } else if (validator instanceof Java6Validator) {
+            setLanguageLevel(JAVA_6);
+        } else if (validator instanceof Java5Validator) {
+            setLanguageLevel(JAVA_5);
+        } else if (validator instanceof Java1_4Validator) {
+            setLanguageLevel(JAVA_1_4);
+        } else if (validator instanceof Java1_3Validator) {
+            setLanguageLevel(JAVA_1_3);
+        } else if (validator instanceof Java1_2Validator) {
+            setLanguageLevel(JAVA_1_2);
+        } else if (validator instanceof Java1_1Validator) {
+            setLanguageLevel(JAVA_1_1);
+        } else if (validator instanceof Java1_0Validator) {
+            setLanguageLevel(JAVA_1_0);
+        } else if (validator instanceof NoProblemsValidator) {
+            setLanguageLevel(RAW);
+        }
+        return this;
+    }
+
+    /**
+     * Disabled by default.
+     * When this is enabled, LexicalPreservingPrinter.print can be used to reproduce
+     * the original formatting of the file.
+     */
+    public ParserConfiguration setLexicalPreservationEnabled(boolean lexicalPreservationEnabled) {
+        this.lexicalPreservationEnabled = lexicalPreservationEnabled;
+        return this;
+    }
+
+    public boolean isLexicalPreservationEnabled() {
+        return lexicalPreservationEnabled;
+    }
+
+    /**
+     * Retrieve the SymbolResolver to be used while parsing, if any.
+     */
+    public Optional<SymbolResolver> getSymbolResolver() {
+        return Optional.ofNullable(symbolResolver);
+    }
+
+    /**
+     * Set the SymbolResolver to be injected while parsing.
+     */
+    public ParserConfiguration setSymbolResolver(SymbolResolver symbolResolver) {
+        this.symbolResolver = symbolResolver;
+        return this;
+    }
+
+    public List<ParseResult.PostProcessor> getPostProcessors() {
+        return postProcessors;
+    }
+
+    public ParserConfiguration setLanguageLevel(LanguageLevel languageLevel) {
+        this.languageLevel = assertNotNull(languageLevel);
+        return this;
+    }
+
+    public LanguageLevel getLanguageLevel() {
+        return languageLevel;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/Position.java b/javaparser-core/src/main/java/com/github/javaparser/Position.java
new file mode 100644
index 0000000..78e95d8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/Position.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Node;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * A position in a source file. Lines and columns start counting at 1.
+ */
+public class Position implements Comparable<Position> {
+    public final int line;
+    public final int column;
+
+    /**
+     * The first position in the file
+     */
+    public static final Position HOME = new Position(1, 1);
+
+    public Position(int line, int column) {
+        if (line < Node.ABSOLUTE_END_LINE) {
+            throw new IllegalArgumentException("Can't position at line " + line);
+        }
+        if (column < -1) {
+            throw new IllegalArgumentException("Can't position at column " + column);
+        }
+        this.line = line;
+        this.column = column;
+    }
+
+    /**
+     * Convenient factory method.
+     */
+    public static Position pos(int line, int column) {
+        return new Position(line, column);
+    }
+
+    public Position withColumn(int column) {
+        return new Position(this.line, column);
+    }
+
+    public Position withLine(int line) {
+        return new Position(line, this.column);
+    }
+
+    /**
+     * Check if the position is usable. Does not know what it is pointing at, so it can't check if the position is after
+     * the end of the source.
+     */
+    public boolean valid() {
+        return line > 0 && column > 0;
+    }
+
+    public boolean invalid() {
+        return !valid();
+    }
+
+    public Position orIfInvalid(Position anotherPosition) {
+        assertNotNull(anotherPosition);
+        if (valid() || anotherPosition.invalid()) {
+            return this;
+        }
+        return anotherPosition;
+    }
+
+    public boolean isAfter(Position position) {
+        assertNotNull(position);
+        if (position.line == Node.ABSOLUTE_BEGIN_LINE) return true;
+        if (line > position.line) {
+            return true;
+        } else if (line == position.line) {
+            return column > position.column;
+        }
+        return false;
+
+    }
+
+    public boolean isBefore(Position position) {
+        assertNotNull(position);
+        if (position.line == Node.ABSOLUTE_END_LINE) return true;
+        if (line < position.line) {
+            return true;
+        } else if (line == position.line) {
+            return column < position.column;
+        }
+        return false;
+    }
+
+    @Override
+    public int compareTo(Position o) {
+        assertNotNull(o);
+        if (isBefore(o)) {
+            return -1;
+        }
+        if (isAfter(o)) {
+            return 1;
+        }
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Position position = (Position) o;
+
+        return line == position.line && column == position.column;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * line + column;
+    }
+
+    @Override
+    public String toString() {
+        return "(line " + line + ",col " + column + ")";
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/Problem.java b/javaparser-core/src/main/java/com/github/javaparser/Problem.java
new file mode 100644
index 0000000..2fc0532
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/Problem.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import java.util.Comparator;
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * A problem that was encountered during parsing.
+ */
+public class Problem {
+    private final String message;
+    private final TokenRange location;
+    private final Throwable cause;
+
+    public Problem(String message, TokenRange location, Throwable cause) {
+        assertNotNull(message);
+
+        this.message = message;
+        this.location = location;
+        this.cause = cause;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder str = new StringBuilder(getVerboseMessage());
+        if (cause != null) {
+            str.append(EOL).append("Problem stacktrace : ").append(EOL);
+            for (int i = 0; i < cause.getStackTrace().length; i++) {
+                StackTraceElement ste = cause.getStackTrace()[i];
+                str.append("  ").append(ste.toString());
+                if (i + 1 != cause.getStackTrace().length)
+                    str.append(EOL);
+            }
+        }
+        return str.toString();
+    }
+
+    /**
+     * @return the message that was passed into the constructor.
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * @return the message plus location information.
+     */
+    public String getVerboseMessage() {
+        return getLocation().map(l -> l.getBegin().getRange().map(r -> r.begin.toString()).orElse("(line ?,col ?)") + " " + message).orElse(message);
+    }
+
+    /**
+     * @return the location that was passed into the constructor.
+     */
+    public Optional<TokenRange> getLocation() {
+        return Optional.ofNullable(location);
+    }
+
+    /**
+     * @deprecated use getLocation()
+     */
+    @Deprecated
+    public Optional<TokenRange> getRange() {
+        return getLocation();
+    }
+
+    /**
+     * @return the cause that was passed into the constructor.
+     */
+    public Optional<Throwable> getCause() {
+        return Optional.ofNullable(cause);
+    }
+
+    /**
+     * Sorts problems on position.
+     */
+    public static Comparator<Problem> PROBLEM_BY_BEGIN_POSITION = (a, b) -> {
+        final Optional<Position> aBegin= a.getLocation().flatMap(l -> l.getBegin().getRange().map(r -> r.begin));
+        final Optional<Position> bBegin = b.getLocation().flatMap(l -> l.getBegin().getRange().map(r -> r.begin));
+
+        if (aBegin.isPresent() && bBegin.isPresent()) {
+            return aBegin.get().compareTo(bBegin.get());
+        }
+        if (a.getLocation().isPresent() || b.getLocation().isPresent()) {
+            if (a.getLocation().isPresent()) {
+                return 1;
+            }
+            return -1;
+        }
+        return 0;
+    };
+
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/Providers.java b/javaparser-core/src/main/java/com/github/javaparser/Providers.java
new file mode 100644
index 0000000..f4b3df9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/Providers.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Factory for providers of source code for JavaParser. Providers that have no parameter for encoding but need it will
+ * use UTF-8.
+ */
+public final class Providers {
+    public static final Charset UTF8 = Charset.forName("utf-8");
+
+    private Providers() {
+    }
+
+    public static Provider provider(Reader reader) {
+        return new StreamProvider(assertNotNull(reader));
+    }
+
+    public static Provider provider(InputStream input, Charset encoding) {
+        assertNotNull(input);
+        assertNotNull(encoding);
+        try {
+            return new StreamProvider(input, encoding.name());
+        } catch (IOException e) {
+            // The only one that is thrown is UnsupportedCharacterEncodingException,
+            // and that's a fundamental problem, so runtime exception.
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static Provider provider(InputStream input) {
+        return provider(input, UTF8);
+    }
+
+    public static Provider provider(File file, Charset encoding) throws FileNotFoundException {
+        return provider(new FileInputStream(assertNotNull(file)), assertNotNull(encoding));
+    }
+
+    public static Provider provider(File file) throws FileNotFoundException {
+        return provider(assertNotNull(file), UTF8);
+    }
+
+    public static Provider provider(Path path, Charset encoding) throws IOException {
+        return provider(Files.newInputStream(assertNotNull(path)), assertNotNull(encoding));
+    }
+
+    public static Provider provider(Path path) throws IOException {
+        return provider(assertNotNull(path), UTF8);
+    }
+
+    public static Provider provider(String source) {
+        return new StringProvider(assertNotNull(source));
+    }
+
+
+    /**
+     * Provide a Provider from the resource found in class loader with the provided encoding.<br/> As resource is
+     * accessed through a class loader, a leading "/" is not allowed in pathToResource
+     */
+    public static Provider resourceProvider(ClassLoader classLoader, String pathToResource, Charset encoding) throws IOException {
+        InputStream resourceAsStream = classLoader.getResourceAsStream(pathToResource);
+        if (resourceAsStream == null) {
+            throw new IOException("Cannot find " + pathToResource);
+        }
+        return provider(resourceAsStream, encoding);
+    }
+
+    /**
+     * Provide a Provider from the resource found in the current class loader with the provided encoding.<br/> As
+     * resource is accessed through a class loader, a leading "/" is not allowed in pathToResource
+     */
+    public static Provider resourceProvider(String pathToResource, Charset encoding) throws IOException {
+        ClassLoader classLoader = Provider.class.getClassLoader();
+        return resourceProvider(classLoader, pathToResource, encoding);
+    }
+
+    /**
+     * Provide a Provider from the resource found in the current class loader with UTF-8 encoding.<br/> As resource is
+     * accessed through a class loader, a leading "/" is not allowed in pathToResource
+     */
+    public static Provider resourceProvider(String pathToResource) throws IOException {
+        return resourceProvider(pathToResource, UTF8);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/Range.java b/javaparser-core/src/main/java/com/github/javaparser/Range.java
new file mode 100644
index 0000000..dc5b329
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/Range.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import static com.github.javaparser.Position.pos;
+
+/**
+ * A range of characters in a source file, from "begin" to "end", including the characters at "begin" and "end".
+ */
+public class Range {
+    public final Position begin;
+    public final Position end;
+
+    public Range(Position begin, Position end) {
+        if (begin == null) {
+            throw new IllegalArgumentException("begin can't be null");
+        }
+        if (end == null) {
+            throw new IllegalArgumentException("end can't be null");
+        }
+        this.begin = begin;
+        this.end = end;
+    }
+
+    public static Range range(Position begin, Position end) {
+        return new Range(begin, end);
+    }
+
+    public static Range range(int beginLine, int beginColumn, int endLine, int endColumn) {
+        return new Range(pos(beginLine, beginColumn), pos(endLine, endColumn));
+    }
+
+    public Range withBeginColumn(int column) {
+        return range(begin.withColumn(column), end);
+    }
+
+    public Range withBeginLine(int line) {
+        return range(begin.withLine(line), end);
+    }
+
+    public Range withEndColumn(int column) {
+        return range(begin, end.withColumn(column));
+    }
+
+    public Range withEndLine(int line) {
+        return range(begin, end.withLine(line));
+    }
+
+    public Range withBegin(Position begin) {
+        return range(begin, this.end);
+    }
+
+    public Range withEnd(Position end) {
+        return range(this.begin, end);
+    }
+
+    /**
+     * As strictlyContains, but two exactly matching ranges are also considered contained one in each other.
+     */
+    public boolean contains(Range other) {
+        return (begin.isBefore(other.begin) || begin.equals(other.begin)) &&
+                (end.isAfter(other.end) || end.equals(other.end));
+    }
+
+    /**
+     * Do this strictly contains other? It means that this has to be larger than other and it has to start as other
+     * or before and end as other or after.
+     */
+    public boolean strictlyContains(Range other) {
+        return begin.isBefore(other.begin) && end.isAfter(other.end);
+    }
+
+    public boolean isBefore(Position position) {
+        return end.isBefore(position);
+    }
+
+    public boolean isAfter(Position position) {
+        return begin.isAfter(position);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Range range = (Range) o;
+
+        return begin.equals(range.begin) && end.equals(range.end);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * begin.hashCode() + end.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return begin + "-" + end;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/TokenRange.java b/javaparser-core/src/main/java/com/github/javaparser/TokenRange.java
new file mode 100644
index 0000000..c0cb038
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/TokenRange.java
@@ -0,0 +1,82 @@
+package com.github.javaparser;
+
+import java.util.Iterator;
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * The range of tokens covered by this node.
+ */
+public class TokenRange implements Iterable<JavaToken> {
+    public static final TokenRange INVALID = new TokenRange(JavaToken.INVALID, JavaToken.INVALID);
+
+    private final JavaToken begin;
+    private final JavaToken end;
+
+    public TokenRange(JavaToken begin, JavaToken end) {
+        this.begin = assertNotNull(begin);
+        this.end = assertNotNull(end);
+    }
+
+    public JavaToken getBegin() {
+        return begin;
+    }
+
+    public JavaToken getEnd() {
+        return end;
+    }
+
+    public Optional<Range> toRange() {
+        if (begin.getRange().isPresent() && end.getRange().isPresent()) {
+            return Optional.of(new Range(begin.getRange().get().begin, end.getRange().get().end));
+        }
+        return Optional.empty();
+    }
+
+    public TokenRange withBegin(JavaToken begin) {
+        return new TokenRange(assertNotNull(begin), end);
+    }
+
+    public TokenRange withEnd(JavaToken end) {
+        return new TokenRange(begin, assertNotNull(end));
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder();
+        for(JavaToken t: this) {
+            result.append(t.getText());
+        }
+        return result.toString();
+    }
+
+    @Override
+    public Iterator<JavaToken> iterator() {
+        return new Iterator<JavaToken>() {
+            private boolean hasNext = true;
+            private JavaToken current = begin;
+
+            @Override
+            public boolean hasNext() {
+                return hasNext;
+            }
+
+            @Override
+            public JavaToken next() {
+                JavaToken retval = current;
+                if(current == null){
+                    throw new IllegalStateException("Attempting to move past end of range.");
+                }
+                if (current == end) {
+                    hasNext = false;
+                }
+                current = current.getNextToken().orElse(null);
+                if(current == null && hasNext){
+                    throw new IllegalStateException("End token is not linked to begin token.");
+                }
+                return retval;
+            }
+        };
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java b/javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java
new file mode 100644
index 0000000..8b90aa7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java
@@ -0,0 +1,239 @@
+package com.github.javaparser;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.*;
+import static com.github.javaparser.utils.Utils.EOL;
+
+/**
+ * Complements GeneratedJavaParserConstants
+ */
+public class TokenTypes {
+    public static boolean isWhitespace(int kind) {
+        return getCategory(kind).isWhitespace();
+    }
+
+    /**
+     * @deprecated use isEndOfLineToken
+     */
+    @Deprecated
+    public static boolean isEndOfLineCharacter(int kind) {
+        return isEndOfLineToken(kind);
+    }
+
+    public static boolean isEndOfLineToken(int kind) {
+        return getCategory(kind).isEndOfLine();
+    }
+
+    public static boolean isWhitespaceOrComment(int kind) {
+        return getCategory(kind).isWhitespaceOrComment();
+    }
+
+    public static boolean isSpaceOrTab(int kind) {
+        return getCategory(kind).isWhitespaceButNotEndOfLine();
+    }
+
+    public static boolean isComment(int kind) {
+        return getCategory(kind).isComment();
+    }
+
+    /**
+     * @deprecated use eolTokenKind
+     */
+    @Deprecated
+    public static int eolToken() {
+        return eolTokenKind();
+    }
+
+    /**
+     * @return the kind of EOL token to use on the platform you're running on.
+     */
+    public static int eolTokenKind() {
+        if (EOL.equals("\n")) {
+            return UNIX_EOL;
+        }
+        if (EOL.equals("\r\n")) {
+            return WINDOWS_EOL;
+        }
+        if (EOL.equals("\r")) {
+            return OLD_MAC_EOL;
+        }
+        throw new AssertionError("Unknown EOL character sequence");
+    }
+
+    /**
+     * @return the token kind for a single space.
+     */
+    public static int spaceTokenKind() {
+        return SPACE;
+    }
+
+    /**
+     * @deprecated use spaceTokenKind
+     */
+    @Deprecated
+    public static int spaceToken() {
+        return spaceTokenKind();
+    }
+
+    /**
+     * Category of a token, a little more detailed than
+     * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.5">The JLS</a>.
+     */
+    public static JavaToken.Category getCategory(int kind) {
+        switch (kind) {
+            case WINDOWS_EOL:
+            case UNIX_EOL:
+            case OLD_MAC_EOL:
+                return JavaToken.Category.EOL;
+            case EOF:
+            case SPACE:
+            case CTRL_Z:
+                return JavaToken.Category.WHITESPACE_NO_EOL;
+            case SINGLE_LINE_COMMENT:
+            case JAVADOC_COMMENT:
+            case MULTI_LINE_COMMENT:
+                return JavaToken.Category.COMMENT;
+            case ABSTRACT:
+            case ASSERT:
+            case BOOLEAN:
+            case BREAK:
+            case BYTE:
+            case CASE:
+            case CATCH:
+            case CHAR:
+            case CLASS:
+            case CONST:
+            case CONTINUE:
+            case _DEFAULT:
+            case DO:
+            case DOUBLE:
+            case ELSE:
+            case ENUM:
+            case EXTENDS:
+            case FALSE:
+            case FINAL:
+            case FINALLY:
+            case FLOAT:
+            case FOR:
+            case GOTO:
+            case IF:
+            case IMPLEMENTS:
+            case IMPORT:
+            case INSTANCEOF:
+            case INT:
+            case INTERFACE:
+            case LONG:
+            case NATIVE:
+            case NEW:
+            case NULL:
+            case PACKAGE:
+            case PRIVATE:
+            case PROTECTED:
+            case PUBLIC:
+            case RETURN:
+            case SHORT:
+            case STATIC:
+            case STRICTFP:
+            case SUPER:
+            case SWITCH:
+            case SYNCHRONIZED:
+            case THIS:
+            case THROW:
+            case THROWS:
+            case TRANSIENT:
+            case TRUE:
+            case TRY:
+            case VOID:
+            case VOLATILE:
+            case WHILE:
+            case REQUIRES:
+            case TO:
+            case WITH:
+            case OPEN:
+            case OPENS:
+            case USES:
+            case MODULE:
+            case EXPORTS:
+            case PROVIDES:
+            case TRANSITIVE:
+                return JavaToken.Category.KEYWORD;
+            case LONG_LITERAL:
+            case INTEGER_LITERAL:
+            case DECIMAL_LITERAL:
+            case HEX_LITERAL:
+            case OCTAL_LITERAL:
+            case BINARY_LITERAL:
+            case FLOATING_POINT_LITERAL:
+            case DECIMAL_FLOATING_POINT_LITERAL:
+            case DECIMAL_EXPONENT:
+            case HEXADECIMAL_FLOATING_POINT_LITERAL:
+            case HEXADECIMAL_EXPONENT:
+            case CHARACTER_LITERAL:
+            case STRING_LITERAL:
+                return JavaToken.Category.LITERAL;
+            case IDENTIFIER:
+                return JavaToken.Category.IDENTIFIER;
+            case LPAREN:
+            case RPAREN:
+            case LBRACE:
+            case RBRACE:
+            case LBRACKET:
+            case RBRACKET:
+            case SEMICOLON:
+            case COMMA:
+            case DOT:
+            case AT:
+                return JavaToken.Category.SEPARATOR;
+            case ASSIGN:
+            case LT:
+            case BANG:
+            case TILDE:
+            case HOOK:
+            case COLON:
+            case EQ:
+            case LE:
+            case GE:
+            case NE:
+            case SC_OR:
+            case SC_AND:
+            case INCR:
+            case DECR:
+            case PLUS:
+            case MINUS:
+            case STAR:
+            case SLASH:
+            case BIT_AND:
+            case BIT_OR:
+            case XOR:
+            case REM:
+            case LSHIFT:
+            case PLUSASSIGN:
+            case MINUSASSIGN:
+            case STARASSIGN:
+            case SLASHASSIGN:
+            case ANDASSIGN:
+            case ORASSIGN:
+            case XORASSIGN:
+            case REMASSIGN:
+            case LSHIFTASSIGN:
+            case RSIGNEDSHIFTASSIGN:
+            case RUNSIGNEDSHIFTASSIGN:
+            case ELLIPSIS:
+            case ARROW:
+            case DOUBLECOLON:
+            case RUNSIGNEDSHIFT:
+            case RSIGNEDSHIFT:
+            case GT:
+                return JavaToken.Category.OPERATOR;
+            // The following are tokens that are only used internally by the lexer
+            case ENTER_JAVADOC_COMMENT:
+            case ENTER_MULTILINE_COMMENT:
+            case COMMENT_CONTENT:
+            case HEX_DIGITS:
+            case LETTER:
+            case UNICODE_ESCAPE:
+            case PART_LETTER:
+            default:
+                throw new AssertionError("Invalid token kind " + kind);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/AccessSpecifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/AccessSpecifier.java
new file mode 100644
index 0000000..63e96b8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/AccessSpecifier.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+/**
+ * Access specifier. Represents one of the possible levels of
+ * access permitted by the language.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public enum AccessSpecifier {
+
+    PUBLIC("public"),
+    PRIVATE("private"),
+    PROTECTED("protected"),
+    DEFAULT("");
+
+    private String codeRepresenation;
+
+    AccessSpecifier(String codeRepresentation) {
+        this.codeRepresenation = codeRepresentation;
+    }
+
+    public String asString() {
+        return this.codeRepresenation;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/AllFieldsConstructor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/AllFieldsConstructor.java
new file mode 100644
index 0000000..33d58e4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/AllFieldsConstructor.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.ast;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Tells tools that this is the constructor which directly initializes all fields (except "range" and "comment")
+ */
+@Target(ElementType.CONSTRUCTOR)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AllFieldsConstructor {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/ArrayCreationLevel.java b/javaparser-core/src/main/java/com/github/javaparser/ast/ArrayCreationLevel.java
new file mode 100644
index 0000000..09148fe
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/ArrayCreationLevel.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ArrayCreationLevelMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+
+/**
+ * In <code>new int[1][2];</code> there are two ArrayCreationLevel objects,
+ * the first one contains the expression "1",
+ * the second the expression "2".
+ */
+public final class ArrayCreationLevel extends Node implements NodeWithAnnotations<ArrayCreationLevel> {
+
+    @OptionalProperty
+    private Expression dimension;
+
+    private NodeList<AnnotationExpr> annotations = new NodeList<>();
+
+    public ArrayCreationLevel() {
+        this(null, null, new NodeList<>());
+    }
+
+    public ArrayCreationLevel(int dimension) {
+        this(null, new IntegerLiteralExpr("" + dimension), new NodeList<>());
+    }
+
+    public ArrayCreationLevel(Expression dimension) {
+        this(null, dimension, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ArrayCreationLevel(Expression dimension, NodeList<AnnotationExpr> annotations) {
+        this(null, dimension, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ArrayCreationLevel(TokenRange tokenRange, Expression dimension, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange);
+        setDimension(dimension);
+        setAnnotations(annotations);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Sets the dimension
+     *
+     * @param dimension the dimension, can be null
+     * @return this, the ArrayCreationLevel
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayCreationLevel setDimension(final Expression dimension) {
+        if (dimension == this.dimension) {
+            return (ArrayCreationLevel) this;
+        }
+        notifyPropertyChange(ObservableProperty.DIMENSION, this.dimension, dimension);
+        if (this.dimension != null)
+            this.dimension.setParentNode(null);
+        this.dimension = dimension;
+        setAsParentNodeOf(dimension);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getDimension() {
+        return Optional.ofNullable(dimension);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayCreationLevel setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (ArrayCreationLevel) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ArrayCreationLevel removeDimension() {
+        return setDimension((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        if (dimension != null) {
+            if (node == dimension) {
+                removeDimension();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ArrayCreationLevel clone() {
+        return (ArrayCreationLevel) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ArrayCreationLevelMetaModel getMetaModel() {
+        return JavaParserMetaModel.arrayCreationLevelMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        if (dimension != null) {
+            if (node == dimension) {
+                setDimension((Expression) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/CompilationUnit.java b/javaparser-core/src/main/java/com/github/javaparser/ast/CompilationUnit.java
new file mode 100644
index 0000000..fd8bb20
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/CompilationUnit.java
@@ -0,0 +1,694 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParseStart;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.modules.ModuleDeclaration;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.CompilationUnitMetaModel;
+import com.github.javaparser.metamodel.InternalProperty;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.printer.PrettyPrinter;
+import com.github.javaparser.utils.ClassUtils;
+import com.github.javaparser.utils.CodeGenerationUtils;
+import com.github.javaparser.utils.Utils;
+import javax.annotation.Generated;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import static com.github.javaparser.JavaParser.parseName;
+import static com.github.javaparser.Providers.UTF8;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.CodeGenerationUtils.subtractPaths;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+
+/**
+ * <p>
+ * This class represents the entire compilation unit. Each java file denotes a
+ * compilation unit.
+ * </p>
+ * A compilation unit start with an optional package declaration,
+ * followed by zero or more import declarations,
+ * followed by zero or more type declarations.
+ *
+ * @author Julio Vilmar Gesser
+ * @see PackageDeclaration
+ * @see ImportDeclaration
+ * @see TypeDeclaration
+ * @see Storage
+ */
+public final class CompilationUnit extends Node {
+
+    @OptionalProperty
+    private PackageDeclaration packageDeclaration;
+
+    private NodeList<ImportDeclaration> imports;
+
+    private NodeList<TypeDeclaration<?>> types;
+
+    @OptionalProperty
+    private ModuleDeclaration module;
+
+    @InternalProperty
+    private Storage storage;
+
+    public CompilationUnit() {
+        this(null, null, new NodeList<>(), new NodeList<>(), null);
+    }
+
+    public CompilationUnit(String packageDeclaration) {
+        this(null, new PackageDeclaration(new Name(packageDeclaration)), new NodeList<>(), new NodeList<>(), null);
+    }
+
+    @AllFieldsConstructor
+    public CompilationUnit(PackageDeclaration packageDeclaration, NodeList<ImportDeclaration> imports, NodeList<TypeDeclaration<?>> types, ModuleDeclaration module) {
+        this(null, packageDeclaration, imports, types, module);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public CompilationUnit(TokenRange tokenRange, PackageDeclaration packageDeclaration, NodeList<ImportDeclaration> imports, NodeList<TypeDeclaration<?>> types, ModuleDeclaration module) {
+        super(tokenRange);
+        setPackageDeclaration(packageDeclaration);
+        setImports(imports);
+        setTypes(types);
+        setModule(module);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return a list containing all comments declared in this compilation unit.
+     * Including javadocs, line comments and block comments of all types,
+     * inner-classes and other members.<br>
+     * If there is no comment, an empty list is returned.
+     *
+     * @return list with all comments of this compilation unit.
+     * @see JavadocComment
+     * @see com.github.javaparser.ast.comments.LineComment
+     * @see com.github.javaparser.ast.comments.BlockComment
+     */
+    public List<Comment> getComments() {
+        return this.getAllContainedComments();
+    }
+
+    /**
+     * Retrieves the list of imports declared in this compilation unit or
+     * <code>null</code> if there is no import.
+     *
+     * @return the list of imports or <code>none</code> if there is no import
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ImportDeclaration> getImports() {
+        return imports;
+    }
+
+    public ImportDeclaration getImport(int i) {
+        return getImports().get(i);
+    }
+
+    /**
+     * Retrieves the package declaration of this compilation unit.<br>
+     * If this compilation unit has no package declaration (default package),
+     * <code>Optional.none()</code> is returned.
+     *
+     * @return the package declaration or <code>none</code>
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<PackageDeclaration> getPackageDeclaration() {
+        return Optional.ofNullable(packageDeclaration);
+    }
+
+    /**
+     * Return the list of top level types declared in this compilation unit.<br>
+     * If there are no types declared, <code>none</code> is returned.
+     *
+     * @return the list of types or <code>none</code> null if there is no type
+     * @see AnnotationDeclaration
+     * @see ClassOrInterfaceDeclaration
+     * @see EnumDeclaration
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<TypeDeclaration<?>> getTypes() {
+        return types;
+    }
+
+    /**
+     * Convenience method that wraps <code>getTypes()</code>.<br>
+     * If <code>i</code> is out of bounds, throws <code>IndexOutOfBoundsException.</code>
+     *
+     * @param i the index of the type declaration to retrieve
+     */
+    public TypeDeclaration<?> getType(int i) {
+        return getTypes().get(i);
+    }
+
+    /**
+     * Sets the list of imports of this compilation unit. The list is initially
+     * <code>null</code>.
+     *
+     * @param imports the list of imports
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CompilationUnit setImports(final NodeList<ImportDeclaration> imports) {
+        assertNotNull(imports);
+        if (imports == this.imports) {
+            return (CompilationUnit) this;
+        }
+        notifyPropertyChange(ObservableProperty.IMPORTS, this.imports, imports);
+        if (this.imports != null)
+            this.imports.setParentNode(null);
+        this.imports = imports;
+        setAsParentNodeOf(imports);
+        return this;
+    }
+
+    public CompilationUnit setImport(int i, ImportDeclaration imports) {
+        getImports().set(i, imports);
+        return this;
+    }
+
+    public CompilationUnit addImport(ImportDeclaration imports) {
+        getImports().add(imports);
+        return this;
+    }
+
+    /**
+     * Sets or clear the package declarations of this compilation unit.
+     *
+     * @param packageDeclaration the packageDeclaration declaration to set or <code>null</code> to default package
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CompilationUnit setPackageDeclaration(final PackageDeclaration packageDeclaration) {
+        if (packageDeclaration == this.packageDeclaration) {
+            return (CompilationUnit) this;
+        }
+        notifyPropertyChange(ObservableProperty.PACKAGE_DECLARATION, this.packageDeclaration, packageDeclaration);
+        if (this.packageDeclaration != null)
+            this.packageDeclaration.setParentNode(null);
+        this.packageDeclaration = packageDeclaration;
+        setAsParentNodeOf(packageDeclaration);
+        return this;
+    }
+
+    /**
+     * Sets the list of types declared in this compilation unit.
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CompilationUnit setTypes(final NodeList<TypeDeclaration<?>> types) {
+        assertNotNull(types);
+        if (types == this.types) {
+            return (CompilationUnit) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPES, this.types, types);
+        if (this.types != null)
+            this.types.setParentNode(null);
+        this.types = types;
+        setAsParentNodeOf(types);
+        return this;
+    }
+
+    public CompilationUnit setType(int i, TypeDeclaration<?> type) {
+        NodeList<TypeDeclaration<?>> copy = new NodeList<>();
+        copy.addAll(getTypes());
+        getTypes().set(i, type);
+        notifyPropertyChange(ObservableProperty.TYPES, copy, types);
+        return this;
+    }
+
+    public CompilationUnit addType(TypeDeclaration<?> type) {
+        NodeList<TypeDeclaration<?>> copy = new NodeList<>();
+        copy.addAll(getTypes());
+        getTypes().add(type);
+        notifyPropertyChange(ObservableProperty.TYPES, copy, types);
+        return this;
+    }
+
+    /**
+     * sets the package declaration of this compilation unit
+     *
+     * @param name the name of the package
+     * @return this, the {@link CompilationUnit}
+     */
+    public CompilationUnit setPackageDeclaration(String name) {
+        setPackageDeclaration(new PackageDeclaration(parseName(name)));
+        return this;
+    }
+
+    /**
+     * Add an import to the list of {@link ImportDeclaration} of this compilation unit<br>
+     * shorthand for {@link #addImport(String, boolean, boolean)} with name,false,false
+     *
+     * @param name the import name
+     * @return this, the {@link CompilationUnit}
+     */
+    public CompilationUnit addImport(String name) {
+        return addImport(name, false, false);
+    }
+
+    /**
+     * Add an import to the list of {@link ImportDeclaration} of this compilation unit<br>
+     * shorthand for {@link #addImport(String)} with clazz.getName()
+     *
+     * @param clazz the class to import
+     * @return this, the {@link CompilationUnit}
+     * @throws RuntimeException if clazz is an anonymous or local class
+     */
+    public CompilationUnit addImport(Class<?> clazz) {
+        if (ClassUtils.isPrimitiveOrWrapper(clazz) || clazz.getName().startsWith("java.lang"))
+            return this;
+        else if (clazz.isMemberClass())
+            return addImport(clazz.getName().replace("$", "."));
+        else if (clazz.isArray() && !ClassUtils.isPrimitiveOrWrapper(clazz.getComponentType()) && !clazz.getComponentType().getName().startsWith("java.lang"))
+            return addImport(clazz.getComponentType().getName());
+        else if (clazz.isAnonymousClass() || clazz.isLocalClass())
+            throw new RuntimeException(clazz.getName() + " is an anonymous or local class therefore it can't be added with addImport");
+        return addImport(clazz.getName());
+    }
+
+    /**
+     * Add an import to the list of {@link ImportDeclaration} of this compilation unit<br>
+     * <b>This method check if no import with the same name is already in the list</b>
+     *
+     * @param name the import name
+     * @param isStatic is it an "import static"
+     * @param isAsterisk does the import end with ".*"
+     * @return this, the {@link CompilationUnit}
+     */
+    public CompilationUnit addImport(String name, boolean isStatic, boolean isAsterisk) {
+        final StringBuilder i = new StringBuilder("import ");
+        if (isStatic) {
+            i.append("static ");
+        }
+        i.append(name);
+        if (isAsterisk) {
+            i.append(".*");
+        }
+        i.append(";");
+        ImportDeclaration importDeclaration = JavaParser.parseImport(i.toString());
+        if (getImports().stream().anyMatch(im -> im.toString().equals(importDeclaration.toString())))
+            return this;
+        else {
+            getImports().add(importDeclaration);
+            return this;
+        }
+    }
+
+    /**
+     * Add a public class to the types of this compilation unit
+     *
+     * @param name the class name
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addClass(String name) {
+        return addClass(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add a class to the types of this compilation unit
+     *
+     * @param name the class name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addClass(String name, Modifier... modifiers) {
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = new ClassOrInterfaceDeclaration(Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), false, name);
+        getTypes().add(classOrInterfaceDeclaration);
+        return classOrInterfaceDeclaration;
+    }
+
+    /**
+     * Add a public interface class to the types of this compilation unit
+     *
+     * @param name the interface name
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addInterface(String name) {
+        return addInterface(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add an interface to the types of this compilation unit
+     *
+     * @param name the interface name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addInterface(String name, Modifier... modifiers) {
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = new ClassOrInterfaceDeclaration(Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), true, name);
+        getTypes().add(classOrInterfaceDeclaration);
+        return classOrInterfaceDeclaration;
+    }
+
+    /**
+     * Add a public enum to the types of this compilation unit
+     *
+     * @param name the enum name
+     * @return the newly created class
+     */
+    public EnumDeclaration addEnum(String name) {
+        return addEnum(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add an enum to the types of this compilation unit
+     *
+     * @param name the enum name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public EnumDeclaration addEnum(String name, Modifier... modifiers) {
+        EnumDeclaration enumDeclaration = new EnumDeclaration(Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), name);
+        getTypes().add(enumDeclaration);
+        return enumDeclaration;
+    }
+
+    /**
+     * Add a public annotation declaration to the types of this compilation unit
+     *
+     * @param name the annotation name
+     * @return the newly created class
+     */
+    public AnnotationDeclaration addAnnotationDeclaration(String name) {
+        return addAnnotationDeclaration(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add an annotation declaration to the types of this compilation unit
+     *
+     * @param name the annotation name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public AnnotationDeclaration addAnnotationDeclaration(String name, Modifier... modifiers) {
+        AnnotationDeclaration annotationDeclaration = new AnnotationDeclaration(Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), name);
+        getTypes().add(annotationDeclaration);
+        return annotationDeclaration;
+    }
+
+    /**
+     * Try to get a top level class declaration by its name
+     *
+     * @param className the class name (case-sensitive)
+     */
+    public Optional<ClassOrInterfaceDeclaration> getClassByName(String className) {
+        return getTypes().stream().filter(type -> type.getNameAsString().equals(className) && type instanceof ClassOrInterfaceDeclaration && !((ClassOrInterfaceDeclaration) type).isInterface()).findFirst().map(t -> (ClassOrInterfaceDeclaration) t);
+    }
+
+    /**
+     * Try to get a top level interface declaration by its name
+     *
+     * @param interfaceName the interface name (case-sensitive)
+     */
+    public Optional<ClassOrInterfaceDeclaration> getInterfaceByName(String interfaceName) {
+        return getTypes().stream().filter(type -> type.getNameAsString().equals(interfaceName) && type instanceof ClassOrInterfaceDeclaration && ((ClassOrInterfaceDeclaration) type).isInterface()).findFirst().map(t -> (ClassOrInterfaceDeclaration) t);
+    }
+
+    /**
+     * Try to get a top level enum declaration by its name
+     *
+     * @param enumName the enum name (case-sensitive)
+     */
+    public Optional<EnumDeclaration> getEnumByName(String enumName) {
+        return getTypes().stream().filter(type -> type.getNameAsString().equals(enumName) && type instanceof EnumDeclaration).findFirst().map(t -> (EnumDeclaration) t);
+    }
+
+    /**
+     * @return the name that the primary type in this file should have, according to the filename in {@link Storage#getFileName()}.
+     * Empty if no file information is present (when this compilation unit wasn't parsed from a file.)
+     */
+    public Optional<String> getPrimaryTypeName() {
+        return getStorage().map(Storage::getFileName).map(Utils::removeFileExtension);
+    }
+
+    /**
+     * @return the type whose name corresponds to the file name.
+     * Empty if no file information is present (when this compilation unit wasn't parsed from a file.)
+     * If for some strange reason there are multiple types of this name, the first one is returned.
+     */
+    public Optional<TypeDeclaration<?>> getPrimaryType() {
+        return getPrimaryTypeName().flatMap(name -> getTypes().stream().filter(t -> t.getNameAsString().equals(name)).findFirst());
+    }
+
+    /**
+     * Try to get a top level annotation type declaration by its name
+     *
+     * @param annotationName the annotation name (case-sensitive)
+     */
+    public Optional<AnnotationDeclaration> getAnnotationDeclarationByName(String annotationName) {
+        return getTypes().stream().filter(type -> type.getNameAsString().equals(annotationName) && type instanceof AnnotationDeclaration).findFirst().map(t -> (AnnotationDeclaration) t);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < imports.size(); i++) {
+            if (imports.get(i) == node) {
+                imports.remove(i);
+                return true;
+            }
+        }
+        if (module != null) {
+            if (node == module) {
+                removeModule();
+                return true;
+            }
+        }
+        if (packageDeclaration != null) {
+            if (node == packageDeclaration) {
+                removePackageDeclaration();
+                return true;
+            }
+        }
+        for (int i = 0; i < types.size(); i++) {
+            if (types.get(i) == node) {
+                types.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public CompilationUnit removePackageDeclaration() {
+        return setPackageDeclaration((PackageDeclaration) null);
+    }
+
+    /**
+     * @return the module declared in this compilation unit.
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<ModuleDeclaration> getModule() {
+        return Optional.ofNullable(module);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CompilationUnit setModule(final ModuleDeclaration module) {
+        if (module == this.module) {
+            return (CompilationUnit) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODULE, this.module, module);
+        if (this.module != null)
+            this.module.setParentNode(null);
+        this.module = module;
+        setAsParentNodeOf(module);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public CompilationUnit removeModule() {
+        return setModule((ModuleDeclaration) null);
+    }
+
+    /**
+     * @return information about where this compilation unit was loaded from, or empty if it wasn't loaded from a file.
+     */
+    public Optional<Storage> getStorage() {
+        return Optional.ofNullable(storage);
+    }
+
+    public CompilationUnit setStorage(Path path) {
+        this.storage = new Storage(this, path);
+        return this;
+    }
+
+    /**
+     * Information about where this compilation unit was loaded from.
+     * This class only stores the absolute location.
+     * For more flexibility use SourceRoot.
+     */
+    public static class Storage {
+
+        private final CompilationUnit compilationUnit;
+
+        private final Path path;
+
+        private Storage(CompilationUnit compilationUnit, Path path) {
+            this.compilationUnit = compilationUnit;
+            this.path = path.toAbsolutePath();
+        }
+
+        /**
+         * @return the path to the source for this CompilationUnit
+         */
+        public Path getPath() {
+            return path;
+        }
+
+        /**
+         * @return the CompilationUnit this Storage is about.
+         */
+        public CompilationUnit getCompilationUnit() {
+            return compilationUnit;
+        }
+
+        /**
+         * @return the source root directory, calculated from the path of this compiation unit, and the package
+         * declaration of this compilation unit. If the package declaration is invalid (when it does not match the end
+         * of the path) a RuntimeException is thrown.
+         */
+        public Path getSourceRoot() {
+            final Optional<String> pkgAsString = compilationUnit.getPackageDeclaration().map(NodeWithName::getNameAsString);
+            return pkgAsString.map(p -> Paths.get(CodeGenerationUtils.packageToPath(p))).map(pkg -> subtractPaths(getDirectory(), pkg)).orElse(getDirectory());
+        }
+
+        public String getFileName() {
+            return path.getFileName().toString();
+        }
+
+        public Path getDirectory() {
+            return path.getParent();
+        }
+
+        /**
+         * Saves the compilation unit to its original location
+         */
+        public void save() {
+            save(cu -> new PrettyPrinter().print(cu));
+        }
+
+        /**
+         * Saves a compilation unit to its original location with formatting according to the function
+         * passed as a parameter.
+         *
+         * @param makeOutput a function that formats the compilation unit
+         */
+        public void save(Function<CompilationUnit, String> makeOutput) {
+            try {
+                Files.createDirectories(path.getParent());
+                final String code = makeOutput.apply(getCompilationUnit());
+                Files.write(path, code.getBytes(UTF8));
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public ParseResult<CompilationUnit> reparse(JavaParser javaParser) {
+            try {
+                return javaParser.parse(ParseStart.COMPILATION_UNIT, provider(getPath()));
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public CompilationUnit clone() {
+        return (CompilationUnit) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public CompilationUnitMetaModel getMetaModel() {
+        return JavaParserMetaModel.compilationUnitMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < imports.size(); i++) {
+            if (imports.get(i) == node) {
+                imports.set(i, (ImportDeclaration) replacementNode);
+                return true;
+            }
+        }
+        if (module != null) {
+            if (node == module) {
+                setModule((ModuleDeclaration) replacementNode);
+                return true;
+            }
+        }
+        if (packageDeclaration != null) {
+            if (node == packageDeclaration) {
+                setPackageDeclaration((PackageDeclaration) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < types.size(); i++) {
+            if (types.get(i) == node) {
+                types.set(i, (TypeDeclaration) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/DataKey.java b/javaparser-core/src/main/java/com/github/javaparser/ast/DataKey.java
new file mode 100644
index 0000000..2f2115d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/DataKey.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+/**
+ * A key to a piece of data associated with a {@link Node} at runtime.
+ * The key contains type information that can be used to check the
+ * type of any user data value for the key when the value is set. DataKey is abstract in order to
+ * force the creation of a subtype. That subtype is used to test for identity when looking for the
+ * user data because actual object identity would suffer from problems under serialization.
+ * So, the correct way to declare a DataKey is like this:
+ * <p>
+ * <pre>
+ * <code>
+ * public static final DataKey&lt;Role&gt; ROLE = new DataKey&lt;Role&gt;() { };
+ * </code>
+ * </pre>
+ * <p>
+ * This code was taken from the <a href="http://wicket.apache.org/">Wicket project</a>.
+ *
+ * @param <T> The type of the object which is stored
+ * @see Node#getData(DataKey)
+ */
+public abstract class DataKey<T> {
+    @Override
+    public int hashCode() {
+        return getClass().hashCode();
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return obj != null && getClass().equals(obj.getClass());
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/ImportDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/ImportDeclaration.java
new file mode 100644
index 0000000..88ab096
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/ImportDeclaration.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ImportDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+
+/**
+ * An import declaration.
+ * <br/><code>import com.github.javaparser.JavaParser;</code>
+ * <br/><code>import com.github.javaparser.*;</code>
+ * <br/><code>import com.github.javaparser.JavaParser.*; </code>
+ * <br/><code>import static com.github.javaparser.JavaParser.*;</code>
+ * <br/><code>import static com.github.javaparser.JavaParser.parse;</code>
+ *
+ * <p>The name does not include the asterisk or the static keyword.</p>
+ * @author Julio Vilmar Gesser
+ */
+public final class ImportDeclaration extends Node implements NodeWithName<ImportDeclaration> {
+
+    private Name name;
+
+    private boolean isStatic;
+
+    private boolean isAsterisk;
+
+    private ImportDeclaration() {
+        this(null, new Name(), false, false);
+    }
+
+    public ImportDeclaration(String name, boolean isStatic, boolean isAsterisk) {
+        this(null, parseName(name), isStatic, isAsterisk);
+    }
+
+    @AllFieldsConstructor
+    public ImportDeclaration(Name name, boolean isStatic, boolean isAsterisk) {
+        this(null, name, isStatic, isAsterisk);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ImportDeclaration(TokenRange tokenRange, Name name, boolean isStatic, boolean isAsterisk) {
+        super(tokenRange);
+        setName(name);
+        setStatic(isStatic);
+        setAsterisk(isAsterisk);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Retrieves the name of the import (.* is not included.)
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    /**
+     * Return if the import ends with "*".
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isAsterisk() {
+        return isAsterisk;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isStatic() {
+        return isStatic;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ImportDeclaration setAsterisk(final boolean isAsterisk) {
+        if (isAsterisk == this.isAsterisk) {
+            return (ImportDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.ASTERISK, this.isAsterisk, isAsterisk);
+        this.isAsterisk = isAsterisk;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ImportDeclaration setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ImportDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ImportDeclaration setStatic(final boolean isStatic) {
+        if (isStatic == this.isStatic) {
+            return (ImportDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.STATIC, this.isStatic, isStatic);
+        this.isStatic = isStatic;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ImportDeclaration clone() {
+        return (ImportDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ImportDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.importDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/Modifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/Modifier.java
new file mode 100644
index 0000000..b6d0309
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/Modifier.java
@@ -0,0 +1,72 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast;

+

+import java.util.EnumSet;

+

+/**

+ * One of the modifiers known in Java.

+ */

+public enum Modifier {

+    PUBLIC,

+    PROTECTED,

+    PRIVATE,

+    ABSTRACT,

+    STATIC,

+    FINAL,

+    TRANSIENT,

+    VOLATILE,

+    SYNCHRONIZED,

+    NATIVE,

+    STRICTFP,

+    TRANSITIVE,

+    DEFAULT;

+

+    final String codeRepresentation;

+

+    Modifier() {

+        this.codeRepresentation = name().toLowerCase();

+    }

+

+    /**

+     * @return the keyword represented by this modifier.

+     */

+    public String asString() {

+        return codeRepresentation;

+    }

+

+    public EnumSet<Modifier> toEnumSet() {

+        return EnumSet.of(this);

+    }

+

+    public static AccessSpecifier getAccessSpecifier(EnumSet<Modifier> modifiers) {

+        if (modifiers.contains(Modifier.PUBLIC)) {

+            return AccessSpecifier.PUBLIC;

+        } else if (modifiers.contains(Modifier.PROTECTED)) {

+            return AccessSpecifier.PROTECTED;

+        } else if (modifiers.contains(Modifier.PRIVATE)) {

+            return AccessSpecifier.PRIVATE;

+        } else {

+            return AccessSpecifier.DEFAULT;

+        }

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java b/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
new file mode 100644
index 0000000..98d0bbc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/Node.java
@@ -0,0 +1,1004 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast;
+
+import com.github.javaparser.HasParentNode;
+import com.github.javaparser.Range;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.nodeTypes.NodeWithRange;
+import com.github.javaparser.ast.nodeTypes.NodeWithTokenRange;
+import com.github.javaparser.ast.observer.AstObserver;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.observer.PropagatingAstObserver;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.EqualsVisitor;
+import com.github.javaparser.ast.visitor.HashCodeVisitor;
+import com.github.javaparser.ast.visitor.Visitable;
+import com.github.javaparser.metamodel.*;
+import com.github.javaparser.printer.PrettyPrinter;
+import com.github.javaparser.printer.PrettyPrinterConfiguration;
+import com.github.javaparser.resolution.SymbolResolver;
+import javax.annotation.Generated;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import static com.github.javaparser.ast.Node.Parsedness.PARSED;
+import static com.github.javaparser.ast.Node.TreeTraversal.PREORDER;
+import static java.util.Collections.unmodifiableList;
+import static java.util.Spliterator.DISTINCT;
+import static java.util.Spliterator.NONNULL;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.metamodel.NodeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+
+/**
+ * Base class for all nodes of the abstract syntax tree.
+ * <h2>Construction</h2>
+ * <p>The tree is built by instantiating the required nodes, then adding them to other nodes.
+ * If it is the parser who is building the tree, it will use the largest constructor,
+ * the one with "range" as the first parameter.
+ * If you want to manually instantiate nodes, we suggest to...
+ * <ul>
+ * <li>use a convenience method, like "addStatement(...)", or if none are available...</li>
+ * <li>use a convenient constructor, like ClassOrInterfaceType(String name), or if none are available...</li>
+ * <li>use the default constructor.</li>
+ * <li>Alternatively, use one of the JavaParser.parse(snippet) methods.</li>
+ * </ul>
+ * ... and use the various methods on the node to initialize it further, if needed.
+ * <h2>Parent/child</h2>
+ * <p>The parent node field is managed automatically and can be seen as read only.
+ * Note that there is only one parent,
+ * and trying to use the same node in two places will lead to unexpected behaviour.
+ * It is advised to clone() a node before moving it around.
+ * <h2>Comments</h2>
+ * <p>Each Node can have one associated comment which describes it and
+ * a number of "orphan comments" which it contains but are not specifically
+ * associated to any child.
+ * <h2>Positions</h2>
+ * <p>When the parser creates nodes, it sets their source code position in the "range" field.
+ * When you manually instantiate nodes, their range is not set.
+ * The top left character is position 1, 1.
+ * Note that since this is an <i>abstract</i> syntax tree,
+ * it leaves out a lot of text from the original source file,
+ * like where braces or comma's are exactly.
+ * Therefore there is no position information on everything in the original source file.
+ * <h2>Observers</h2>
+ * <p>It is possible to add observers to the the tree.
+ * Any change in the tree is sent as an event to any observers watching.
+ * <h2>Visitors</h2>
+ * <p>The most comfortable way of working with an abstract syntax tree is using visitors.
+ * You can use one of the visitors in the visitor package, or extend one of them.
+ * A visitor can be "run" by calling accept on a node:
+ * <pre>node.accept(visitor, argument);</pre>
+ * where argument is an object of your choice (often simply null.)
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Node implements Cloneable, HasParentNode<Node>, Visitable, NodeWithRange<Node>, NodeWithTokenRange<Node> {
+
+    /**
+     * Different registration mode for observers on nodes.
+     */
+    public enum ObserverRegistrationMode {
+
+        /**
+         * Notify exclusively for changes happening on this node alone.
+         */
+        JUST_THIS_NODE,
+        /**
+         * Notify for changes happening on this node and all its descendants existing at the moment in
+         * which the observer was registered. Nodes attached later will not be observed.
+         */
+        THIS_NODE_AND_EXISTING_DESCENDANTS,
+        /**
+         * Notify for changes happening on this node and all its descendants. The descendants existing at the moment in
+         * which the observer was registered will be observed immediately. As new nodes are attached later they are
+         * automatically registered to be observed.
+         */
+        SELF_PROPAGATING
+    }
+
+    public enum Parsedness {
+
+        PARSED, UNPARSABLE
+    }
+
+    /**
+     * This can be used to sort nodes on position.
+     */
+    public static Comparator<NodeWithRange<?>> NODE_BY_BEGIN_POSITION = (a, b) -> {
+        if (a.getRange().isPresent() && b.getRange().isPresent()) {
+            return a.getRange().get().begin.compareTo(b.getRange().get().begin);
+        }
+        if (a.getRange().isPresent() || b.getRange().isPresent()) {
+            if (a.getRange().isPresent()) {
+                return 1;
+            }
+            return -1;
+        }
+        return 0;
+    };
+
+    private static final PrettyPrinter toStringPrinter = new PrettyPrinter(new PrettyPrinterConfiguration());
+
+    protected static final PrettyPrinterConfiguration prettyPrinterNoCommentsConfiguration = new PrettyPrinterConfiguration().setPrintComments(false);
+
+    @InternalProperty
+    private Range range;
+
+    @InternalProperty
+    private TokenRange tokenRange;
+
+    @InternalProperty
+    private Node parentNode;
+
+    @InternalProperty
+    private List<Node> childNodes = new LinkedList<>();
+
+    @InternalProperty
+    private List<Comment> orphanComments = new LinkedList<>();
+
+    @InternalProperty
+    private IdentityHashMap<DataKey<?>, Object> data = null;
+
+    @OptionalProperty
+    private Comment comment;
+
+    @InternalProperty
+    private List<AstObserver> observers = new ArrayList<>();
+
+    @InternalProperty
+    private Parsedness parsed = PARSED;
+
+    protected Node(TokenRange tokenRange) {
+        setTokenRange(tokenRange);
+    }
+
+    /**
+     * Called in every constructor for node specific code.
+     * It can't be written in the constructor itself because it will
+     * be overwritten during code generation.
+     */
+    protected void customInitialization() {
+    }
+
+    /**
+     * This is a comment associated with this node.
+     *
+     * @return comment property
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Comment> getComment() {
+        return Optional.ofNullable(comment);
+    }
+
+    /**
+     * @return the range of characters in the source code that this node covers.
+     */
+    public Optional<Range> getRange() {
+        return Optional.ofNullable(range);
+    }
+
+    /**
+     * @return the range of tokens that this node covers.
+     */
+    public Optional<TokenRange> getTokenRange() {
+        return Optional.ofNullable(tokenRange);
+    }
+
+    public Node setTokenRange(TokenRange tokenRange) {
+        this.tokenRange = tokenRange;
+        if (tokenRange == null || !(tokenRange.getBegin().getRange().isPresent() && tokenRange.getBegin().getRange().isPresent())) {
+            range = null;
+        } else {
+            range = new Range(tokenRange.getBegin().getRange().get().begin, tokenRange.getEnd().getRange().get().end);
+        }
+        return this;
+    }
+
+    /**
+     * @param range the range of characters in the source code that this node covers. null can be used to indicate that
+     * no range information is known, or that it is not of interest.
+     */
+    public Node setRange(Range range) {
+        if (this.range == range) {
+            return this;
+        }
+        notifyPropertyChange(ObservableProperty.RANGE, this.range, range);
+        this.range = range;
+        return this;
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    public final Node setComment(final Comment comment) {
+        if (this.comment == comment) {
+            return this;
+        }
+        if (comment != null && (this instanceof Comment)) {
+            throw new RuntimeException("A comment can not be commented");
+        }
+        notifyPropertyChange(ObservableProperty.COMMENT, this.comment, comment);
+        if (this.comment != null) {
+            this.comment.setCommentedNode(null);
+        }
+        this.comment = comment;
+        if (comment != null) {
+            this.comment.setCommentedNode(this);
+        }
+        return this;
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    public final Node setLineComment(String comment) {
+        return setComment(new LineComment(comment));
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    public final Node setBlockComment(String comment) {
+        return setComment(new BlockComment(comment));
+    }
+
+    /**
+     * Return the String representation of this node.
+     *
+     * @return the String representation of this node
+     */
+    @Override
+    public final String toString() {
+        return toStringPrinter.print(this);
+    }
+
+    public final String toString(PrettyPrinterConfiguration prettyPrinterConfiguration) {
+        return new PrettyPrinter(prettyPrinterConfiguration).print(this);
+    }
+
+    @Override
+    public final int hashCode() {
+        return HashCodeVisitor.hashCode(this);
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null || !(obj instanceof Node)) {
+            return false;
+        }
+        return EqualsVisitor.equals(this, (Node) obj);
+    }
+
+    @Override
+    public Optional<Node> getParentNode() {
+        return Optional.ofNullable(parentNode);
+    }
+
+    /**
+     * Contains all nodes that have this node set as their parent.
+     * You can add and remove nodes from this list by adding or removing nodes from the fields of this node.
+     *
+     * @return all nodes that have this node as their parent.
+     */
+    public List<Node> getChildNodes() {
+        return unmodifiableList(childNodes);
+    }
+
+    public void addOrphanComment(Comment comment) {
+        orphanComments.add(comment);
+        comment.setParentNode(this);
+    }
+
+    public boolean removeOrphanComment(Comment comment) {
+        boolean removed = orphanComments.remove(comment);
+        if (removed) {
+            comment.setParentNode(null);
+        }
+        return removed;
+    }
+
+    /**
+     * This is a list of Comment which are inside the node and are not associated
+     * with any meaningful AST Node.
+     * <p>
+     * For example, comments at the end of methods (immediately before the parenthesis)
+     * or at the end of CompilationUnit are orphan comments.
+     * <p>
+     * When more than one comment preceeds a statement, the one immediately preceding it
+     * it is associated with the statements, while the others are orphans.
+     * <p>
+     * Changes to this list are not persisted.
+     *
+     * @return all comments that cannot be attributed to a concept
+     */
+    public List<Comment> getOrphanComments() {
+        return new LinkedList<>(orphanComments);
+    }
+
+    /**
+     * This is the list of Comment which are contained in the Node either because
+     * they are properly associated to one of its children or because they are floating
+     * around inside the Node
+     *
+     * @return all Comments within the node as a list
+     */
+    public List<Comment> getAllContainedComments() {
+        List<Comment> comments = new LinkedList<>();
+        comments.addAll(getOrphanComments());
+        for (Node child : getChildNodes()) {
+            child.getComment().ifPresent(comments::add);
+            comments.addAll(child.getAllContainedComments());
+        }
+        return comments;
+    }
+
+    /**
+     * Assign a new parent to this node, removing it
+     * from the list of children of the previous parent, if any.
+     *
+     * @param newParentNode node to be set as parent
+     */
+    @Override
+    public Node setParentNode(Node newParentNode) {
+        if (newParentNode == parentNode) {
+            return this;
+        }
+        observers.forEach(o -> o.parentChange(this, parentNode, newParentNode));
+        // remove from old parent, if any
+        if (parentNode != null) {
+            final List<Node> parentChildNodes = parentNode.childNodes;
+            for (int i = 0; i < parentChildNodes.size(); i++) {
+                if (parentChildNodes.get(i) == this) {
+                    parentChildNodes.remove(i);
+                }
+            }
+        }
+        parentNode = newParentNode;
+        // add to new parent, if any
+        if (parentNode != null) {
+            parentNode.childNodes.add(this);
+        }
+        return this;
+    }
+
+    protected void setAsParentNodeOf(Node childNode) {
+        if (childNode != null) {
+            childNode.setParentNode(getParentNodeForChildren());
+        }
+    }
+
+    public static final int ABSOLUTE_BEGIN_LINE = -1;
+
+    public static final int ABSOLUTE_END_LINE = -2;
+
+    /**
+     * @deprecated use getComment().isPresent()
+     */
+    @Deprecated
+    public boolean hasComment() {
+        return comment != null;
+    }
+
+    public void tryAddImportToParentCompilationUnit(Class<?> clazz) {
+        getAncestorOfType(CompilationUnit.class).ifPresent(p -> p.addImport(clazz));
+    }
+
+    /**
+     * Recursively finds all nodes of a certain type.
+     *
+     * @param clazz the type of node to find.
+     * @deprecated use find(Class)
+     */
+    public <N extends Node> List<N> getChildNodesByType(Class<N> clazz) {
+        List<N> nodes = new ArrayList<>();
+        for (Node child : getChildNodes()) {
+            if (clazz.isInstance(child)) {
+                nodes.add(clazz.cast(child));
+            }
+            nodes.addAll(child.getChildNodesByType(clazz));
+        }
+        return nodes;
+    }
+
+    /**
+     * @deprecated use findAll(Class)
+     */
+    @Deprecated
+    public <N extends Node> List<N> getNodesByType(Class<N> clazz) {
+        return getChildNodesByType(clazz);
+    }
+
+    /**
+     * Gets data for this node using the given key.
+     *
+     * @param <M> The type of the data.
+     * @param key The key for the data
+     * @return The data or null of no data was found for the given key
+     * @see DataKey
+     */
+    @SuppressWarnings("unchecked")
+    public <M> M getData(final DataKey<M> key) {
+        if (data == null) {
+            return null;
+        }
+        return (M) data.get(key);
+    }
+
+    /**
+     * Sets data for this node using the given key.
+     * For information on creating DataKey, see {@link DataKey}.
+     *
+     * @param <M> The type of data
+     * @param key The singleton key for the data
+     * @param object The data object
+     * @see DataKey
+     */
+    public <M> void setData(DataKey<M> key, M object) {
+        if (data == null) {
+            data = new IdentityHashMap<>();
+        }
+        data.put(key, object);
+    }
+
+    /**
+     * @return does this node have data for this key?
+     */
+    public boolean containsData(DataKey<?> key) {
+        if (data == null) {
+            return false;
+        }
+        return data.get(key) != null;
+    }
+
+    /**
+     * Try to remove this node from the parent
+     *
+     * @return true if removed, false if it is a required property of the parent, or if the parent isn't set.
+     * @throws RuntimeException if it fails in an unexpected way
+     */
+    public boolean remove() {
+        if (parentNode == null) {
+            return false;
+        }
+        return parentNode.remove(this);
+    }
+
+    /**
+     * Try to replace this node in the parent with the supplied node.
+     *
+     * @return true if removed, or if the parent isn't set.
+     * @throws RuntimeException if it fails in an unexpected way
+     */
+    public boolean replace(Node node) {
+        if (parentNode == null) {
+            return false;
+        }
+        return parentNode.replace(this, node);
+    }
+
+    /**
+     * Forcibly removes this node from the AST.
+     * If it cannot be removed from the parent with remove(),
+     * it will try to remove its parent instead,
+     * until it finds a node that can be removed,
+     * or no parent can be found.
+     * <p>
+     * Since everything at CompilationUnit level is removable,
+     * this method will only (silently) fail when the node is in a detached AST fragment.
+     */
+    public void removeForced() {
+        if (!remove()) {
+            getParentNode().ifPresent(Node::remove);
+        }
+    }
+
+    @Override
+    public Node getParentNodeForChildren() {
+        return this;
+    }
+
+    protected void setAsParentNodeOf(NodeList<? extends Node> list) {
+        if (list != null) {
+            list.setParentNode(getParentNodeForChildren());
+        }
+    }
+
+    public <P> void notifyPropertyChange(ObservableProperty property, P oldValue, P newValue) {
+        this.observers.forEach(o -> o.propertyChange(this, property, oldValue, newValue));
+    }
+
+    @Override
+    public void unregister(AstObserver observer) {
+        this.observers.remove(observer);
+    }
+
+    @Override
+    public void register(AstObserver observer) {
+        this.observers.add(observer);
+    }
+
+    /**
+     * Register a new observer for the given node. Depending on the mode specified also descendants, existing
+     * and new, could be observed. For more details see <i>ObserverRegistrationMode</i>.
+     */
+    public void register(AstObserver observer, ObserverRegistrationMode mode) {
+        if (mode == null) {
+            throw new IllegalArgumentException("Mode should be not null");
+        }
+        switch(mode) {
+            case JUST_THIS_NODE:
+                register(observer);
+                break;
+            case THIS_NODE_AND_EXISTING_DESCENDANTS:
+                registerForSubtree(observer);
+                break;
+            case SELF_PROPAGATING:
+                registerForSubtree(PropagatingAstObserver.transformInPropagatingObserver(observer));
+                break;
+            default:
+                throw new UnsupportedOperationException("This mode is not supported: " + mode);
+        }
+    }
+
+    /**
+     * Register the observer for the current node and all the contained node and nodelists, recursively.
+     */
+    public void registerForSubtree(AstObserver observer) {
+        register(observer);
+        this.getChildNodes().forEach(c -> c.registerForSubtree(observer));
+        for (PropertyMetaModel property : getMetaModel().getAllPropertyMetaModels()) {
+            if (property.isNodeList()) {
+                NodeList<?> nodeList = (NodeList<?>) property.getValue(this);
+                if (nodeList != null)
+                    nodeList.register(observer);
+            }
+        }
+    }
+
+    @Override
+    public boolean isRegistered(AstObserver observer) {
+        return this.observers.contains(observer);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (comment != null) {
+            if (node == comment) {
+                removeComment();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public Node removeComment() {
+        return setComment((Comment) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public Node clone() {
+        return (Node) accept(new CloneVisitor(), null);
+    }
+
+    /**
+     * @return get JavaParser specific node introspection information.
+     */
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public NodeMetaModel getMetaModel() {
+        return JavaParserMetaModel.nodeMetaModel;
+    }
+
+    /**
+     * @return whether this node was successfully parsed or not.
+     * If it was not, only the range and tokenRange fields will be valid.
+     */
+    public Parsedness getParsed() {
+        return parsed;
+    }
+
+    /**
+     * Used by the parser to flag unparsable nodes.
+     */
+    public Node setParsed(Parsedness parsed) {
+        this.parsed = parsed;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (comment != null) {
+            if (node == comment) {
+                setComment((Comment) replacementNode);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Finds the root node of this AST by finding the topmost parent.
+     */
+    public Node findRootNode() {
+        Node n = this;
+        while (n.getParentNode().isPresent()) {
+            n = n.getParentNode().get();
+        }
+        return n;
+    }
+
+    /**
+     * @return the containing CompilationUnit, or empty if this node is not inside a compilation unit.
+     */
+    public Optional<CompilationUnit> findCompilationUnit() {
+        Node rootNode = findRootNode();
+        if (rootNode instanceof CompilationUnit) {
+            return Optional.of((CompilationUnit) rootNode);
+        }
+        return Optional.empty();
+    }
+
+    protected SymbolResolver getSymbolResolver() {
+        return findCompilationUnit().map(cu -> {
+            SymbolResolver symbolResolver = cu.getData(SYMBOL_RESOLVER_KEY);
+            if (symbolResolver == null) {
+                throw new IllegalStateException("Symbol resolution not configured: to configure consider setting a SymbolResolver in the ParserConfiguration");
+            }
+            return symbolResolver;
+        }).orElseThrow(() -> new IllegalStateException("The node is not inserted in a CompilationUnit"));
+    }
+
+    // We need to expose it because we will need to use it to inject the SymbolSolver
+    public static final DataKey<SymbolResolver> SYMBOL_RESOLVER_KEY = new DataKey<SymbolResolver>() {
+    };
+
+    public enum TreeTraversal {
+
+        PREORDER, BREADTHFIRST, POSTORDER, PARENTS, DIRECT_CHILDREN
+    }
+
+    private Iterator<Node> treeIterator(TreeTraversal traversal) {
+        switch(traversal) {
+            case BREADTHFIRST:
+                return new BreadthFirstIterator(this);
+            case POSTORDER:
+                return new PostOrderIterator(this);
+            case PREORDER:
+                return new PreOrderIterator(this);
+            case DIRECT_CHILDREN:
+                return new DirectChildrenIterator(this);
+            case PARENTS:
+                return new ParentsVisitor(this);
+            default:
+                throw new IllegalArgumentException("Unknown traversal choice.");
+        }
+    }
+
+    private Iterable<Node> treeIterable(TreeTraversal traversal) {
+        return () -> treeIterator(traversal);
+    }
+
+    /**
+     * Make a stream of nodes using traversal algorithm "traversal".
+     */
+    public Stream<Node> stream(TreeTraversal traversal) {
+        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(treeIterator(traversal), NONNULL | DISTINCT), false);
+    }
+
+    /**
+     * Make a stream of nodes using pre-order traversal.
+     */
+    public Stream<Node> stream() {
+        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(treeIterator(PREORDER), NONNULL | DISTINCT), false);
+    }
+
+    /**
+     * Walks the AST, calling the consumer for every node, with traversal algorithm "traversal".
+     * <br/>This is the most general walk method. All other walk and findAll methods are based on this.
+     */
+    public void walk(TreeTraversal traversal, Consumer<Node> consumer) {
+        // Could be implemented as a call to the above walk method, but this is a little more efficient.
+        for (Node node : treeIterable(traversal)) {
+            consumer.accept(node);
+        }
+    }
+
+    /**
+     * Walks the AST, calling the consumer for every node with pre-order traversal.
+     */
+    public void walk(Consumer<Node> consumer) {
+        walk(PREORDER, consumer);
+    }
+
+    /**
+     * Walks the AST with pre-order traversal, calling the consumer for every node of type "nodeType".
+     */
+    public <T extends Node> void walk(Class<T> nodeType, Consumer<T> consumer) {
+        walk(TreeTraversal.PREORDER, node -> {
+            if (nodeType.isAssignableFrom(node.getClass())) {
+                consumer.accept(nodeType.cast(node));
+            }
+        });
+    }
+
+    /**
+     * Walks the AST with pre-order traversal, returning all nodes of type "nodeType".
+     */
+    public <T extends Node> List<T> findAll(Class<T> nodeType) {
+        final List<T> found = new ArrayList<>();
+        walk(nodeType, found::add);
+        return found;
+    }
+
+    /**
+     * Walks the AST with pre-order traversal, returning all nodes of type "nodeType" that match the predicate.
+     */
+    public <T extends Node> List<T> findAll(Class<T> nodeType, Predicate<T> predicate) {
+        final List<T> found = new ArrayList<>();
+        walk(nodeType, n -> {
+            if (predicate.test(n))
+                found.add(n);
+        });
+        return found;
+    }
+
+    /**
+     * Walks the AST, applying the function for every node, with traversal algorithm "traversal". If the function
+     * returns something else than null, the traversal is stopped and the function result is returned. <br/>This is the
+     * most general findFirst method. All other findFirst methods are based on this.
+     */
+    public <T> Optional<T> findFirst(TreeTraversal traversal, Function<Node, Optional<T>> consumer) {
+        for (Node node : treeIterable(traversal)) {
+            final Optional<T> result = consumer.apply(node);
+            if (result.isPresent()) {
+                return result;
+            }
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * Walks the AST with pre-order traversal, returning the first node of type "nodeType" or empty() if none is found.
+     */
+    public <N extends Node> Optional<N> findFirst(Class<N> nodeType) {
+        return findFirst(TreeTraversal.PREORDER, node -> {
+            if (nodeType.isAssignableFrom(node.getClass())) {
+                return Optional.of(nodeType.cast(node));
+            }
+            return Optional.empty();
+        });
+    }
+
+    /**
+     * Walks the AST with pre-order traversal, returning the first node of type "nodeType" that matches "predicate" or empty() if none is
+     * found.
+     */
+    public <N extends Node> Optional<N> findFirst(Class<N> nodeType, Predicate<N> predicate) {
+        return findFirst(TreeTraversal.PREORDER, node -> {
+            if (nodeType.isAssignableFrom(node.getClass())) {
+                final N castNode = nodeType.cast(node);
+                if (predicate.test(castNode)) {
+                    return Optional.of(castNode);
+                }
+            }
+            return Optional.empty();
+        });
+    }
+
+    /**
+     * Walks the parents of this node, returning the first node of type "nodeType" or empty() if none is found.
+     */
+    public <N extends Node> Optional<N> findParent(Class<N> nodeType) {
+        Node n = this;
+        while (n.getParentNode().isPresent()) {
+            n = n.getParentNode().get();
+            if (nodeType.isAssignableFrom(n.getClass())) {
+                return Optional.of(nodeType.cast(n));
+            }
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * Performs a breadth-first node traversal starting with a given node.
+     *
+     * @see <a href="https://en.wikipedia.org/wiki/Breadth-first_search">Breadth-first traversal</a>
+     */
+    public static class BreadthFirstIterator implements Iterator<Node> {
+
+        private final Queue<Node> queue = new LinkedList<>();
+
+        public BreadthFirstIterator(Node node) {
+            queue.add(node);
+        }
+
+        @Override
+        public boolean hasNext() {
+            return !queue.isEmpty();
+        }
+
+        @Override
+        public Node next() {
+            Node next = queue.remove();
+            queue.addAll(next.getChildNodes());
+            return next;
+        }
+    }
+
+    /**
+     * Performs a simple traversal over all nodes that have the passed node as their parent.
+     */
+    public static class DirectChildrenIterator implements Iterator<Node> {
+
+        private final Iterator<Node> childrenIterator;
+
+        public DirectChildrenIterator(Node node) {
+            childrenIterator = new ArrayList<>(node.getChildNodes()).iterator();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return childrenIterator.hasNext();
+        }
+
+        @Override
+        public Node next() {
+            return childrenIterator.next();
+        }
+    }
+
+    /**
+     * Iterates over the parent of the node, then the parent's parent, then the parent's parent's parent, until running
+     * out of parents.
+     */
+    public static class ParentsVisitor implements Iterator<Node> {
+
+        private Node node;
+
+        public ParentsVisitor(Node node) {
+            this.node = node;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return node.getParentNode().isPresent();
+        }
+
+        @Override
+        public Node next() {
+            node = node.getParentNode().orElse(null);
+            return node;
+        }
+    }
+
+    /**
+     * Performs a pre-order (or depth-first) node traversal starting with a given node.
+     *
+     * @see <a href="https://en.wikipedia.org/wiki/Pre-order">Pre-order traversal</a>
+     */
+    public static class PreOrderIterator implements Iterator<Node> {
+
+        private final Stack<Node> stack = new Stack<>();
+
+        public PreOrderIterator(Node node) {
+            stack.add(node);
+        }
+
+        @Override
+        public boolean hasNext() {
+            return !stack.isEmpty();
+        }
+
+        @Override
+        public Node next() {
+            Node next = stack.pop();
+            List<Node> children = next.getChildNodes();
+            for (int i = children.size() - 1; i >= 0; i--) {
+                stack.add(children.get(i));
+            }
+            return next;
+        }
+    }
+
+    /**
+     * Performs a post-order (or leaves-first) node traversal starting with a given node.
+     *
+     * @see <a href="https://en.wikipedia.org/wiki/Post-order">Post-order traversal</a>
+     */
+    public static class PostOrderIterator implements Iterator<Node> {
+
+        private final Stack<List<Node>> nodesStack = new Stack<>();
+
+        private final Stack<Integer> cursorStack = new Stack<>();
+
+        private final Node root;
+
+        private boolean hasNext = true;
+
+        public PostOrderIterator(Node root) {
+            this.root = root;
+            fillStackToLeaf(root);
+        }
+
+        private void fillStackToLeaf(Node node) {
+            while (true) {
+                List<Node> childNodes = new ArrayList<>(node.getChildNodes());
+                if (childNodes.isEmpty()) {
+                    break;
+                }
+                nodesStack.push(childNodes);
+                cursorStack.push(0);
+                node = childNodes.get(0);
+            }
+        }
+
+        @Override
+        public boolean hasNext() {
+            return hasNext;
+        }
+
+        @Override
+        public Node next() {
+            final List<Node> nodes = nodesStack.peek();
+            final int cursor = cursorStack.peek();
+            final boolean levelHasNext = cursor < nodes.size();
+            if (levelHasNext) {
+                Node node = nodes.get(cursor);
+                fillStackToLeaf(node);
+                return nextFromLevel();
+            } else {
+                nodesStack.pop();
+                cursorStack.pop();
+                hasNext = !nodesStack.empty();
+                if (hasNext) {
+                    return nextFromLevel();
+                }
+                return root;
+            }
+        }
+
+        private Node nextFromLevel() {
+            final List<Node> nodes = nodesStack.peek();
+            final int cursor = cursorStack.pop();
+            cursorStack.push(cursor + 1);
+            return nodes.get(cursor);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/NodeList.java b/javaparser-core/src/main/java/com/github/javaparser/ast/NodeList.java
new file mode 100644
index 0000000..f370e96
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/NodeList.java
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.HasParentNode;
+import com.github.javaparser.ast.observer.AstObserver;
+import com.github.javaparser.ast.observer.Observable;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.Visitable;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.InternalProperty;
+
+import java.util.*;
+import java.util.function.*;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * A list of nodes.
+ * It usually has a parent node.
+ * Unlike normal Nodes, this does not mean that it is a child of that parent.
+ * Instead, this list will make every node it contains a child of its parent.
+ * This way, a NodeList does not create an extra level inside the AST.
+ *
+ * @param <N> the type of nodes contained.
+ */
+public class NodeList<N extends Node> implements List<N>, Iterable<N>, HasParentNode<NodeList<N>>, Visitable, Observable {
+    @InternalProperty
+    private List<N> innerList = new ArrayList<>(0);
+
+    private Node parentNode;
+
+    private List<AstObserver> observers = new ArrayList<>();
+
+    public NodeList() {
+        parentNode = null;
+    }
+
+    public NodeList(Collection<N> n) {
+        this.addAll(n);
+    }
+
+    public NodeList(N... n) {
+        this.addAll(Arrays.asList(n));
+    }
+
+    @Override
+    public boolean add(N node) {
+        notifyElementAdded(innerList.size(), node);
+        own(node);
+        return innerList.add(node);
+    }
+
+    private void own(N node) {
+        if (node == null) {
+            return;
+        }
+        setAsParentNodeOf(node);
+    }
+
+    public boolean remove(Node node) {
+        int index = innerList.indexOf(node);
+        if (index != -1) {
+            notifyElementRemoved(index, node);
+            node.setParentNode(null);
+        }
+        return innerList.remove(node);
+    }
+
+    public N removeFirst() {
+        return remove(0);
+    }
+
+    public N removeLast() {
+        return remove(innerList.size() - 1);
+    }
+
+    @SafeVarargs
+    public static <X extends Node> NodeList<X> nodeList(X... nodes) {
+        final NodeList<X> nodeList = new NodeList<>();
+        Collections.addAll(nodeList, nodes);
+        return nodeList;
+    }
+
+    public static <X extends Node> NodeList<X> nodeList(Collection<X> nodes) {
+        final NodeList<X> nodeList = new NodeList<>();
+        nodeList.addAll(nodes);
+        return nodeList;
+    }
+
+    public static <X extends Node> NodeList<X> nodeList(NodeList<X> nodes) {
+        final NodeList<X> nodeList = new NodeList<>();
+        nodeList.addAll(nodes);
+        return nodeList;
+    }
+
+    public boolean contains(N node) {
+        return innerList.contains(node);
+    }
+
+    @Override
+    public int size() {
+        return innerList.size();
+    }
+
+    @Override
+    public N get(int i) {
+        return innerList.get(i);
+    }
+
+    @Override
+    public Iterator<N> iterator() {
+        // TODO take care of "Iterator.remove"
+        return innerList.iterator();
+    }
+
+    @Override
+    public N set(int index, N element) {
+        if (index < 0 || index >= innerList.size()) {
+            throw new IllegalArgumentException("Illegal index. The index should be between 0 and " + innerList.size()
+                    + " excluded. It is instead " + index);
+        }
+        if (element == innerList.get(index)) {
+            return element;
+        }
+        notifyElementReplaced(index, element);
+        innerList.get(index).setParentNode(null);
+        setAsParentNodeOf(element);
+        return innerList.set(index, element);
+    }
+
+    @Override
+    public N remove(int index) {
+        notifyElementRemoved(index, innerList.get(index));
+        N remove = innerList.remove(index);
+        if (remove != null)
+            remove.setParentNode(null);
+        return remove;
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return innerList.isEmpty();
+    }
+
+    @Override
+    public void sort(Comparator<? super N> comparator) {
+        innerList.sort(comparator);
+    }
+
+    public void addAll(NodeList<N> otherList) {
+        for (N node : otherList) {
+            add(node);
+        }
+    }
+
+    @Override
+    public void add(int index, N node) {
+        notifyElementAdded(index, node);
+        own(node);
+        innerList.add(index, node);
+    }
+
+    /**
+     * Inserts the node before all other nodes.
+     */
+    public NodeList<N> addFirst(N node) {
+        add(0, node);
+        return this;
+    }
+
+    /**
+     * Inserts the node after all other nodes. (This is simply an alias for add.)
+     */
+    public NodeList<N> addLast(N node) {
+        add(node);
+        return this;
+    }
+
+    /**
+     * Inserts the node after afterThisNode.
+     *
+     * @throws IllegalArgumentException when afterThisNode is not in this list.
+     */
+    public NodeList<N> addAfter(N node, N afterThisNode) {
+        int i = indexOf(afterThisNode);
+        if (i == -1) {
+            throw new IllegalArgumentException("Can't find node to insert after.");
+        }
+        add(i + 1, node);
+        return this;
+    }
+
+    /**
+     * Inserts the node before beforeThisNode.
+     *
+     * @throws IllegalArgumentException when beforeThisNode is not in this list.
+     */
+    public NodeList<N> addBefore(N node, N beforeThisNode) {
+        int i = indexOf(beforeThisNode);
+        if (i == -1) {
+            throw new IllegalArgumentException("Can't find node to insert before.");
+        }
+        add(i, node);
+        return this;
+    }
+
+
+    @Override
+    public Optional<Node> getParentNode() {
+        return Optional.ofNullable(parentNode);
+    }
+
+    /**
+     * Sets the parentNode
+     *
+     * @param parentNode the parentNode
+     * @return this, the NodeList
+     */
+    @Override
+    public NodeList<N> setParentNode(Node parentNode) {
+        this.parentNode = parentNode;
+        setAsParentNodeOf(innerList);
+        return this;
+    }
+
+    @Override
+    public Node getParentNodeForChildren() {
+        return parentNode;
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * @see java.lang.Iterable#forEach(java.util.function.Consumer)
+     */
+    @Override
+    public void forEach(Consumer<? super N> action) {
+        innerList.forEach(action);
+    }
+
+    /**
+     * @see java.util.List#contains(java.lang.Object)
+     */
+    @Override
+    public boolean contains(Object o) {
+        return innerList.contains(o);
+    }
+
+    /**
+     * @see java.util.List#toArray()
+     */
+    @Override
+    public Object[] toArray() {
+        return innerList.toArray();
+    }
+
+    /**
+     * @see java.util.List#toArray(java.lang.Object[])
+     */
+    @Override
+    public <T> T[] toArray(T[] a) {
+        return innerList.toArray(a);
+    }
+
+    /**
+     * @see java.util.List#remove(java.lang.Object)
+     */
+    @Override
+    public boolean remove(Object o) {
+        if (o instanceof Node) {
+            return remove((Node) o);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * @see java.util.List#containsAll(java.util.Collection)
+     */
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        return innerList.containsAll(c);
+    }
+
+    /**
+     * @see java.util.List#addAll(java.util.Collection)
+     */
+    @Override
+    public boolean addAll(Collection<? extends N> c) {
+        c.forEach(this::add);
+        return !c.isEmpty();
+    }
+
+    /**
+     * @see java.util.List#addAll(int, java.util.Collection)
+     */
+    @Override
+    public boolean addAll(int index, Collection<? extends N> c) {
+        for (N e : c) {
+            add(index++, e);
+        }
+        return !c.isEmpty();
+    }
+
+    /**
+     * @see java.util.List#removeAll(java.util.Collection)
+     */
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        boolean changed = false;
+        for (Object e : c) {
+            changed = remove(e) || changed;
+        }
+        return changed;
+    }
+
+    /**
+     * @see java.util.List#retainAll(java.util.Collection)
+     */
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        boolean changed = false;
+        for (Object e : this.stream().filter(it -> !c.contains(it)).toArray()) {
+            if (!c.contains(e)) {
+                changed = remove(e) || changed;
+            }
+        }
+        return changed;
+    }
+
+    /**
+     * @see java.util.List#replaceAll(java.util.function.UnaryOperator)
+     */
+    @Override
+    public void replaceAll(UnaryOperator<N> operator) {
+        for (int i = 0; i < this.size(); i++) {
+            set(i, operator.apply(this.get(i)));
+        }
+    }
+
+    /**
+     * @see java.util.Collection#removeIf(java.util.function.Predicate)
+     */
+    @Override
+    public boolean removeIf(Predicate<? super N> filter) {
+        boolean changed = false;
+        for (Object e : this.stream().filter(filter).toArray()) {
+            changed = remove(e) || changed;
+        }
+        return changed;
+    }
+
+    /**
+     * @see java.util.List#clear()
+     */
+    @Override
+    public void clear() {
+        while (!isEmpty()) {
+            remove(0);
+        }
+    }
+
+    /**
+     * @see java.util.List#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object o) {
+        return innerList.equals(o);
+    }
+
+    /**
+     * @see java.util.List#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        return innerList.hashCode();
+    }
+
+    /**
+     * @see java.util.List#indexOf(java.lang.Object)
+     */
+    @Override
+    public int indexOf(Object o) {
+        return innerList.indexOf(o);
+    }
+
+    /**
+     * @see java.util.List#lastIndexOf(java.lang.Object)
+     */
+    @Override
+    public int lastIndexOf(Object o) {
+        return innerList.lastIndexOf(o);
+    }
+
+    /**
+     * @see java.util.List#listIterator()
+     */
+    @Override
+    public ListIterator<N> listIterator() {
+        return innerList.listIterator();
+    }
+
+    /**
+     * @see java.util.List#listIterator(int)
+     */
+    @Override
+    public ListIterator<N> listIterator(int index) {
+        return innerList.listIterator(index);
+    }
+
+    /**
+     * @see java.util.Collection#parallelStream()
+     */
+    @Override
+    public Stream<N> parallelStream() {
+        return innerList.parallelStream();
+    }
+
+    /**
+     * @see java.util.List#subList(int, int)
+     */
+    @Override
+    public List<N> subList(int fromIndex, int toIndex) {
+        return innerList.subList(fromIndex, toIndex);
+    }
+
+    /**
+     * @see java.util.List#spliterator()
+     */
+    @Override
+    public Spliterator<N> spliterator() {
+        return innerList.spliterator();
+    }
+
+    private void notifyElementAdded(int index, Node nodeAddedOrRemoved) {
+        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.ADDITION, index, nodeAddedOrRemoved));
+    }
+
+    private void notifyElementRemoved(int index, Node nodeAddedOrRemoved) {
+        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.REMOVAL, index, nodeAddedOrRemoved));
+    }
+
+    private void notifyElementReplaced(int index, Node nodeAddedOrRemoved) {
+        this.observers.forEach(o -> o.listReplacement(this, index, this.get(index), nodeAddedOrRemoved));
+    }
+
+    @Override
+    public void unregister(AstObserver observer) {
+        this.observers.remove(observer);
+    }
+
+    @Override
+    public void register(AstObserver observer) {
+        this.observers.add(observer);
+    }
+
+    @Override
+    public boolean isRegistered(AstObserver observer) {
+        return this.observers.contains(observer);
+    }
+
+    /**
+     * Replaces the first node that is equal to "old" with "replacement".
+     *
+     * @return true if a replacement has happened.
+     */
+    public boolean replace(N old, N replacement) {
+        int i = indexOf(old);
+        if (i == -1) {
+            return false;
+        }
+        set(i, replacement);
+        return true;
+    }
+
+    /**
+     * @return the opposite of isEmpty()
+     */
+    public boolean isNonEmpty() {
+        return !isEmpty();
+    }
+
+    public void ifNonEmpty(Consumer<? super NodeList<N>> consumer) {
+        if (isNonEmpty())
+            consumer.accept(this);
+    }
+
+    public static <T extends Node> Collector<T, NodeList<T>, NodeList<T>> toNodeList() {
+        return Collector.of(NodeList::new, NodeList::add, (left, right) -> {
+            left.addAll(right);
+            return left;
+        });
+    }
+
+    private void setAsParentNodeOf(List<? extends Node> childNodes) {
+        if (childNodes != null) {
+            for (HasParentNode current : childNodes) {
+                current.setParentNode(getParentNodeForChildren());
+            }
+        }
+    }
+
+    private void setAsParentNodeOf(Node childNode) {
+        if (childNode != null) {
+            childNode.setParentNode(getParentNodeForChildren());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return innerList.stream().map(Node::toString).collect(Collectors.joining(", ", "[", "]"));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/PackageDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/PackageDeclaration.java
new file mode 100644
index 0000000..65a1ca7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/PackageDeclaration.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.PackageDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+
+/**
+ * A package declaration.
+ * <br/><code>package com.github.javaparser.ast;</code>
+ * <br/><code>@Wonderful package anything.can.be.annotated.nowadays;</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class PackageDeclaration extends Node implements NodeWithAnnotations<PackageDeclaration>, NodeWithName<PackageDeclaration> {
+
+    private NodeList<AnnotationExpr> annotations = new NodeList<>();
+
+    private Name name;
+
+    public PackageDeclaration() {
+        this(null, new NodeList<>(), new Name());
+    }
+
+    public PackageDeclaration(Name name) {
+        this(null, new NodeList<>(), name);
+    }
+
+    @AllFieldsConstructor
+    public PackageDeclaration(NodeList<AnnotationExpr> annotations, Name name) {
+        this(null, annotations, name);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public PackageDeclaration(TokenRange tokenRange, NodeList<AnnotationExpr> annotations, Name name) {
+        super(tokenRange);
+        setAnnotations(annotations);
+        setName(name);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Retrieves the list of annotations declared before the package
+     * declaration. Return <code>null</code> if there are no annotations.
+     *
+     * @return list of annotations or <code>null</code>
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    /**
+     * Return the name expression of the package.
+     *
+     * @return the name of the package
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    /**
+     * @param annotations the annotations to set
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public PackageDeclaration setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (PackageDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    /**
+     * Sets the name of this package declaration.
+     *
+     * @param name the name to set
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public PackageDeclaration setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (PackageDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public PackageDeclaration clone() {
+        return (PackageDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public PackageDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.packageDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/AnnotationDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/AnnotationDeclaration.java
new file mode 100644
index 0000000..aa793ef
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/AnnotationDeclaration.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.AnnotationDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedAnnotationDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An annotation type declaration.<br/><code>@interface X { ... }</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class AnnotationDeclaration extends TypeDeclaration<AnnotationDeclaration> implements NodeWithAbstractModifier<AnnotationDeclaration>, Resolvable<ResolvedAnnotationDeclaration> {
+
+    public AnnotationDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new SimpleName(), new NodeList<>());
+    }
+
+    public AnnotationDeclaration(EnumSet<Modifier> modifiers, String name) {
+        this(null, modifiers, new NodeList<>(), new SimpleName(name), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public AnnotationDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<BodyDeclaration<?>> members) {
+        this(null, modifiers, annotations, name, members);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public AnnotationDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<BodyDeclaration<?>> members) {
+        super(tokenRange, modifiers, annotations, name, members);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public AnnotationDeclaration clone() {
+        return (AnnotationDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public AnnotationDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.annotationDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAnnotationDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AnnotationDeclaration asAnnotationDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAnnotationDeclaration(Consumer<AnnotationDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedAnnotationDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedAnnotationDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AnnotationDeclaration> toAnnotationDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java
new file mode 100644
index 0000000..48b6db6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.AnnotationMemberDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedAnnotationMemberDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import javax.annotation.Generated;
+import java.util.EnumSet;
+import java.util.Optional;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * The "int id();" in <code>@interface X { int id(); }</code>
+ * <p>
+ * <br/>All annotations preceding the type will be set on this object, not on the type. JavaParser doesn't know if it
+ * they are applicable to the method or the type.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class AnnotationMemberDeclaration extends BodyDeclaration<AnnotationMemberDeclaration> implements NodeWithJavadoc<AnnotationMemberDeclaration>, NodeWithSimpleName<AnnotationMemberDeclaration>, NodeWithType<AnnotationMemberDeclaration, Type>, NodeWithPublicModifier<AnnotationMemberDeclaration>, NodeWithAbstractModifier<AnnotationMemberDeclaration>, Resolvable<ResolvedAnnotationMemberDeclaration> {
+
+    private EnumSet<Modifier> modifiers;
+
+    private Type type;
+
+    private SimpleName name;
+
+    @OptionalProperty
+    private Expression defaultValue;
+
+    public AnnotationMemberDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new ClassOrInterfaceType(), new SimpleName(), null);
+    }
+
+    public AnnotationMemberDeclaration(EnumSet<Modifier> modifiers, Type type, String name, Expression defaultValue) {
+        this(null, modifiers, new NodeList<>(), type, new SimpleName(name), defaultValue);
+    }
+
+    @AllFieldsConstructor
+    public AnnotationMemberDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, Type type, SimpleName name, Expression defaultValue) {
+        this(null, modifiers, annotations, type, name, defaultValue);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public AnnotationMemberDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, Type type, SimpleName name, Expression defaultValue) {
+        super(tokenRange, annotations);
+        setModifiers(modifiers);
+        setType(type);
+        setName(name);
+        setDefaultValue(defaultValue);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getDefaultValue() {
+        return Optional.ofNullable(defaultValue);
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     *
+     * @return modifiers
+     * @see Modifier
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public AnnotationMemberDeclaration removeDefaultValue() {
+        return setDefaultValue((Expression) null);
+    }
+
+    /**
+     * Sets the default value
+     *
+     * @param defaultValue the default value, can be null
+     * @return this, the AnnotationMemberDeclaration
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AnnotationMemberDeclaration setDefaultValue(final Expression defaultValue) {
+        if (defaultValue == this.defaultValue) {
+            return (AnnotationMemberDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.DEFAULT_VALUE, this.defaultValue, defaultValue);
+        if (this.defaultValue != null)
+            this.defaultValue.setParentNode(null);
+        this.defaultValue = defaultValue;
+        setAsParentNodeOf(defaultValue);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AnnotationMemberDeclaration setModifiers(final EnumSet<Modifier> modifiers) {
+        assertNotNull(modifiers);
+        if (modifiers == this.modifiers) {
+            return (AnnotationMemberDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers);
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AnnotationMemberDeclaration setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (AnnotationMemberDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AnnotationMemberDeclaration setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (AnnotationMemberDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (defaultValue != null) {
+            if (node == defaultValue) {
+                removeDefaultValue();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public AnnotationMemberDeclaration clone() {
+        return (AnnotationMemberDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public AnnotationMemberDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.annotationMemberDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (defaultValue != null) {
+            if (node == defaultValue) {
+                setDefaultValue((Expression) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAnnotationMemberDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AnnotationMemberDeclaration asAnnotationMemberDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAnnotationMemberDeclaration(Consumer<AnnotationMemberDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedAnnotationMemberDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedAnnotationMemberDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AnnotationMemberDeclaration> toAnnotationMemberDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/BodyDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/BodyDeclaration.java
new file mode 100644
index 0000000..dc871e3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/BodyDeclaration.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.BodyDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import java.util.Optional;
+
+/**
+ * Any declaration that can appear between the { and } of a class, interface, or enum.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class BodyDeclaration<T extends BodyDeclaration<?>> extends Node implements NodeWithAnnotations<T> {
+
+    private NodeList<AnnotationExpr> annotations;
+
+    public BodyDeclaration() {
+        this(null, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public BodyDeclaration(NodeList<AnnotationExpr> annotations) {
+        this(null, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public BodyDeclaration(TokenRange tokenRange, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange);
+        setAnnotations(annotations);
+        customInitialization();
+    }
+
+    protected BodyDeclaration(TokenRange range) {
+        this(range, new NodeList<>());
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return (T) this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public BodyDeclaration<?> clone() {
+        return (BodyDeclaration<?>) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public BodyDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.bodyDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAnnotationDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AnnotationDeclaration asAnnotationDeclaration() {
+        throw new IllegalStateException(f("%s is not an AnnotationDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAnnotationMemberDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AnnotationMemberDeclaration asAnnotationMemberDeclaration() {
+        throw new IllegalStateException(f("%s is not an AnnotationMemberDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isCallableDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public CallableDeclaration asCallableDeclaration() {
+        throw new IllegalStateException(f("%s is not an CallableDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isClassOrInterfaceDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ClassOrInterfaceDeclaration asClassOrInterfaceDeclaration() {
+        throw new IllegalStateException(f("%s is not an ClassOrInterfaceDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isConstructorDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ConstructorDeclaration asConstructorDeclaration() {
+        throw new IllegalStateException(f("%s is not an ConstructorDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEnumConstantDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EnumConstantDeclaration asEnumConstantDeclaration() {
+        throw new IllegalStateException(f("%s is not an EnumConstantDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEnumDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EnumDeclaration asEnumDeclaration() {
+        throw new IllegalStateException(f("%s is not an EnumDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isFieldDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public FieldDeclaration asFieldDeclaration() {
+        throw new IllegalStateException(f("%s is not an FieldDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isInitializerDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public InitializerDeclaration asInitializerDeclaration() {
+        throw new IllegalStateException(f("%s is not an InitializerDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMethodDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MethodDeclaration asMethodDeclaration() {
+        throw new IllegalStateException(f("%s is not an MethodDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTypeDeclaration() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TypeDeclaration asTypeDeclaration() {
+        throw new IllegalStateException(f("%s is not an TypeDeclaration", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAnnotationDeclaration(Consumer<AnnotationDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAnnotationMemberDeclaration(Consumer<AnnotationMemberDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifCallableDeclaration(Consumer<CallableDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifClassOrInterfaceDeclaration(Consumer<ClassOrInterfaceDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifConstructorDeclaration(Consumer<ConstructorDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEnumConstantDeclaration(Consumer<EnumConstantDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEnumDeclaration(Consumer<EnumDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifFieldDeclaration(Consumer<FieldDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifInitializerDeclaration(Consumer<InitializerDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMethodDeclaration(Consumer<MethodDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTypeDeclaration(Consumer<TypeDeclaration> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AnnotationDeclaration> toAnnotationDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AnnotationMemberDeclaration> toAnnotationMemberDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<CallableDeclaration> toCallableDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ClassOrInterfaceDeclaration> toClassOrInterfaceDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ConstructorDeclaration> toConstructorDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EnumConstantDeclaration> toEnumConstantDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EnumDeclaration> toEnumDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<FieldDeclaration> toFieldDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<InitializerDeclaration> toInitializerDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MethodDeclaration> toMethodDeclaration() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TypeDeclaration> toTypeDeclaration() {
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/CallableDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/CallableDeclaration.java
new file mode 100644
index 0000000..e2e41fe
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/CallableDeclaration.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.nodeTypes.modifiers.*;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.CallableDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.OptionalProperty;
+import javax.annotation.Generated;
+import java.util.EnumSet;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * Represents a declaration which is callable eg. a method or a constructor.
+ */
+public abstract class CallableDeclaration<T extends CallableDeclaration<?>> extends BodyDeclaration<T> implements NodeWithAccessModifiers<T>, NodeWithDeclaration, NodeWithSimpleName<T>, NodeWithParameters<T>, NodeWithThrownExceptions<T>, NodeWithTypeParameters<T>, NodeWithJavadoc<T>, NodeWithAbstractModifier<T>, NodeWithStaticModifier<T>, NodeWithFinalModifier<T>, NodeWithStrictfpModifier<T> {
+
+    private EnumSet<Modifier> modifiers;
+
+    private NodeList<TypeParameter> typeParameters;
+
+    private SimpleName name;
+
+    private NodeList<Parameter> parameters;
+
+    private NodeList<ReferenceType> thrownExceptions;
+
+    @OptionalProperty
+    private ReceiverParameter receiverParameter;
+
+    @AllFieldsConstructor
+    CallableDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<TypeParameter> typeParameters, SimpleName name, NodeList<Parameter> parameters, NodeList<ReferenceType> thrownExceptions, ReceiverParameter receiverParameter) {
+        this(null, modifiers, annotations, typeParameters, name, parameters, thrownExceptions, receiverParameter);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public CallableDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<TypeParameter> typeParameters, SimpleName name, NodeList<Parameter> parameters, NodeList<ReferenceType> thrownExceptions, ReceiverParameter receiverParameter) {
+        super(tokenRange, annotations);
+        setModifiers(modifiers);
+        setTypeParameters(typeParameters);
+        setName(name);
+        setParameters(parameters);
+        setThrownExceptions(thrownExceptions);
+        setReceiverParameter(receiverParameter);
+        customInitialization();
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     *
+     * @return modifiers
+     * @see Modifier
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setModifiers(final EnumSet<Modifier> modifiers) {
+        assertNotNull(modifiers);
+        if (modifiers == this.modifiers) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers);
+        this.modifiers = modifiers;
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Parameter> getParameters() {
+        return parameters;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setParameters(final NodeList<Parameter> parameters) {
+        assertNotNull(parameters);
+        if (parameters == this.parameters) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.PARAMETERS, this.parameters, parameters);
+        if (this.parameters != null)
+            this.parameters.setParentNode(null);
+        this.parameters = parameters;
+        setAsParentNodeOf(parameters);
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ReferenceType> getThrownExceptions() {
+        return thrownExceptions;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setThrownExceptions(final NodeList<ReferenceType> thrownExceptions) {
+        assertNotNull(thrownExceptions);
+        if (thrownExceptions == this.thrownExceptions) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.THROWN_EXCEPTIONS, this.thrownExceptions, thrownExceptions);
+        if (this.thrownExceptions != null)
+            this.thrownExceptions.setParentNode(null);
+        this.thrownExceptions = thrownExceptions;
+        setAsParentNodeOf(thrownExceptions);
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<TypeParameter> getTypeParameters() {
+        return typeParameters;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setTypeParameters(final NodeList<TypeParameter> typeParameters) {
+        assertNotNull(typeParameters);
+        if (typeParameters == this.typeParameters) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_PARAMETERS, this.typeParameters, typeParameters);
+        if (this.typeParameters != null)
+            this.typeParameters.setParentNode(null);
+        this.typeParameters = typeParameters;
+        setAsParentNodeOf(typeParameters);
+        return (T) this;
+    }
+
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows) {
+        return getDeclarationAsString(includingModifiers, includingThrows, true);
+    }
+
+    public String getDeclarationAsString() {
+        return getDeclarationAsString(true, true, true);
+    }
+
+    public abstract String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName);
+
+    protected String appendThrowsIfRequested(boolean includingThrows) {
+        StringBuilder sb = new StringBuilder();
+        if (includingThrows) {
+            boolean firstThrow = true;
+            for (ReferenceType thr : getThrownExceptions()) {
+                if (firstThrow) {
+                    firstThrow = false;
+                    sb.append(" throws ");
+                } else {
+                    sb.append(", ");
+                }
+                sb.append(thr.toString(prettyPrinterNoCommentsConfiguration));
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < parameters.size(); i++) {
+            if (parameters.get(i) == node) {
+                parameters.remove(i);
+                return true;
+            }
+        }
+        if (receiverParameter != null) {
+            if (node == receiverParameter) {
+                removeReceiverParameter();
+                return true;
+            }
+        }
+        for (int i = 0; i < thrownExceptions.size(); i++) {
+            if (thrownExceptions.get(i) == node) {
+                thrownExceptions.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < typeParameters.size(); i++) {
+            if (typeParameters.get(i) == node) {
+                typeParameters.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    /**
+     * A method or constructor signature.
+     * <p/>Note that since JavaParser has no real knowledge of types - only the text found in the source file - using
+     * this will fail in some cases. (java.util.String != String for example, and generics are not taken into account.)
+     */
+    public static class Signature {
+
+        private final String name;
+
+        private final List<Type> parameterTypes;
+
+        private Signature(String name, List<Type> parameterTypes) {
+            this.name = name;
+            this.parameterTypes = parameterTypes;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public List<Type> getParameterTypes() {
+            return parameterTypes;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o)
+                return true;
+            if (o == null || getClass() != o.getClass())
+                return false;
+            Signature signature = (Signature) o;
+            if (!name.equals(signature.name))
+                return false;
+            if (!parameterTypes.equals(signature.parameterTypes))
+                return false;
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = name.hashCode();
+            result = 31 * result + parameterTypes.hashCode();
+            return result;
+        }
+
+        public String asString() {
+            return parameterTypes.stream().map(Type::asString).collect(joining(", ", name + "(", ")"));
+        }
+
+        @Override
+        public String toString() {
+            return asString();
+        }
+    }
+
+    public Signature getSignature() {
+        return new Signature(getName().getIdentifier(), getParameters().stream().map(this::getTypeWithVarargsAsArray).map(this::stripGenerics).map(this::stripAnnotations).collect(toList()));
+    }
+
+    private Type stripAnnotations(Type type) {
+        if (type instanceof NodeWithAnnotations) {
+            ((NodeWithAnnotations) type).setAnnotations(new NodeList<>());
+        }
+        return type;
+    }
+
+    private Type stripGenerics(Type type) {
+        if (type instanceof NodeWithTypeArguments) {
+            ((NodeWithTypeArguments) type).setTypeArguments((NodeList<Type>) null);
+        }
+        return type;
+    }
+
+    private Type getTypeWithVarargsAsArray(Parameter p) {
+        /* A signature includes the varargs ellipsis.
+         This is a field on parameter which we lose when we only get the type,
+         so we represent it as an additional [] on the type. */
+        Type t = p.getType().clone();
+        if (p.isVarArgs()) {
+            t = new ArrayType(t);
+        }
+        return t;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public CallableDeclaration<?> clone() {
+        return (CallableDeclaration<?>) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public CallableDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.callableDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        for (int i = 0; i < parameters.size(); i++) {
+            if (parameters.get(i) == node) {
+                parameters.set(i, (Parameter) replacementNode);
+                return true;
+            }
+        }
+        if (receiverParameter != null) {
+            if (node == receiverParameter) {
+                setReceiverParameter((ReceiverParameter) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < thrownExceptions.size(); i++) {
+            if (thrownExceptions.get(i) == node) {
+                thrownExceptions.set(i, (ReferenceType) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < typeParameters.size(); i++) {
+            if (typeParameters.get(i) == node) {
+                typeParameters.set(i, (TypeParameter) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isCallableDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public CallableDeclaration asCallableDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifCallableDeclaration(Consumer<CallableDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<ReceiverParameter> getReceiverParameter() {
+        return Optional.ofNullable(receiverParameter);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setReceiverParameter(final ReceiverParameter receiverParameter) {
+        if (receiverParameter == this.receiverParameter) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.RECEIVER_PARAMETER, this.receiverParameter, receiverParameter);
+        if (this.receiverParameter != null)
+            this.receiverParameter.setParentNode(null);
+        this.receiverParameter = receiverParameter;
+        setAsParentNodeOf(receiverParameter);
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public CallableDeclaration removeReceiverParameter() {
+        return setReceiverParameter((ReceiverParameter) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<CallableDeclaration> toCallableDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java
new file mode 100644
index 0000000..a275066
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithConstructors;
+import com.github.javaparser.ast.nodeTypes.NodeWithExtends;
+import com.github.javaparser.ast.nodeTypes.NodeWithImplements;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.LocalClassDeclarationStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.ClassOrInterfaceDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedAnnotationDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import javax.annotation.Generated;
+import java.util.EnumSet;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A definition of a class or interface.<br/><code>class X { ... }</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassOrInterfaceDeclaration extends TypeDeclaration<ClassOrInterfaceDeclaration> implements NodeWithImplements<ClassOrInterfaceDeclaration>, NodeWithExtends<ClassOrInterfaceDeclaration>, NodeWithTypeParameters<ClassOrInterfaceDeclaration>, NodeWithAbstractModifier<ClassOrInterfaceDeclaration>, NodeWithFinalModifier<ClassOrInterfaceDeclaration>, NodeWithConstructors<ClassOrInterfaceDeclaration>, Resolvable<ResolvedReferenceTypeDeclaration> {
+
+    private boolean isInterface;
+
+    private NodeList<TypeParameter> typeParameters;
+
+    // Can contain more than one item if this is an interface
+    private NodeList<ClassOrInterfaceType> extendedTypes;
+
+    private NodeList<ClassOrInterfaceType> implementedTypes;
+
+    public ClassOrInterfaceDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), false, new SimpleName(), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>());
+    }
+
+    public ClassOrInterfaceDeclaration(final EnumSet<Modifier> modifiers, final boolean isInterface, final String name) {
+        this(null, modifiers, new NodeList<>(), isInterface, new SimpleName(name), new NodeList<>(), new NodeList<>(), new NodeList<>(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ClassOrInterfaceDeclaration(final EnumSet<Modifier> modifiers, final NodeList<AnnotationExpr> annotations, final boolean isInterface, final SimpleName name, final NodeList<TypeParameter> typeParameters, final NodeList<ClassOrInterfaceType> extendedTypes, final NodeList<ClassOrInterfaceType> implementedTypes, final NodeList<BodyDeclaration<?>> members) {
+        this(null, modifiers, annotations, isInterface, name, typeParameters, extendedTypes, implementedTypes, members);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ClassOrInterfaceDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, boolean isInterface, SimpleName name, NodeList<TypeParameter> typeParameters, NodeList<ClassOrInterfaceType> extendedTypes, NodeList<ClassOrInterfaceType> implementedTypes, NodeList<BodyDeclaration<?>> members) {
+        super(tokenRange, modifiers, annotations, name, members);
+        setInterface(isInterface);
+        setTypeParameters(typeParameters);
+        setExtendedTypes(extendedTypes);
+        setImplementedTypes(implementedTypes);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ClassOrInterfaceType> getExtendedTypes() {
+        return extendedTypes;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ClassOrInterfaceType> getImplementedTypes() {
+        return implementedTypes;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<TypeParameter> getTypeParameters() {
+        return typeParameters;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isInterface() {
+        return isInterface;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceDeclaration setExtendedTypes(final NodeList<ClassOrInterfaceType> extendedTypes) {
+        assertNotNull(extendedTypes);
+        if (extendedTypes == this.extendedTypes) {
+            return (ClassOrInterfaceDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXTENDED_TYPES, this.extendedTypes, extendedTypes);
+        if (this.extendedTypes != null)
+            this.extendedTypes.setParentNode(null);
+        this.extendedTypes = extendedTypes;
+        setAsParentNodeOf(extendedTypes);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceDeclaration setImplementedTypes(final NodeList<ClassOrInterfaceType> implementedTypes) {
+        assertNotNull(implementedTypes);
+        if (implementedTypes == this.implementedTypes) {
+            return (ClassOrInterfaceDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.IMPLEMENTED_TYPES, this.implementedTypes, implementedTypes);
+        if (this.implementedTypes != null)
+            this.implementedTypes.setParentNode(null);
+        this.implementedTypes = implementedTypes;
+        setAsParentNodeOf(implementedTypes);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceDeclaration setInterface(final boolean isInterface) {
+        if (isInterface == this.isInterface) {
+            return (ClassOrInterfaceDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.INTERFACE, this.isInterface, isInterface);
+        this.isInterface = isInterface;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceDeclaration setTypeParameters(final NodeList<TypeParameter> typeParameters) {
+        assertNotNull(typeParameters);
+        if (typeParameters == this.typeParameters) {
+            return (ClassOrInterfaceDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_PARAMETERS, this.typeParameters, typeParameters);
+        if (this.typeParameters != null)
+            this.typeParameters.setParentNode(null);
+        this.typeParameters = typeParameters;
+        setAsParentNodeOf(typeParameters);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < extendedTypes.size(); i++) {
+            if (extendedTypes.get(i) == node) {
+                extendedTypes.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < implementedTypes.size(); i++) {
+            if (implementedTypes.get(i) == node) {
+                implementedTypes.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < typeParameters.size(); i++) {
+            if (typeParameters.get(i) == node) {
+                typeParameters.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    /**
+     * @return is this class's parent a LocalClassDeclarationStmt ?
+     */
+    public boolean isLocalClassDeclaration() {
+        return getParentNode().map(p -> p instanceof LocalClassDeclarationStmt).orElse(false);
+    }
+
+    /**
+     * @return is this an inner class?
+     * NOTE: many people are confused over terminology. Refer to https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html .
+     */
+    public boolean isInnerClass() {
+        return isNestedType() && !isInterface && !isStatic();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ClassOrInterfaceDeclaration clone() {
+        return (ClassOrInterfaceDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ClassOrInterfaceDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.classOrInterfaceDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < extendedTypes.size(); i++) {
+            if (extendedTypes.get(i) == node) {
+                extendedTypes.set(i, (ClassOrInterfaceType) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < implementedTypes.size(); i++) {
+            if (implementedTypes.get(i) == node) {
+                implementedTypes.set(i, (ClassOrInterfaceType) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < typeParameters.size(); i++) {
+            if (typeParameters.get(i) == node) {
+                typeParameters.set(i, (TypeParameter) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isClassOrInterfaceDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ClassOrInterfaceDeclaration asClassOrInterfaceDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifClassOrInterfaceDeclaration(Consumer<ClassOrInterfaceDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedReferenceTypeDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ClassOrInterfaceDeclaration> toClassOrInterfaceDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/ConstructorDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ConstructorDeclaration.java
new file mode 100644
index 0000000..ab1dad9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ConstructorDeclaration.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.EnumSet;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ConstructorDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A constructor declaration: <code>class X { X() { } }</code> where X(){} is the constructor declaration.
+ *
+ * <br/>All annotations preceding the name will be set on this object, not on the class.
+ * JavaParser doesn't know if it they are applicable to the method or the class.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ConstructorDeclaration extends CallableDeclaration<ConstructorDeclaration> implements NodeWithBlockStmt<ConstructorDeclaration>, NodeWithAccessModifiers<ConstructorDeclaration>, NodeWithJavadoc<ConstructorDeclaration>, NodeWithSimpleName<ConstructorDeclaration>, NodeWithParameters<ConstructorDeclaration>, NodeWithThrownExceptions<ConstructorDeclaration>, NodeWithTypeParameters<ConstructorDeclaration>, Resolvable<ResolvedConstructorDeclaration> {
+
+    private BlockStmt body;
+
+    public ConstructorDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new NodeList<>(), new SimpleName(), new NodeList<>(), new NodeList<>(), new BlockStmt(), null);
+    }
+
+    public ConstructorDeclaration(String name) {
+        this(null, EnumSet.of(Modifier.PUBLIC), new NodeList<>(), new NodeList<>(), new SimpleName(name), new NodeList<>(), new NodeList<>(), new BlockStmt(), null);
+    }
+
+    public ConstructorDeclaration(EnumSet<Modifier> modifiers, String name) {
+        this(null, modifiers, new NodeList<>(), new NodeList<>(), new SimpleName(name), new NodeList<>(), new NodeList<>(), new BlockStmt(), null);
+    }
+
+    public ConstructorDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<TypeParameter> typeParameters, SimpleName name, NodeList<Parameter> parameters, NodeList<ReferenceType> thrownExceptions, BlockStmt body) {
+        this(null, modifiers, annotations, typeParameters, name, parameters, thrownExceptions, body, null);
+    }
+
+    @AllFieldsConstructor
+    public ConstructorDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<TypeParameter> typeParameters, SimpleName name, NodeList<Parameter> parameters, NodeList<ReferenceType> thrownExceptions, BlockStmt body, ReceiverParameter receiverParameter) {
+        this(null, modifiers, annotations, typeParameters, name, parameters, thrownExceptions, body, receiverParameter);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ConstructorDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<TypeParameter> typeParameters, SimpleName name, NodeList<Parameter> parameters, NodeList<ReferenceType> thrownExceptions, BlockStmt body, ReceiverParameter receiverParameter) {
+        super(tokenRange, modifiers, annotations, typeParameters, name, parameters, thrownExceptions, receiverParameter);
+        setBody(body);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BlockStmt getBody() {
+        return body;
+    }
+
+    /**
+     * Sets the body
+     *
+     * @param body the body, can not be null
+     * @return this, the ConstructorDeclaration
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ConstructorDeclaration setBody(final BlockStmt body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (ConstructorDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Override
+    public ConstructorDeclaration setModifiers(final EnumSet<Modifier> modifiers) {
+        return super.setModifiers(modifiers);
+    }
+
+    @Override
+    public ConstructorDeclaration setName(final SimpleName name) {
+        return super.setName(name);
+    }
+
+    @Override
+    public ConstructorDeclaration setParameters(final NodeList<Parameter> parameters) {
+        return super.setParameters(parameters);
+    }
+
+    @Override
+    public ConstructorDeclaration setThrownExceptions(final NodeList<ReferenceType> thrownExceptions) {
+        return super.setThrownExceptions(thrownExceptions);
+    }
+
+    @Override
+    public ConstructorDeclaration setTypeParameters(final NodeList<TypeParameter> typeParameters) {
+        return super.setTypeParameters(typeParameters);
+    }
+
+    /**
+     * The declaration returned has this schema:
+     * <p>
+     * [accessSpecifier] className ([paramType [paramName]])
+     * [throws exceptionsList]
+     */
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName) {
+        StringBuilder sb = new StringBuilder();
+        if (includingModifiers) {
+            AccessSpecifier accessSpecifier = Modifier.getAccessSpecifier(getModifiers());
+            sb.append(accessSpecifier.asString());
+            sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ");
+        }
+        sb.append(getName());
+        sb.append("(");
+        boolean firstParam = true;
+        for (Parameter param : getParameters()) {
+            if (firstParam) {
+                firstParam = false;
+            } else {
+                sb.append(", ");
+            }
+            if (includingParameterName) {
+                sb.append(param.toString(prettyPrinterNoCommentsConfiguration));
+            } else {
+                sb.append(param.getType().toString(prettyPrinterNoCommentsConfiguration));
+            }
+        }
+        sb.append(")");
+        sb.append(appendThrowsIfRequested(includingThrows));
+        return sb.toString();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ConstructorDeclaration clone() {
+        return (ConstructorDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ConstructorDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.constructorDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((BlockStmt) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isConstructorDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ConstructorDeclaration asConstructorDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifConstructorDeclaration(Consumer<ConstructorDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedConstructorDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedConstructorDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ConstructorDeclaration> toConstructorDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/EnumConstantDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/EnumConstantDeclaration.java
new file mode 100644
index 0000000..5a331e4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/EnumConstantDeclaration.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.EnumConstantDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * One of the values an enum can take. A(1) and B(2) in this example: <code>enum X { A(1), B(2) }</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class EnumConstantDeclaration extends BodyDeclaration<EnumConstantDeclaration> implements NodeWithJavadoc<EnumConstantDeclaration>, NodeWithSimpleName<EnumConstantDeclaration>, NodeWithArguments<EnumConstantDeclaration>, Resolvable<ResolvedEnumConstantDeclaration> {
+
+    private SimpleName name;
+
+    private NodeList<Expression> arguments;
+
+    private NodeList<BodyDeclaration<?>> classBody;
+
+    public EnumConstantDeclaration() {
+        this(null, new NodeList<>(), new SimpleName(), new NodeList<>(), new NodeList<>());
+    }
+
+    public EnumConstantDeclaration(String name) {
+        this(null, new NodeList<>(), new SimpleName(name), new NodeList<>(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public EnumConstantDeclaration(NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<Expression> arguments, NodeList<BodyDeclaration<?>> classBody) {
+        this(null, annotations, name, arguments, classBody);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public EnumConstantDeclaration(TokenRange tokenRange, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<Expression> arguments, NodeList<BodyDeclaration<?>> classBody) {
+        super(tokenRange, annotations);
+        setName(name);
+        setArguments(arguments);
+        setClassBody(classBody);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getArguments() {
+        return arguments;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<BodyDeclaration<?>> getClassBody() {
+        return classBody;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumConstantDeclaration setArguments(final NodeList<Expression> arguments) {
+        assertNotNull(arguments);
+        if (arguments == this.arguments) {
+            return (EnumConstantDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.ARGUMENTS, this.arguments, arguments);
+        if (this.arguments != null)
+            this.arguments.setParentNode(null);
+        this.arguments = arguments;
+        setAsParentNodeOf(arguments);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumConstantDeclaration setClassBody(final NodeList<BodyDeclaration<?>> classBody) {
+        assertNotNull(classBody);
+        if (classBody == this.classBody) {
+            return (EnumConstantDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.CLASS_BODY, this.classBody, classBody);
+        if (this.classBody != null)
+            this.classBody.setParentNode(null);
+        this.classBody = classBody;
+        setAsParentNodeOf(classBody);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumConstantDeclaration setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (EnumConstantDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < classBody.size(); i++) {
+            if (classBody.get(i) == node) {
+                classBody.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public EnumConstantDeclaration clone() {
+        return (EnumConstantDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public EnumConstantDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.enumConstantDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < classBody.size(); i++) {
+            if (classBody.get(i) == node) {
+                classBody.set(i, (BodyDeclaration) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEnumConstantDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EnumConstantDeclaration asEnumConstantDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEnumConstantDeclaration(Consumer<EnumConstantDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedEnumConstantDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedEnumConstantDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EnumConstantDeclaration> toEnumConstantDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/EnumDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/EnumDeclaration.java
new file mode 100644
index 0000000..44fb1e4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/EnumDeclaration.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithConstructors;
+import com.github.javaparser.ast.nodeTypes.NodeWithImplements;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.EnumDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedEnumDeclaration;
+import javax.annotation.Generated;
+import java.util.EnumSet;
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * The declaration of an enum.<br/><code>enum X { ... }</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class EnumDeclaration extends TypeDeclaration<EnumDeclaration> implements NodeWithImplements<EnumDeclaration>, NodeWithConstructors<EnumDeclaration>, Resolvable<ResolvedEnumDeclaration> {
+
+    private NodeList<ClassOrInterfaceType> implementedTypes;
+
+    private NodeList<EnumConstantDeclaration> entries;
+
+    public EnumDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new SimpleName(), new NodeList<>(), new NodeList<>(), new NodeList<>());
+    }
+
+    public EnumDeclaration(EnumSet<Modifier> modifiers, String name) {
+        this(null, modifiers, new NodeList<>(), new SimpleName(name), new NodeList<>(), new NodeList<>(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public EnumDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<ClassOrInterfaceType> implementedTypes, NodeList<EnumConstantDeclaration> entries, NodeList<BodyDeclaration<?>> members) {
+        this(null, modifiers, annotations, name, implementedTypes, entries, members);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public EnumDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<ClassOrInterfaceType> implementedTypes, NodeList<EnumConstantDeclaration> entries, NodeList<BodyDeclaration<?>> members) {
+        super(tokenRange, modifiers, annotations, name, members);
+        setImplementedTypes(implementedTypes);
+        setEntries(entries);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<EnumConstantDeclaration> getEntries() {
+        return entries;
+    }
+
+    public EnumConstantDeclaration getEntry(int i) {
+        return getEntries().get(i);
+    }
+
+    public EnumDeclaration setEntry(int i, EnumConstantDeclaration element) {
+        getEntries().set(i, element);
+        return this;
+    }
+
+    public EnumDeclaration addEntry(EnumConstantDeclaration element) {
+        getEntries().add(element);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ClassOrInterfaceType> getImplementedTypes() {
+        return implementedTypes;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumDeclaration setEntries(final NodeList<EnumConstantDeclaration> entries) {
+        assertNotNull(entries);
+        if (entries == this.entries) {
+            return (EnumDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.ENTRIES, this.entries, entries);
+        if (this.entries != null)
+            this.entries.setParentNode(null);
+        this.entries = entries;
+        setAsParentNodeOf(entries);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumDeclaration setImplementedTypes(final NodeList<ClassOrInterfaceType> implementedTypes) {
+        assertNotNull(implementedTypes);
+        if (implementedTypes == this.implementedTypes) {
+            return (EnumDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.IMPLEMENTED_TYPES, this.implementedTypes, implementedTypes);
+        if (this.implementedTypes != null)
+            this.implementedTypes.setParentNode(null);
+        this.implementedTypes = implementedTypes;
+        setAsParentNodeOf(implementedTypes);
+        return this;
+    }
+
+    public EnumConstantDeclaration addEnumConstant(String name) {
+        assertNonEmpty(name);
+        EnumConstantDeclaration enumConstant = new EnumConstantDeclaration(name);
+        getEntries().add(enumConstant);
+        return enumConstant;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < entries.size(); i++) {
+            if (entries.get(i) == node) {
+                entries.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < implementedTypes.size(); i++) {
+            if (implementedTypes.get(i) == node) {
+                implementedTypes.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public EnumDeclaration clone() {
+        return (EnumDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public EnumDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.enumDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < entries.size(); i++) {
+            if (entries.get(i) == node) {
+                entries.set(i, (EnumConstantDeclaration) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < implementedTypes.size(); i++) {
+            if (implementedTypes.get(i) == node) {
+                implementedTypes.set(i, (ClassOrInterfaceType) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEnumDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EnumDeclaration asEnumDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEnumDeclaration(Consumer<EnumDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedEnumDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedEnumDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EnumDeclaration> toEnumDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/FieldDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/FieldDeclaration.java
new file mode 100644
index 0000000..547e95a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/FieldDeclaration.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.AssignExpr.Operator;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.VoidType;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.FieldDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.ast.Modifier.*;
+import static com.github.javaparser.ast.NodeList.nodeList;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import java.util.function.Consumer;
+
+/**
+ * The declaration of a field in a class. "private static int a=15*15;" in this example: <code>class X { private static
+ * int a=15*15; }</code>
+ *
+ * <br/>All annotations preceding the type will be set on this object, not on the type.
+ * JavaParser doesn't know if it they are applicable to the method or the type.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class FieldDeclaration extends BodyDeclaration<FieldDeclaration> implements NodeWithJavadoc<FieldDeclaration>, NodeWithVariables<FieldDeclaration>, NodeWithAccessModifiers<FieldDeclaration>, NodeWithStaticModifier<FieldDeclaration>, NodeWithFinalModifier<FieldDeclaration>, Resolvable<ResolvedFieldDeclaration> {
+
+    private EnumSet<Modifier> modifiers;
+
+    @NonEmptyProperty
+    private NodeList<VariableDeclarator> variables;
+
+    public FieldDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new NodeList<>());
+    }
+
+    public FieldDeclaration(EnumSet<Modifier> modifiers, VariableDeclarator variable) {
+        this(null, modifiers, new NodeList<>(), nodeList(variable));
+    }
+
+    public FieldDeclaration(EnumSet<Modifier> modifiers, NodeList<VariableDeclarator> variables) {
+        this(null, modifiers, new NodeList<>(), variables);
+    }
+
+    @AllFieldsConstructor
+    public FieldDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<VariableDeclarator> variables) {
+        this(null, modifiers, annotations, variables);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public FieldDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<VariableDeclarator> variables) {
+        super(tokenRange, annotations);
+        setModifiers(modifiers);
+        setVariables(variables);
+        customInitialization();
+    }
+
+    /**
+     * Creates a {@link FieldDeclaration}.
+     *
+     * @param modifiers modifiers
+     * @param type type
+     * @param name field name
+     */
+    public FieldDeclaration(EnumSet<Modifier> modifiers, Type type, String name) {
+        this(assertNotNull(modifiers), new VariableDeclarator(type, assertNotNull(name)));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     *
+     * @return modifiers
+     * @see Modifier
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<VariableDeclarator> getVariables() {
+        return variables;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public FieldDeclaration setModifiers(final EnumSet<Modifier> modifiers) {
+        assertNotNull(modifiers);
+        if (modifiers == this.modifiers) {
+            return (FieldDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers);
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public FieldDeclaration setVariables(final NodeList<VariableDeclarator> variables) {
+        assertNotNull(variables);
+        if (variables == this.variables) {
+            return (FieldDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.VARIABLES, this.variables, variables);
+        if (this.variables != null)
+            this.variables.setParentNode(null);
+        this.variables = variables;
+        setAsParentNodeOf(variables);
+        return this;
+    }
+
+    /**
+     * Create a getter for this field, <b>will only work if this field declares only 1 identifier and if this field is
+     * already added to a ClassOrInterfaceDeclaration</b>
+     *
+     * @return the {@link MethodDeclaration} created
+     * @throws IllegalStateException if there is more than 1 variable identifier or if this field isn't attached to a
+     * class or enum
+     */
+    public MethodDeclaration createGetter() {
+        if (getVariables().size() != 1)
+            throw new IllegalStateException("You can use this only when the field declares only 1 variable name");
+        Optional<ClassOrInterfaceDeclaration> parentClass = getAncestorOfType(ClassOrInterfaceDeclaration.class);
+        Optional<EnumDeclaration> parentEnum = getAncestorOfType(EnumDeclaration.class);
+        if (!(parentClass.isPresent() || parentEnum.isPresent()) || (parentClass.isPresent() && parentClass.get().isInterface()))
+            throw new IllegalStateException("You can use this only when the field is attached to a class or an enum");
+        VariableDeclarator variable = getVariable(0);
+        String fieldName = variable.getNameAsString();
+        String fieldNameUpper = fieldName.toUpperCase().substring(0, 1) + fieldName.substring(1, fieldName.length());
+        final MethodDeclaration getter;
+        getter = parentClass.map(clazz -> clazz.addMethod("get" + fieldNameUpper, PUBLIC)).orElseGet(() -> parentEnum.get().addMethod("get" + fieldNameUpper, PUBLIC));
+        getter.setType(variable.getType());
+        BlockStmt blockStmt = new BlockStmt();
+        getter.setBody(blockStmt);
+        blockStmt.addStatement(new ReturnStmt(fieldName));
+        return getter;
+    }
+
+    /**
+     * Create a setter for this field, <b>will only work if this field declares only 1 identifier and if this field is
+     * already added to a ClassOrInterfaceDeclaration</b>
+     *
+     * @return the {@link MethodDeclaration} created
+     * @throws IllegalStateException if there is more than 1 variable identifier or if this field isn't attached to a
+     * class or enum
+     */
+    public MethodDeclaration createSetter() {
+        if (getVariables().size() != 1)
+            throw new IllegalStateException("You can use this only when the field declares only 1 variable name");
+        Optional<ClassOrInterfaceDeclaration> parentClass = getAncestorOfType(ClassOrInterfaceDeclaration.class);
+        Optional<EnumDeclaration> parentEnum = getAncestorOfType(EnumDeclaration.class);
+        if (!(parentClass.isPresent() || parentEnum.isPresent()) || (parentClass.isPresent() && parentClass.get().isInterface()))
+            throw new IllegalStateException("You can use this only when the field is attached to a class or an enum");
+        VariableDeclarator variable = getVariable(0);
+        String fieldName = variable.getNameAsString();
+        String fieldNameUpper = fieldName.toUpperCase().substring(0, 1) + fieldName.substring(1, fieldName.length());
+        final MethodDeclaration setter;
+        setter = parentClass.map(clazz -> clazz.addMethod("set" + fieldNameUpper, PUBLIC)).orElseGet(() -> parentEnum.get().addMethod("set" + fieldNameUpper, PUBLIC));
+        setter.setType(new VoidType());
+        setter.getParameters().add(new Parameter(variable.getType(), fieldName));
+        BlockStmt blockStmt2 = new BlockStmt();
+        setter.setBody(blockStmt2);
+        blockStmt2.addStatement(new AssignExpr(new NameExpr("this." + fieldName), new NameExpr(fieldName), Operator.ASSIGN));
+        return setter;
+    }
+
+    public boolean isTransient() {
+        return getModifiers().contains(TRANSIENT);
+    }
+
+    public boolean isVolatile() {
+        return getModifiers().contains(VOLATILE);
+    }
+
+    public FieldDeclaration setTransient(boolean set) {
+        return setModifier(TRANSIENT, set);
+    }
+
+    public FieldDeclaration setVolatile(boolean set) {
+        return setModifier(VOLATILE, set);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < variables.size(); i++) {
+            if (variables.get(i) == node) {
+                variables.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public FieldDeclaration clone() {
+        return (FieldDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public FieldDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.fieldDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < variables.size(); i++) {
+            if (variables.get(i) == node) {
+                variables.set(i, (VariableDeclarator) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isFieldDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public FieldDeclaration asFieldDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifFieldDeclaration(Consumer<FieldDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedFieldDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedFieldDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<FieldDeclaration> toFieldDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/InitializerDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/InitializerDeclaration.java
new file mode 100644
index 0000000..06fe78e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/InitializerDeclaration.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.InitializerDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A (possibly static) initializer body. "static { a=3; }" in this example: <code>class X { static { a=3; }  } </code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class InitializerDeclaration extends BodyDeclaration<InitializerDeclaration> implements NodeWithJavadoc<InitializerDeclaration>, NodeWithBlockStmt<InitializerDeclaration> {
+
+    private boolean isStatic;
+
+    private BlockStmt body;
+
+    public InitializerDeclaration() {
+        this(null, false, new BlockStmt());
+    }
+
+    @AllFieldsConstructor
+    public InitializerDeclaration(boolean isStatic, BlockStmt body) {
+        this(null, isStatic, body);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public InitializerDeclaration(TokenRange tokenRange, boolean isStatic, BlockStmt body) {
+        super(tokenRange);
+        setStatic(isStatic);
+        setBody(body);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BlockStmt getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isStatic() {
+        return isStatic;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public InitializerDeclaration setBody(final BlockStmt body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (InitializerDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public InitializerDeclaration setStatic(final boolean isStatic) {
+        if (isStatic == this.isStatic) {
+            return (InitializerDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.STATIC, this.isStatic, isStatic);
+        this.isStatic = isStatic;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public InitializerDeclaration clone() {
+        return (InitializerDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public InitializerDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.initializerDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((BlockStmt) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isInitializerDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public InitializerDeclaration asInitializerDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifInitializerDeclaration(Consumer<InitializerDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<InitializerDeclaration> toInitializerDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
new file mode 100644
index 0000000..dff4cad
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/MethodDeclaration.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.nodeTypes.modifiers.*;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.EnumSet;
+import java.util.Optional;
+import static com.github.javaparser.ast.Modifier.*;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.MethodDeclarationMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import java.util.function.Consumer;
+
+/**
+ * A method declaration. "public int abc() {return 1;}" in this example: <code>class X { public int abc() {return 1;}
+ * }</code>
+ *
+ * <br/>All annotations preceding the return type will be set on this object, not on the return type.
+ * JavaParser doesn't know if it they are applicable to the method or the type.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class MethodDeclaration extends CallableDeclaration<MethodDeclaration> implements NodeWithType<MethodDeclaration, Type>, NodeWithOptionalBlockStmt<MethodDeclaration>, NodeWithJavadoc<MethodDeclaration>, NodeWithDeclaration, NodeWithSimpleName<MethodDeclaration>, NodeWithParameters<MethodDeclaration>, NodeWithThrownExceptions<MethodDeclaration>, NodeWithTypeParameters<MethodDeclaration>, NodeWithAccessModifiers<MethodDeclaration>, NodeWithAbstractModifier<MethodDeclaration>, NodeWithStaticModifier<MethodDeclaration>, NodeWithFinalModifier<MethodDeclaration>, NodeWithStrictfpModifier<MethodDeclaration>, Resolvable<ResolvedMethodDeclaration> {
+
+    private Type type;
+
+    @OptionalProperty
+    private BlockStmt body;
+
+    public MethodDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new NodeList<>(), new ClassOrInterfaceType(), new SimpleName(), new NodeList<>(), new NodeList<>(), new BlockStmt(), null);
+    }
+
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, final Type type, final String name) {
+        this(null, modifiers, new NodeList<>(), new NodeList<>(), type, new SimpleName(name), new NodeList<>(), new NodeList<>(), new BlockStmt(), null);
+    }
+
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, final String name, final Type type, final NodeList<Parameter> parameters) {
+        this(null, modifiers, new NodeList<>(), new NodeList<>(), type, new SimpleName(name), parameters, new NodeList<>(), new BlockStmt(), null);
+    }
+
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, final NodeList<AnnotationExpr> annotations, final NodeList<TypeParameter> typeParameters, final Type type, final SimpleName name, final NodeList<Parameter> parameters, final NodeList<ReferenceType> thrownExceptions, final BlockStmt body) {
+        this(null, modifiers, annotations, typeParameters, type, name, parameters, thrownExceptions, body, null);
+    }
+
+    @AllFieldsConstructor
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, final NodeList<AnnotationExpr> annotations, final NodeList<TypeParameter> typeParameters, final Type type, final SimpleName name, final NodeList<Parameter> parameters, final NodeList<ReferenceType> thrownExceptions, final BlockStmt body, ReceiverParameter receiverParameter) {
+        this(null, modifiers, annotations, typeParameters, type, name, parameters, thrownExceptions, body, receiverParameter);
+    }
+
+    /**
+     * @deprecated this constructor allows you to set "isDefault", but this is no longer a field of this node, but simply one of the modifiers. Use setDefault(boolean) or add DEFAULT to the modifiers set.
+     */
+    @Deprecated
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, final NodeList<AnnotationExpr> annotations, final NodeList<TypeParameter> typeParameters, final Type type, final SimpleName name, final boolean isDefault, final NodeList<Parameter> parameters, final NodeList<ReferenceType> thrownExceptions, final BlockStmt body) {
+        this(null, modifiers, annotations, typeParameters, type, name, parameters, thrownExceptions, body, null);
+        setDefault(isDefault);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public MethodDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<TypeParameter> typeParameters, Type type, SimpleName name, NodeList<Parameter> parameters, NodeList<ReferenceType> thrownExceptions, BlockStmt body, ReceiverParameter receiverParameter) {
+        super(tokenRange, modifiers, annotations, typeParameters, name, parameters, thrownExceptions, receiverParameter);
+        setType(type);
+        setBody(body);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<BlockStmt> getBody() {
+        return Optional.ofNullable(body);
+    }
+
+    /**
+     * Sets the body
+     *
+     * @param body the body, can be null
+     * @return this, the MethodDeclaration
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodDeclaration setBody(final BlockStmt body) {
+        if (body == this.body) {
+            return (MethodDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodDeclaration setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (MethodDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    public MethodDeclaration setModifiers(final EnumSet<Modifier> modifiers) {
+        return super.setModifiers(modifiers);
+    }
+
+    @Override
+    public MethodDeclaration setName(final SimpleName name) {
+        return super.setName(name);
+    }
+
+    @Override
+    public MethodDeclaration setParameters(final NodeList<Parameter> parameters) {
+        return super.setParameters(parameters);
+    }
+
+    @Override
+    public MethodDeclaration setThrownExceptions(final NodeList<ReferenceType> thrownExceptions) {
+        return super.setThrownExceptions(thrownExceptions);
+    }
+
+    @Override
+    public MethodDeclaration setTypeParameters(final NodeList<TypeParameter> typeParameters) {
+        return super.setTypeParameters(typeParameters);
+    }
+
+    /**
+     * The declaration returned has this schema:
+     * <p>
+     * [accessSpecifier] [static] [abstract] [final] [native]
+     * [synchronized] returnType methodName ([paramType [paramName]])
+     * [throws exceptionsList]
+     *
+     * @return method declaration as String
+     */
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName) {
+        StringBuilder sb = new StringBuilder();
+        if (includingModifiers) {
+            AccessSpecifier accessSpecifier = getAccessSpecifier(getModifiers());
+            sb.append(accessSpecifier.asString());
+            sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ");
+            if (getModifiers().contains(STATIC)) {
+                sb.append("static ");
+            }
+            if (getModifiers().contains(ABSTRACT)) {
+                sb.append("abstract ");
+            }
+            if (getModifiers().contains(FINAL)) {
+                sb.append("final ");
+            }
+            if (getModifiers().contains(NATIVE)) {
+                sb.append("native ");
+            }
+            if (getModifiers().contains(SYNCHRONIZED)) {
+                sb.append("synchronized ");
+            }
+        }
+        sb.append(getType().toString(prettyPrinterNoCommentsConfiguration));
+        sb.append(" ");
+        sb.append(getName());
+        sb.append("(");
+        boolean firstParam = true;
+        for (Parameter param : getParameters()) {
+            if (firstParam) {
+                firstParam = false;
+            } else {
+                sb.append(", ");
+            }
+            if (includingParameterName) {
+                sb.append(param.toString(prettyPrinterNoCommentsConfiguration));
+            } else {
+                sb.append(param.getType().toString(prettyPrinterNoCommentsConfiguration));
+                if (param.isVarArgs()) {
+                    sb.append("...");
+                }
+            }
+        }
+        sb.append(")");
+        sb.append(appendThrowsIfRequested(includingThrows));
+        return sb.toString();
+    }
+
+    public boolean isNative() {
+        return getModifiers().contains(NATIVE);
+    }
+
+    public boolean isSynchronized() {
+        return getModifiers().contains(SYNCHRONIZED);
+    }
+
+    public boolean isDefault() {
+        return getModifiers().contains(DEFAULT);
+    }
+
+    public MethodDeclaration setNative(boolean set) {
+        return setModifier(NATIVE, set);
+    }
+
+    public MethodDeclaration setSynchronized(boolean set) {
+        return setModifier(SYNCHRONIZED, set);
+    }
+
+    public MethodDeclaration setDefault(boolean set) {
+        return setModifier(DEFAULT, set);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (body != null) {
+            if (node == body) {
+                removeBody();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public MethodDeclaration removeBody() {
+        return setBody((BlockStmt) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public MethodDeclaration clone() {
+        return (MethodDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public MethodDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.methodDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (body != null) {
+            if (node == body) {
+                setBody((BlockStmt) replacementNode);
+                return true;
+            }
+        }
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMethodDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MethodDeclaration asMethodDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMethodDeclaration(Consumer<MethodDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedMethodDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedMethodDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MethodDeclaration> toMethodDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/Parameter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/Parameter.java
new file mode 100644
index 0000000..a7cf357
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/Parameter.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ParameterMetaModel;
+import java.util.EnumSet;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+
+/**
+ * The parameters to a method or lambda. Lambda parameters may have inferred types, in that case "type" is UnknownType.
+ * <br/>Note that <a href="https://en.wikipedia.org/wiki/Parameter_(computer_programming)#Parameters_and_arguments">parameters
+ * are different from arguments.</a> <br/>"String x" and "float y" are the parameters in <code>int abc(String x, float
+ * y) {...}</code>
+ *
+ * <br/>All annotations preceding the type will be set on this object, not on the type.
+ * JavaParser doesn't know if it they are applicable to the parameter or the type.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class Parameter extends Node implements NodeWithType<Parameter, Type>, NodeWithAnnotations<Parameter>, NodeWithSimpleName<Parameter>, NodeWithFinalModifier<Parameter>, Resolvable<ResolvedParameterDeclaration> {
+
+    private Type type;
+
+    private boolean isVarArgs;
+
+    private NodeList<AnnotationExpr> varArgsAnnotations;
+
+    private EnumSet<Modifier> modifiers;
+
+    private NodeList<AnnotationExpr> annotations;
+
+    private SimpleName name;
+
+    public Parameter() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new ClassOrInterfaceType(), false, new NodeList<>(), new SimpleName());
+    }
+
+    public Parameter(Type type, SimpleName name) {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), type, false, new NodeList<>(), name);
+    }
+
+    /**
+     * Creates a new {@link Parameter}.
+     *
+     * @param type type of the parameter
+     * @param name name of the parameter
+     */
+    public Parameter(Type type, String name) {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), type, false, new NodeList<>(), new SimpleName(name));
+    }
+
+    public Parameter(EnumSet<Modifier> modifiers, Type type, SimpleName name) {
+        this(null, modifiers, new NodeList<>(), type, false, new NodeList<>(), name);
+    }
+
+    @AllFieldsConstructor
+    public Parameter(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, Type type, boolean isVarArgs, NodeList<AnnotationExpr> varArgsAnnotations, SimpleName name) {
+        this(null, modifiers, annotations, type, isVarArgs, varArgsAnnotations, name);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public Parameter(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, Type type, boolean isVarArgs, NodeList<AnnotationExpr> varArgsAnnotations, SimpleName name) {
+        super(tokenRange);
+        setModifiers(modifiers);
+        setAnnotations(annotations);
+        setType(type);
+        setVarArgs(isVarArgs);
+        setVarArgsAnnotations(varArgsAnnotations);
+        setName(name);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isVarArgs() {
+        return isVarArgs;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Parameter setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (Parameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Parameter setVarArgs(final boolean isVarArgs) {
+        if (isVarArgs == this.isVarArgs) {
+            return (Parameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.VAR_ARGS, this.isVarArgs, isVarArgs);
+        this.isVarArgs = isVarArgs;
+        return this;
+    }
+
+    /**
+     * @return the list returned could be immutable (in that case it will be empty)
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    /**
+     * Return the modifiers of this parameter declaration.
+     *
+     * @return modifiers
+     * @see Modifier
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * @param annotations a null value is currently treated as an empty list. This behavior could change in the future,
+     * so please avoid passing null
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Parameter setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (Parameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Parameter setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (Parameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Parameter setModifiers(final EnumSet<Modifier> modifiers) {
+        assertNotNull(modifiers);
+        if (modifiers == this.modifiers) {
+            return (Parameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers);
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < varArgsAnnotations.size(); i++) {
+            if (varArgsAnnotations.get(i) == node) {
+                varArgsAnnotations.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getVarArgsAnnotations() {
+        return varArgsAnnotations;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Parameter setVarArgsAnnotations(final NodeList<AnnotationExpr> varArgsAnnotations) {
+        assertNotNull(varArgsAnnotations);
+        if (varArgsAnnotations == this.varArgsAnnotations) {
+            return (Parameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.VAR_ARGS_ANNOTATIONS, this.varArgsAnnotations, varArgsAnnotations);
+        if (this.varArgsAnnotations != null)
+            this.varArgsAnnotations.setParentNode(null);
+        this.varArgsAnnotations = varArgsAnnotations;
+        setAsParentNodeOf(varArgsAnnotations);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public Parameter clone() {
+        return (Parameter) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ParameterMetaModel getMetaModel() {
+        return JavaParserMetaModel.parameterMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        for (int i = 0; i < varArgsAnnotations.size(); i++) {
+            if (varArgsAnnotations.get(i) == node) {
+                varArgsAnnotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    public ResolvedParameterDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedParameterDeclaration.class);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/ReceiverParameter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ReceiverParameter.java
new file mode 100644
index 0000000..b0038e1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/ReceiverParameter.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ParameterMetaModel;
+import javax.annotation.Generated;
+import java.util.EnumSet;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.metamodel.ReceiverParameterMetaModel;
+
+/**
+ * The rather obscure <a href="http://blog.joda.org/2015/12/explicit-receiver-parameters.html">"receiver parameter" feature of Java</a>.
+ *
+ * <br/>All annotations preceding the type will be set on this object, not on the type.
+ * JavaParser doesn't know if it they are applicable to the receiver parameter or the type.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ReceiverParameter extends Node implements NodeWithType<ReceiverParameter, Type>, NodeWithAnnotations<ReceiverParameter>, NodeWithName<ReceiverParameter> {
+
+    private Type type;
+
+    private NodeList<AnnotationExpr> annotations;
+
+    private Name name;
+
+    public ReceiverParameter() {
+        this(null, new NodeList<>(), new ClassOrInterfaceType(), new Name());
+    }
+
+    public ReceiverParameter(Type type, Name name) {
+        this(null, new NodeList<>(), type, name);
+    }
+
+    /**
+     * Creates a new {@link ReceiverParameter}.
+     *
+     * @param type type of the parameter
+     * @param name name of the parameter
+     */
+    public ReceiverParameter(Type type, String name) {
+        this(null, new NodeList<>(), type, new Name(name));
+    }
+
+    @AllFieldsConstructor
+    public ReceiverParameter(NodeList<AnnotationExpr> annotations, Type type, Name name) {
+        this(null, annotations, type, name);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ReceiverParameter(TokenRange tokenRange, NodeList<AnnotationExpr> annotations, Type type, Name name) {
+        super(tokenRange);
+        setAnnotations(annotations);
+        setType(type);
+        setName(name);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ReceiverParameter setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (ReceiverParameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    /**
+     * @return the list returned could be immutable (in that case it will be empty)
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    /**
+     * @param annotations a null value is currently treated as an empty list. This behavior could change in the future,
+     * so please avoid passing null
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ReceiverParameter setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (ReceiverParameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ReceiverParameter clone() {
+        return (ReceiverParameter) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ReceiverParameterMetaModel getMetaModel() {
+        return JavaParserMetaModel.receiverParameterMetaModel;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ReceiverParameter setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ReceiverParameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/TypeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/TypeDeclaration.java
new file mode 100644
index 0000000..06f9753
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/TypeDeclaration.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavadoc;
+import com.github.javaparser.ast.nodeTypes.NodeWithMembers;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStrictfpModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.TypeDeclarationMetaModel;
+import javax.annotation.Generated;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.toList;
+import com.github.javaparser.ast.Node;
+import java.util.Optional;
+
+/**
+ * A base class for all types of type declarations.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class TypeDeclaration<T extends TypeDeclaration<?>> extends BodyDeclaration<T> implements NodeWithSimpleName<T>, NodeWithJavadoc<T>, NodeWithMembers<T>, NodeWithAccessModifiers<T>, NodeWithStaticModifier<T>, NodeWithStrictfpModifier<T> {
+
+    private SimpleName name;
+
+    private EnumSet<Modifier> modifiers;
+
+    private NodeList<BodyDeclaration<?>> members;
+
+    public TypeDeclaration() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new SimpleName(), new NodeList<>());
+    }
+
+    public TypeDeclaration(EnumSet<Modifier> modifiers, String name) {
+        this(null, modifiers, new NodeList<>(), new SimpleName(name), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public TypeDeclaration(EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<BodyDeclaration<?>> members) {
+        this(null, modifiers, annotations, name, members);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public TypeDeclaration(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, SimpleName name, NodeList<BodyDeclaration<?>> members) {
+        super(tokenRange, annotations);
+        setModifiers(modifiers);
+        setName(name);
+        setMembers(members);
+        customInitialization();
+    }
+
+    /**
+     * Adds the given declaration to the specified type.
+     *
+     * @param decl member declaration
+     */
+    public T addMember(BodyDeclaration<?> decl) {
+        NodeList<BodyDeclaration<?>> members = getMembers();
+        members.add(decl);
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<BodyDeclaration<?>> getMembers() {
+        return members;
+    }
+
+    /**
+     * Return the modifiers of this type declaration.
+     *
+     * @return modifiers
+     * @see Modifier
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setMembers(final NodeList<BodyDeclaration<?>> members) {
+        assertNotNull(members);
+        if (members == this.members) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.MEMBERS, this.members, members);
+        if (this.members != null)
+            this.members.setParentNode(null);
+        this.members = members;
+        setAsParentNodeOf(members);
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setModifiers(final EnumSet<Modifier> modifiers) {
+        assertNotNull(modifiers);
+        if (modifiers == this.modifiers) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers);
+        this.modifiers = modifiers;
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    @SuppressWarnings("unchecked")
+    public T setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (T) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return (T) this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < members.size(); i++) {
+            if (members.get(i) == node) {
+                members.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    /**
+     * @return is this type's parent a CompilationUnit?
+     */
+    public boolean isTopLevelType() {
+        return getParentNode().map(p -> p instanceof CompilationUnit).orElse(false);
+    }
+
+    /**
+     * @return methods or constructors whose signatures match the passed signature.
+     */
+    public List<CallableDeclaration<?>> getCallablesWithSignature(CallableDeclaration.Signature signature) {
+        return getMembers().stream().filter(m -> m instanceof CallableDeclaration).map(m -> ((CallableDeclaration<?>) m)).filter(m -> m.getSignature().equals(signature)).collect(toList());
+    }
+
+    /**
+     * @return is this type's parent a TypeDeclaration?
+     * NOTE: many people are confused over terminology. Refer to https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html .
+     */
+    public boolean isNestedType() {
+        return getParentNode().map(p -> p instanceof TypeDeclaration).orElse(false);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public TypeDeclaration<?> clone() {
+        return (TypeDeclaration<?>) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public TypeDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.typeDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < members.size(); i++) {
+            if (members.get(i) == node) {
+                members.set(i, (BodyDeclaration) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTypeDeclaration() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TypeDeclaration asTypeDeclaration() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTypeDeclaration(Consumer<TypeDeclaration> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TypeDeclaration> toTypeDeclaration() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/body/VariableDeclarator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/body/VariableDeclarator.java
new file mode 100644
index 0000000..0d342ac
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/body/VariableDeclarator.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.observer.AstObserverAdapter;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.metamodel.VariableDeclaratorMetaModel;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+
+/**
+ * The declaration of a variable.<br/>In <code>int x = 14, y = 3;</code> "int x = 14"  and "int y = 3"  are
+ * VariableDeclarators.
+ * <p/>The type is on all of the variable declarators because, thanks to array brackets, each variable can have a different type.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclarator extends Node implements NodeWithType<VariableDeclarator, Type>, NodeWithSimpleName<VariableDeclarator>, Resolvable<ResolvedFieldDeclaration> {
+
+    private SimpleName name;
+
+    @OptionalProperty
+    @NonEmptyProperty
+    private Expression initializer;
+
+    private Type type;
+
+    public VariableDeclarator() {
+        this(null, new ClassOrInterfaceType(), new SimpleName(), null);
+    }
+
+    public VariableDeclarator(Type type, String variableName) {
+        this(null, type, new SimpleName(variableName), null);
+    }
+
+    public VariableDeclarator(Type type, SimpleName name) {
+        this(null, type, name, null);
+    }
+
+    public VariableDeclarator(Type type, String variableName, Expression initializer) {
+        this(null, type, new SimpleName(variableName), initializer);
+    }
+
+    /**
+     * Defines the declaration of a variable.
+     *
+     * @param name The identifier for this variable. IE. The variables name.
+     * @param initializer What this variable should be initialized to. An {@link com.github.javaparser.ast.expr.AssignExpr}
+     * is unnecessary as the <code>=</code> operator is already added.
+     */
+    @AllFieldsConstructor
+    public VariableDeclarator(Type type, SimpleName name, Expression initializer) {
+        this(null, type, name, initializer);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public VariableDeclarator(TokenRange tokenRange, Type type, SimpleName name, Expression initializer) {
+        super(tokenRange);
+        setType(type);
+        setName(name);
+        setInitializer(initializer);
+        customInitialization();
+    }
+
+    @Override
+    protected void customInitialization() {
+        // We register an observer on the type property. When it is changed the MaximumCommonType is changes as well,
+        // because it is derived from the type of the variables it contains, for this reason we notify about the change
+        register(new AstObserverAdapter() {
+
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                if (property == ObservableProperty.TYPE) {
+                    VariableDeclarator vd = VariableDeclarator.this;
+                    if (vd.getParentNode().isPresent() && vd.getParentNode().get() instanceof NodeWithVariables) {
+                        NodeWithVariables nodeWithVariables = (NodeWithVariables) vd.getParentNode().get();
+                        // We calculate the value the property will assume after the change will be completed
+                        Optional<Type> currentMaxCommonType = nodeWithVariables.getMaximumCommonType();
+                        List<Type> types = new LinkedList<>();
+                        int index = nodeWithVariables.getVariables().indexOf(vd);
+                        for (int i = 0; i < nodeWithVariables.getVariables().size(); i++) {
+                            if (i == index) {
+                                types.add((Type) newValue);
+                            } else {
+                                types.add(nodeWithVariables.getVariable(i).getType());
+                            }
+                        }
+                        Optional<Type> newMaxCommonType = NodeWithVariables.calculateMaximumCommonType(types);
+                        ((Node) nodeWithVariables).notifyPropertyChange(ObservableProperty.MAXIMUM_COMMON_TYPE, currentMaxCommonType.orElse(null), newMaxCommonType.orElse(null));
+                    }
+                }
+            }
+        });
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getInitializer() {
+        return Optional.ofNullable(initializer);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public VariableDeclarator setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (VariableDeclarator) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    /**
+     * Sets the initializer expression
+     *
+     * @param initializer the initializer expression, can be null
+     * @return this, the VariableDeclarator
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public VariableDeclarator setInitializer(final Expression initializer) {
+        if (initializer == this.initializer) {
+            return (VariableDeclarator) this;
+        }
+        notifyPropertyChange(ObservableProperty.INITIALIZER, this.initializer, initializer);
+        if (this.initializer != null)
+            this.initializer.setParentNode(null);
+        this.initializer = initializer;
+        setAsParentNodeOf(initializer);
+        return this;
+    }
+
+    /**
+     * Will create a {@link NameExpr} with the initializer param
+     *
+     * @param init the initializer expression, can be null
+     * @return this, the VariableDeclarator
+     */
+    public VariableDeclarator setInitializer(String init) {
+        return setInitializer(new NameExpr(assertNonEmpty(init)));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public VariableDeclarator setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (VariableDeclarator) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (initializer != null) {
+            if (node == initializer) {
+                removeInitializer();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public VariableDeclarator removeInitializer() {
+        return setInitializer((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public VariableDeclarator clone() {
+        return (VariableDeclarator) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public VariableDeclaratorMetaModel getMetaModel() {
+        return JavaParserMetaModel.variableDeclaratorMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (initializer != null) {
+            if (node == initializer) {
+                setInitializer((Expression) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    public ResolvedFieldDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedFieldDeclaration.class);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/comments/BlockComment.java b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/BlockComment.java
new file mode 100644
index 0000000..8d30b28
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/BlockComment.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.BlockCommentMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * <p>
+ * AST node that represent block comments.
+ * </p>
+ * Block comments can has multi lines and are delimited by "/&#42;" and
+ * "&#42;/".
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class BlockComment extends Comment {
+
+    public BlockComment() {
+        this(null, "empty");
+    }
+
+    @AllFieldsConstructor
+    public BlockComment(String content) {
+        this(null, content);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public BlockComment(TokenRange tokenRange, String content) {
+        super(tokenRange, content);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public BlockComment clone() {
+        return (BlockComment) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public BlockCommentMetaModel getMetaModel() {
+        return JavaParserMetaModel.blockCommentMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBlockComment() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BlockComment asBlockComment() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBlockComment(Consumer<BlockComment> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BlockComment> toBlockComment() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/comments/Comment.java b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/Comment.java
new file mode 100644
index 0000000..0c5f6b4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/Comment.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.CommentMetaModel;
+import com.github.javaparser.metamodel.InternalProperty;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Abstract class for all AST nodes that represent comments.
+ *
+ * @author Julio Vilmar Gesser
+ * @see BlockComment
+ * @see LineComment
+ * @see JavadocComment
+ */
+public abstract class Comment extends Node {
+
+    private String content;
+
+    @InternalProperty
+    private Node commentedNode;
+
+    @AllFieldsConstructor
+    public Comment(String content) {
+        this(null, content);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public Comment(TokenRange tokenRange, String content) {
+        super(tokenRange);
+        setContent(content);
+        customInitialization();
+    }
+
+    /**
+     * Return the text of the comment.
+     *
+     * @return text of the comment
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public String getContent() {
+        return content;
+    }
+
+    /**
+     * Sets the text of the comment.
+     *
+     * @param content the text of the comment to set
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Comment setContent(final String content) {
+        assertNotNull(content);
+        if (content == this.content) {
+            return (Comment) this;
+        }
+        notifyPropertyChange(ObservableProperty.CONTENT, this.content, content);
+        this.content = content;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLineComment() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LineComment asLineComment() {
+        throw new IllegalStateException(f("%s is not an LineComment", this));
+    }
+
+    public Optional<Node> getCommentedNode() {
+        return Optional.ofNullable(this.commentedNode);
+    }
+
+    /**
+     * Sets the commentedNode
+     *
+     * @param commentedNode the commentedNode, can be null
+     * @return this, the Comment
+     */
+    public Comment setCommentedNode(Node commentedNode) {
+        notifyPropertyChange(ObservableProperty.COMMENTED_NODE, this.commentedNode, commentedNode);
+        if (commentedNode == null) {
+            this.commentedNode = null;
+            return this;
+        }
+        if (commentedNode == this) {
+            throw new IllegalArgumentException();
+        }
+        if (commentedNode instanceof Comment) {
+            throw new IllegalArgumentException();
+        }
+        this.commentedNode = commentedNode;
+        return this;
+    }
+
+    public boolean isOrphan() {
+        return this.commentedNode == null;
+    }
+
+    @Override
+    public boolean remove() {
+        // the other are orphan comments and remove should work with them
+        if (this.commentedNode != null) {
+            this.commentedNode.setComment(null);
+            return true;
+        } else if (this.getParentNode().isPresent()) {
+            return this.getParentNode().get().removeOrphanComment(this);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public Comment clone() {
+        return (Comment) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public CommentMetaModel getMetaModel() {
+        return JavaParserMetaModel.commentMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBlockComment() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BlockComment asBlockComment() {
+        throw new IllegalStateException(f("%s is not an BlockComment", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isJavadocComment() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public JavadocComment asJavadocComment() {
+        throw new IllegalStateException(f("%s is not an JavadocComment", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBlockComment(Consumer<BlockComment> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifJavadocComment(Consumer<JavadocComment> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLineComment(Consumer<LineComment> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BlockComment> toBlockComment() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<JavadocComment> toJavadocComment() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LineComment> toLineComment() {
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/comments/CommentsCollection.java b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/CommentsCollection.java
new file mode 100644
index 0000000..f3f2577
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/CommentsCollection.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.Range;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.ast.Node.NODE_BY_BEGIN_POSITION;
+
+/**
+ * The comments contained in a certain parsed piece of source code.
+ */
+public class CommentsCollection {
+    private final TreeSet<Comment> comments = new TreeSet<>(NODE_BY_BEGIN_POSITION);
+
+    public CommentsCollection() {
+    }
+
+    public CommentsCollection(Collection<Comment> commentsToCopy) {
+        comments.addAll(commentsToCopy);
+    }
+
+    public Set<LineComment> getLineComments() {
+        return comments.stream()
+                .filter(comment -> comment instanceof LineComment)
+                .map(comment -> (LineComment) comment)
+                .collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)));
+    }
+
+    public Set<BlockComment> getBlockComments() {
+        return comments.stream()
+                .filter(comment -> comment instanceof BlockComment)
+                .map(comment -> (BlockComment) comment)
+                .collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)));
+    }
+
+    public Set<JavadocComment> getJavadocComments() {
+        return comments.stream()
+                .filter(comment -> comment instanceof JavadocComment)
+                .map(comment -> (JavadocComment) comment)
+                .collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)));
+    }
+
+    public void addComment(Comment comment) {
+        comments.add(comment);
+    }
+
+    public boolean contains(Comment comment) {
+        if (!comment.getRange().isPresent()) {
+            return false;
+        }
+        Range commentRange = comment.getRange().get();
+        for (Comment c : getComments()) {
+            if (!c.getRange().isPresent()) {
+                return false;
+            }
+            Range cRange = c.getRange().get();
+            // we tolerate a difference of one element in the end column:
+            // it depends how \r and \n are calculated...
+            if (cRange.begin.equals(commentRange.begin) &&
+                    cRange.end.line == commentRange.end.line &&
+                    Math.abs(cRange.end.column - commentRange.end.column) < 2) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public TreeSet<Comment> getComments() {
+        return comments;
+    }
+
+    public int size() {
+        return comments.size();
+    }
+
+    public CommentsCollection minus(CommentsCollection other) {
+        CommentsCollection result = new CommentsCollection();
+        result.comments.addAll(
+                comments.stream()
+                        .filter(comment -> !other.contains(comment))
+                        .collect(Collectors.toList()));
+        return result;
+    }
+
+    public CommentsCollection copy() {
+        return new CommentsCollection(comments);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/comments/JavadocComment.java b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/JavadocComment.java
new file mode 100644
index 0000000..d795997
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/JavadocComment.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.javadoc.Javadoc;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavadocCommentMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A Javadoc comment. <code>/&#42;&#42; a comment &#42;/</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class JavadocComment extends Comment {
+
+    public JavadocComment() {
+        this(null, "empty");
+    }
+
+    @AllFieldsConstructor
+    public JavadocComment(String content) {
+        this(null, content);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public JavadocComment(TokenRange tokenRange, String content) {
+        super(tokenRange, content);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    public Javadoc parse() {
+        return JavaParser.parseJavadoc(getContent());
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public JavadocComment clone() {
+        return (JavadocComment) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public JavadocCommentMetaModel getMetaModel() {
+        return JavaParserMetaModel.javadocCommentMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isJavadocComment() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public JavadocComment asJavadocComment() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifJavadocComment(Consumer<JavadocComment> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<JavadocComment> toJavadocComment() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/comments/LineComment.java b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/LineComment.java
new file mode 100644
index 0000000..ddbce80
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/comments/LineComment.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.LineCommentMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * <p>
+ * AST node that represent line comments.
+ * </p>
+ * Line comments start with "//" and finish at the end of the line ("\n").
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class LineComment extends Comment {
+
+    public LineComment() {
+        this(null, "empty");
+    }
+
+    @AllFieldsConstructor
+    public LineComment(String content) {
+        this(null, content);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public LineComment(TokenRange tokenRange, String content) {
+        super(tokenRange, content);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLineComment() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public LineComment clone() {
+        return (LineComment) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public LineCommentMetaModel getMetaModel() {
+        return JavaParserMetaModel.lineCommentMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LineComment asLineComment() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLineComment(Consumer<LineComment> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LineComment> toLineComment() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/AnnotationExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/AnnotationExpr.java
new file mode 100644
index 0000000..31c70fb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/AnnotationExpr.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.AnnotationExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A base class for the different types of annotations.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class AnnotationExpr extends Expression implements NodeWithName<AnnotationExpr> {
+
+    protected Name name;
+
+    public AnnotationExpr() {
+        this(null, new Name());
+    }
+
+    @AllFieldsConstructor
+    public AnnotationExpr(Name name) {
+        this(null, name);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public AnnotationExpr(TokenRange tokenRange, Name name) {
+        super(tokenRange);
+        setName(name);
+        customInitialization();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AnnotationExpr setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (AnnotationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public AnnotationExpr clone() {
+        return (AnnotationExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public AnnotationExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.annotationExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAnnotationExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AnnotationExpr asAnnotationExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAnnotationExpr(Consumer<AnnotationExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AnnotationExpr> toAnnotationExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayAccessExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayAccessExpr.java
new file mode 100644
index 0000000..6945dd9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayAccessExpr.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ArrayAccessExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Array brackets [] being used to get a value from an array.
+ * In <br/><code>getNames()[15*15]</code> the name expression is getNames() and the index expression is 15*15.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayAccessExpr extends Expression {
+
+    private Expression name;
+
+    private Expression index;
+
+    public ArrayAccessExpr() {
+        this(null, new NameExpr(), new IntegerLiteralExpr());
+    }
+
+    @AllFieldsConstructor
+    public ArrayAccessExpr(Expression name, Expression index) {
+        this(null, name, index);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ArrayAccessExpr(TokenRange tokenRange, Expression name, Expression index) {
+        super(tokenRange);
+        setName(name);
+        setIndex(index);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getIndex() {
+        return index;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayAccessExpr setIndex(final Expression index) {
+        assertNotNull(index);
+        if (index == this.index) {
+            return (ArrayAccessExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.INDEX, this.index, index);
+        if (this.index != null)
+            this.index.setParentNode(null);
+        this.index = index;
+        setAsParentNodeOf(index);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayAccessExpr setName(final Expression name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ArrayAccessExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ArrayAccessExpr clone() {
+        return (ArrayAccessExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ArrayAccessExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.arrayAccessExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == index) {
+            setIndex((Expression) replacementNode);
+            return true;
+        }
+        if (node == name) {
+            setName((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayAccessExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayAccessExpr asArrayAccessExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayAccessExpr(Consumer<ArrayAccessExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayAccessExpr> toArrayAccessExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayCreationExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayCreationExpr.java
new file mode 100644
index 0000000..5099258
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayCreationExpr.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.ArrayCreationExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.JavaParser.parseType;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.metamodel.OptionalProperty;
+import java.util.function.Consumer;
+
+/**
+ * <code>new int[5][4][][]</code> or <code>new int[][]{{1},{2,3}}</code>.
+ *
+ * <br/>"int" is the element type.
+ * <br/>All the brackets are stored in the levels field, from left to right.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayCreationExpr extends Expression {
+
+    @NonEmptyProperty
+    private NodeList<ArrayCreationLevel> levels;
+
+    private Type elementType;
+
+    @OptionalProperty
+    private ArrayInitializerExpr initializer;
+
+    public ArrayCreationExpr() {
+        this(null, new ClassOrInterfaceType(), new NodeList<>(), new ArrayInitializerExpr());
+    }
+
+    @AllFieldsConstructor
+    public ArrayCreationExpr(Type elementType, NodeList<ArrayCreationLevel> levels, ArrayInitializerExpr initializer) {
+        this(null, elementType, levels, initializer);
+    }
+
+    public ArrayCreationExpr(Type elementType) {
+        this(null, elementType, new NodeList<>(), new ArrayInitializerExpr());
+    }
+
+    /**
+     * @deprecated range shouldn't be in utility constructors.
+     */
+    @Deprecated
+    public ArrayCreationExpr(Range range, Type elementType) {
+        this(null, elementType, new NodeList<>(), new ArrayInitializerExpr());
+        setRange(range);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ArrayCreationExpr(TokenRange tokenRange, Type elementType, NodeList<ArrayCreationLevel> levels, ArrayInitializerExpr initializer) {
+        super(tokenRange);
+        setElementType(elementType);
+        setLevels(levels);
+        setInitializer(initializer);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<ArrayInitializerExpr> getInitializer() {
+        return Optional.ofNullable(initializer);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getElementType() {
+        return elementType;
+    }
+
+    /**
+     * Sets the initializer
+     *
+     * @param initializer the initializer, can be null
+     * @return this, the ArrayCreationExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayCreationExpr setInitializer(final ArrayInitializerExpr initializer) {
+        if (initializer == this.initializer) {
+            return (ArrayCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.INITIALIZER, this.initializer, initializer);
+        if (this.initializer != null)
+            this.initializer.setParentNode(null);
+        this.initializer = initializer;
+        setAsParentNodeOf(initializer);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayCreationExpr setElementType(final Type elementType) {
+        assertNotNull(elementType);
+        if (elementType == this.elementType) {
+            return (ArrayCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.ELEMENT_TYPE, this.elementType, elementType);
+        if (this.elementType != null)
+            this.elementType.setParentNode(null);
+        this.elementType = elementType;
+        setAsParentNodeOf(elementType);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ArrayCreationLevel> getLevels() {
+        return levels;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayCreationExpr setLevels(final NodeList<ArrayCreationLevel> levels) {
+        assertNotNull(levels);
+        if (levels == this.levels) {
+            return (ArrayCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.LEVELS, this.levels, levels);
+        if (this.levels != null)
+            this.levels.setParentNode(null);
+        this.levels = levels;
+        setAsParentNodeOf(levels);
+        return this;
+    }
+
+    /**
+     * Takes the element type and wraps it in an ArrayType for every array creation level.
+     */
+    public Type createdType() {
+        Type result = elementType;
+        for (int i = 0; i < levels.size(); i++) {
+            result = new ArrayType(result, ArrayType.Origin.TYPE, new NodeList<>());
+        }
+        return result;
+    }
+
+    /**
+     * Sets this type to this class and try to import it to the {@link CompilationUnit} if needed
+     *
+     * @param typeClass the type
+     * @return this
+     */
+    public ArrayCreationExpr setElementType(Class<?> typeClass) {
+        tryAddImportToParentCompilationUnit(typeClass);
+        return setElementType(parseType(typeClass.getSimpleName()));
+    }
+
+    public ArrayCreationExpr setElementType(final String type) {
+        return setElementType(parseType(type));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (initializer != null) {
+            if (node == initializer) {
+                removeInitializer();
+                return true;
+            }
+        }
+        for (int i = 0; i < levels.size(); i++) {
+            if (levels.get(i) == node) {
+                levels.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ArrayCreationExpr removeInitializer() {
+        return setInitializer((ArrayInitializerExpr) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ArrayCreationExpr clone() {
+        return (ArrayCreationExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ArrayCreationExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.arrayCreationExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == elementType) {
+            setElementType((Type) replacementNode);
+            return true;
+        }
+        if (initializer != null) {
+            if (node == initializer) {
+                setInitializer((ArrayInitializerExpr) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < levels.size(); i++) {
+            if (levels.get(i) == node) {
+                levels.set(i, (ArrayCreationLevel) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayCreationExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayCreationExpr asArrayCreationExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayCreationExpr(Consumer<ArrayCreationExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayCreationExpr> toArrayCreationExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayInitializerExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayInitializerExpr.java
new file mode 100644
index 0000000..d585a18
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ArrayInitializerExpr.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ArrayInitializerExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * The initialization of an array. In the following sample, the outer { } is an ArrayInitializerExpr.
+ * It has two expressions inside: two ArrayInitializerExprs.
+ * These have two expressions each, one has 1 and 1, the other two and two.
+ * <br/><code>new int[][]{{1, 1}, {2, 2}};</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayInitializerExpr extends Expression {
+
+    private NodeList<Expression> values;
+
+    public ArrayInitializerExpr() {
+        this(null, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ArrayInitializerExpr(NodeList<Expression> values) {
+        this(null, values);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ArrayInitializerExpr(TokenRange tokenRange, NodeList<Expression> values) {
+        super(tokenRange);
+        setValues(values);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getValues() {
+        return values;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayInitializerExpr setValues(final NodeList<Expression> values) {
+        assertNotNull(values);
+        if (values == this.values) {
+            return (ArrayInitializerExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.VALUES, this.values, values);
+        if (this.values != null)
+            this.values.setParentNode(null);
+        this.values = values;
+        setAsParentNodeOf(values);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < values.size(); i++) {
+            if (values.get(i) == node) {
+                values.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ArrayInitializerExpr clone() {
+        return (ArrayInitializerExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ArrayInitializerExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.arrayInitializerExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < values.size(); i++) {
+            if (values.get(i) == node) {
+                values.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayInitializerExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayInitializerExpr asArrayInitializerExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayInitializerExpr(Consumer<ArrayInitializerExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayInitializerExpr> toArrayInitializerExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/AssignExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/AssignExpr.java
new file mode 100644
index 0000000..fbb4687
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/AssignExpr.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.AssignExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.printer.Printable;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An assignment expression. It supports the operators that are found the the AssignExpr.Operator enum.
+ * <br/><code>a=5</code>
+ * <br/><code>time+=500</code>
+ * <br/><code>watch.time+=500</code>
+ * <br/><code>(((time)))=100*60</code>
+ * <br/><code>peanut[a]=true</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class AssignExpr extends Expression {
+
+    public enum Operator implements Printable {
+
+        ASSIGN("="),
+        PLUS("+="),
+        MINUS("-="),
+        MULTIPLY("*="),
+        DIVIDE("/="),
+        BINARY_AND("&="),
+        BINARY_OR("|="),
+        XOR("^="),
+        REMAINDER("%="),
+        LEFT_SHIFT("<<="),
+        SIGNED_RIGHT_SHIFT(">>="),
+        UNSIGNED_RIGHT_SHIFT(">>>=");
+
+        private final String codeRepresentation;
+
+        Operator(String codeRepresentation) {
+            this.codeRepresentation = codeRepresentation;
+        }
+
+        public String asString() {
+            return codeRepresentation;
+        }
+
+        public Optional<BinaryExpr.Operator> toBinaryOperator() {
+            switch(this) {
+                case PLUS:
+                    return Optional.of(BinaryExpr.Operator.PLUS);
+                case MINUS:
+                    return Optional.of(BinaryExpr.Operator.MINUS);
+                case MULTIPLY:
+                    return Optional.of(BinaryExpr.Operator.MULTIPLY);
+                case DIVIDE:
+                    return Optional.of(BinaryExpr.Operator.DIVIDE);
+                case BINARY_AND:
+                    return Optional.of(BinaryExpr.Operator.BINARY_AND);
+                case BINARY_OR:
+                    return Optional.of(BinaryExpr.Operator.BINARY_OR);
+                case XOR:
+                    return Optional.of(BinaryExpr.Operator.XOR);
+                case REMAINDER:
+                    return Optional.of(BinaryExpr.Operator.REMAINDER);
+                case LEFT_SHIFT:
+                    return Optional.of(BinaryExpr.Operator.LEFT_SHIFT);
+                case SIGNED_RIGHT_SHIFT:
+                    return Optional.of(BinaryExpr.Operator.SIGNED_RIGHT_SHIFT);
+                case UNSIGNED_RIGHT_SHIFT:
+                    return Optional.of(BinaryExpr.Operator.UNSIGNED_RIGHT_SHIFT);
+                default:
+                    return Optional.empty();
+            }
+        }
+    }
+
+    private Expression target;
+
+    private Expression value;
+
+    private Operator operator;
+
+    public AssignExpr() {
+        this(null, new NameExpr(), new StringLiteralExpr(), Operator.ASSIGN);
+    }
+
+    @AllFieldsConstructor
+    public AssignExpr(Expression target, Expression value, Operator operator) {
+        this(null, target, value, operator);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public AssignExpr(TokenRange tokenRange, Expression target, Expression value, Operator operator) {
+        super(tokenRange);
+        setTarget(target);
+        setValue(value);
+        setOperator(operator);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Operator getOperator() {
+        return operator;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getTarget() {
+        return target;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getValue() {
+        return value;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AssignExpr setOperator(final Operator operator) {
+        assertNotNull(operator);
+        if (operator == this.operator) {
+            return (AssignExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.OPERATOR, this.operator, operator);
+        this.operator = operator;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AssignExpr setTarget(final Expression target) {
+        assertNotNull(target);
+        if (target == this.target) {
+            return (AssignExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TARGET, this.target, target);
+        if (this.target != null)
+            this.target.setParentNode(null);
+        this.target = target;
+        setAsParentNodeOf(target);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AssignExpr setValue(final Expression value) {
+        assertNotNull(value);
+        if (value == this.value) {
+            return (AssignExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.VALUE, this.value, value);
+        if (this.value != null)
+            this.value.setParentNode(null);
+        this.value = value;
+        setAsParentNodeOf(value);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public AssignExpr clone() {
+        return (AssignExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public AssignExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.assignExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == target) {
+            setTarget((Expression) replacementNode);
+            return true;
+        }
+        if (node == value) {
+            setValue((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAssignExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AssignExpr asAssignExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAssignExpr(Consumer<AssignExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AssignExpr> toAssignExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/BinaryExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/BinaryExpr.java
new file mode 100644
index 0000000..5ec79c0
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/BinaryExpr.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.BinaryExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.printer.Printable;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An expression with an expression on the left, an expression on the right, and an operator in the middle.
+ * It supports the operators that are found the the BinaryExpr.Operator enum.
+ * <br/><code>a && b</code>
+ * <br/><code>155 * 33</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class BinaryExpr extends Expression {
+
+    public enum Operator implements Printable {
+
+        OR("||"),
+        AND("&&"),
+        BINARY_OR("|"),
+        BINARY_AND("&"),
+        XOR("^"),
+        EQUALS("=="),
+        NOT_EQUALS("!="),
+        LESS("<"),
+        GREATER(">"),
+        LESS_EQUALS("<="),
+        GREATER_EQUALS(">="),
+        LEFT_SHIFT("<<"),
+        SIGNED_RIGHT_SHIFT(">>"),
+        UNSIGNED_RIGHT_SHIFT(">>>"),
+        PLUS("+"),
+        MINUS("-"),
+        MULTIPLY("*"),
+        DIVIDE("/"),
+        REMAINDER("%");
+
+        private final String codeRepresentation;
+
+        Operator(String codeRepresentation) {
+            this.codeRepresentation = codeRepresentation;
+        }
+
+        public String asString() {
+            return codeRepresentation;
+        }
+
+        public Optional<AssignExpr.Operator> toAssignOperator() {
+            switch(this) {
+                case BINARY_OR:
+                    return Optional.of(AssignExpr.Operator.BINARY_OR);
+                case BINARY_AND:
+                    return Optional.of(AssignExpr.Operator.BINARY_AND);
+                case XOR:
+                    return Optional.of(AssignExpr.Operator.XOR);
+                case LEFT_SHIFT:
+                    return Optional.of(AssignExpr.Operator.LEFT_SHIFT);
+                case SIGNED_RIGHT_SHIFT:
+                    return Optional.of(AssignExpr.Operator.SIGNED_RIGHT_SHIFT);
+                case UNSIGNED_RIGHT_SHIFT:
+                    return Optional.of(AssignExpr.Operator.UNSIGNED_RIGHT_SHIFT);
+                case PLUS:
+                    return Optional.of(AssignExpr.Operator.PLUS);
+                case MINUS:
+                    return Optional.of(AssignExpr.Operator.MINUS);
+                case MULTIPLY:
+                    return Optional.of(AssignExpr.Operator.MULTIPLY);
+                case DIVIDE:
+                    return Optional.of(AssignExpr.Operator.DIVIDE);
+                case REMAINDER:
+                    return Optional.of(AssignExpr.Operator.REMAINDER);
+                default:
+                    return Optional.empty();
+            }
+        }
+    }
+
+    private Expression left;
+
+    private Expression right;
+
+    private Operator operator;
+
+    public BinaryExpr() {
+        this(null, new BooleanLiteralExpr(), new BooleanLiteralExpr(), Operator.EQUALS);
+    }
+
+    @AllFieldsConstructor
+    public BinaryExpr(Expression left, Expression right, Operator operator) {
+        this(null, left, right, operator);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public BinaryExpr(TokenRange tokenRange, Expression left, Expression right, Operator operator) {
+        super(tokenRange);
+        setLeft(left);
+        setRight(right);
+        setOperator(operator);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getLeft() {
+        return left;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Operator getOperator() {
+        return operator;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getRight() {
+        return right;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BinaryExpr setLeft(final Expression left) {
+        assertNotNull(left);
+        if (left == this.left) {
+            return (BinaryExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.LEFT, this.left, left);
+        if (this.left != null)
+            this.left.setParentNode(null);
+        this.left = left;
+        setAsParentNodeOf(left);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BinaryExpr setOperator(final Operator operator) {
+        assertNotNull(operator);
+        if (operator == this.operator) {
+            return (BinaryExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.OPERATOR, this.operator, operator);
+        this.operator = operator;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BinaryExpr setRight(final Expression right) {
+        assertNotNull(right);
+        if (right == this.right) {
+            return (BinaryExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.RIGHT, this.right, right);
+        if (this.right != null)
+            this.right.setParentNode(null);
+        this.right = right;
+        setAsParentNodeOf(right);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public BinaryExpr clone() {
+        return (BinaryExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public BinaryExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.binaryExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == left) {
+            setLeft((Expression) replacementNode);
+            return true;
+        }
+        if (node == right) {
+            setRight((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBinaryExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BinaryExpr asBinaryExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBinaryExpr(Consumer<BinaryExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BinaryExpr> toBinaryExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/BooleanLiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/BooleanLiteralExpr.java
new file mode 100644
index 0000000..4be43b2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/BooleanLiteralExpr.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.BooleanLiteralExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * The boolean literals.
+ * <br/><code>true</code>
+ * <br/><code>false</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class BooleanLiteralExpr extends LiteralExpr {
+
+    private boolean value;
+
+    public BooleanLiteralExpr() {
+        this(null, false);
+    }
+
+    @AllFieldsConstructor
+    public BooleanLiteralExpr(boolean value) {
+        this(null, value);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public BooleanLiteralExpr(TokenRange tokenRange, boolean value) {
+        super(tokenRange);
+        setValue(value);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean getValue() {
+        return value;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BooleanLiteralExpr setValue(final boolean value) {
+        if (value == this.value) {
+            return (BooleanLiteralExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.VALUE, this.value, value);
+        this.value = value;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public BooleanLiteralExpr clone() {
+        return (BooleanLiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public BooleanLiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.booleanLiteralExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBooleanLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BooleanLiteralExpr asBooleanLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBooleanLiteralExpr(Consumer<BooleanLiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BooleanLiteralExpr> toBooleanLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/CastExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/CastExpr.java
new file mode 100644
index 0000000..174d24c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/CastExpr.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithExpression;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.CastExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A typecast. The (long) in <code>(long)15</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class CastExpr extends Expression implements NodeWithType<CastExpr, Type>, NodeWithExpression<CastExpr> {
+
+    private Type type;
+
+    private Expression expression;
+
+    public CastExpr() {
+        this(null, new ClassOrInterfaceType(), new NameExpr());
+    }
+
+    @AllFieldsConstructor
+    public CastExpr(Type type, Expression expression) {
+        this(null, type, expression);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public CastExpr(TokenRange tokenRange, Type type, Expression expression) {
+        super(tokenRange);
+        setType(type);
+        setExpression(expression);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getExpression() {
+        return expression;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CastExpr setExpression(final Expression expression) {
+        assertNotNull(expression);
+        if (expression == this.expression) {
+            return (CastExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CastExpr setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (CastExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public CastExpr clone() {
+        return (CastExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public CastExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.castExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == expression) {
+            setExpression((Expression) replacementNode);
+            return true;
+        }
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isCastExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public CastExpr asCastExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifCastExpr(Consumer<CastExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<CastExpr> toCastExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/CharLiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/CharLiteralExpr.java
new file mode 100644
index 0000000..bc2db00
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/CharLiteralExpr.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.CharLiteralExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.utils.StringEscapeUtils;
+import com.github.javaparser.utils.Utils;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A literal character.
+ * <br/><code>'a'</code>
+ * <br/><code>'\t'</code>
+ * <br/><code>'Ω'</code>
+ * <br/><code>'\177'</code>
+ * <br/><code>'💩'</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class CharLiteralExpr extends LiteralStringValueExpr {
+
+    public CharLiteralExpr() {
+        this(null, "?");
+    }
+
+    @AllFieldsConstructor
+    public CharLiteralExpr(String value) {
+        this(null, value);
+    }
+
+    /**
+     * Constructs a CharLiteralExpr with given escaped character.
+     *
+     * @param value a char
+     */
+    public CharLiteralExpr(char value) {
+        this(null, StringEscapeUtils.escapeJava(String.valueOf(value)));
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public CharLiteralExpr(TokenRange tokenRange, String value) {
+        super(tokenRange, value);
+        customInitialization();
+    }
+
+    /**
+     * Utility method that creates a new StringLiteralExpr. Escapes EOL characters.
+     */
+    public static CharLiteralExpr escape(String string) {
+        return new CharLiteralExpr(Utils.escapeEndOfLines(string));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    /**
+     * @return the unescaped value character of this literal
+     */
+    public char asChar() {
+        return StringEscapeUtils.unescapeJava(value).charAt(0);
+    }
+
+    /**
+     * Sets the given char as the literal value
+     *
+     * @param value a char
+     * @return this expression
+     */
+    public CharLiteralExpr setChar(char value) {
+        this.value = String.valueOf(value);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public CharLiteralExpr clone() {
+        return (CharLiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public CharLiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.charLiteralExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isCharLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public CharLiteralExpr asCharLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifCharLiteralExpr(Consumer<CharLiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<CharLiteralExpr> toCharLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ClassExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ClassExpr.java
new file mode 100644
index 0000000..729bd4f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ClassExpr.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ClassExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Defines an expression that accesses the class of a type.
+ * <br/><code>Object.class</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassExpr extends Expression implements NodeWithType<ClassExpr, Type> {
+
+    private Type type;
+
+    public ClassExpr() {
+        this(null, new ClassOrInterfaceType());
+    }
+
+    @AllFieldsConstructor
+    public ClassExpr(Type type) {
+        this(null, type);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ClassExpr(TokenRange tokenRange, Type type) {
+        super(tokenRange);
+        setType(type);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassExpr setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (ClassExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ClassExpr clone() {
+        return (ClassExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ClassExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.classExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isClassExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ClassExpr asClassExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifClassExpr(Consumer<ClassExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ClassExpr> toClassExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ConditionalExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ConditionalExpr.java
new file mode 100644
index 0000000..bdc50a0
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ConditionalExpr.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithCondition;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ConditionalExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * The ternary conditional expression.
+ * In <code>b==0?x:y</code>, b==0 is the condition, x is thenExpr, and y is elseExpr.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ConditionalExpr extends Expression implements NodeWithCondition<ConditionalExpr> {
+
+    private Expression condition;
+
+    private Expression thenExpr;
+
+    private Expression elseExpr;
+
+    public ConditionalExpr() {
+        this(null, new BooleanLiteralExpr(), new StringLiteralExpr(), new StringLiteralExpr());
+    }
+
+    @AllFieldsConstructor
+    public ConditionalExpr(Expression condition, Expression thenExpr, Expression elseExpr) {
+        this(null, condition, thenExpr, elseExpr);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ConditionalExpr(TokenRange tokenRange, Expression condition, Expression thenExpr, Expression elseExpr) {
+        super(tokenRange);
+        setCondition(condition);
+        setThenExpr(thenExpr);
+        setElseExpr(elseExpr);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getCondition() {
+        return condition;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getElseExpr() {
+        return elseExpr;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getThenExpr() {
+        return thenExpr;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ConditionalExpr setCondition(final Expression condition) {
+        assertNotNull(condition);
+        if (condition == this.condition) {
+            return (ConditionalExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.CONDITION, this.condition, condition);
+        if (this.condition != null)
+            this.condition.setParentNode(null);
+        this.condition = condition;
+        setAsParentNodeOf(condition);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ConditionalExpr setElseExpr(final Expression elseExpr) {
+        assertNotNull(elseExpr);
+        if (elseExpr == this.elseExpr) {
+            return (ConditionalExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.ELSE_EXPR, this.elseExpr, elseExpr);
+        if (this.elseExpr != null)
+            this.elseExpr.setParentNode(null);
+        this.elseExpr = elseExpr;
+        setAsParentNodeOf(elseExpr);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ConditionalExpr setThenExpr(final Expression thenExpr) {
+        assertNotNull(thenExpr);
+        if (thenExpr == this.thenExpr) {
+            return (ConditionalExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.THEN_EXPR, this.thenExpr, thenExpr);
+        if (this.thenExpr != null)
+            this.thenExpr.setParentNode(null);
+        this.thenExpr = thenExpr;
+        setAsParentNodeOf(thenExpr);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ConditionalExpr clone() {
+        return (ConditionalExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ConditionalExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.conditionalExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == condition) {
+            setCondition((Expression) replacementNode);
+            return true;
+        }
+        if (node == elseExpr) {
+            setElseExpr((Expression) replacementNode);
+            return true;
+        }
+        if (node == thenExpr) {
+            setThenExpr((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isConditionalExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ConditionalExpr asConditionalExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifConditionalExpr(Consumer<ConditionalExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ConditionalExpr> toConditionalExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/DoubleLiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/DoubleLiteralExpr.java
new file mode 100644
index 0000000..007fdf3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/DoubleLiteralExpr.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.DoubleLiteralExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A float or a double constant. This value is stored exactly as found in the source.
+ * <br/><code>100.1f</code>
+ * <br/><code>23958D</code>
+ * <br/><code>0x4.5p1f</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class DoubleLiteralExpr extends LiteralStringValueExpr {
+
+    public DoubleLiteralExpr() {
+        this(null, "0");
+    }
+
+    @AllFieldsConstructor
+    public DoubleLiteralExpr(final String value) {
+        this(null, value);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public DoubleLiteralExpr(TokenRange tokenRange, String value) {
+        super(tokenRange, value);
+        customInitialization();
+    }
+
+    public DoubleLiteralExpr(final double value) {
+        this(null, String.valueOf(value));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    /**
+     * @return the literal value as a double
+     */
+    public double asDouble() {
+        return Double.parseDouble(value);
+    }
+
+    public DoubleLiteralExpr setDouble(double value) {
+        this.value = String.valueOf(value);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public DoubleLiteralExpr clone() {
+        return (DoubleLiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public DoubleLiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.doubleLiteralExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isDoubleLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public DoubleLiteralExpr asDoubleLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifDoubleLiteralExpr(Consumer<DoubleLiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<DoubleLiteralExpr> toDoubleLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/EnclosedExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/EnclosedExpr.java
new file mode 100644
index 0000000..c3d56d8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/EnclosedExpr.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.EnclosedExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import java.util.function.Consumer;
+
+/**
+ * An expression between ( ).
+ * <br/><code>(1+1)</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class EnclosedExpr extends Expression {
+
+    private Expression inner;
+
+    public EnclosedExpr() {
+        this(null, new StringLiteralExpr());
+    }
+
+    @AllFieldsConstructor
+    public EnclosedExpr(final Expression inner) {
+        this(null, inner);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public EnclosedExpr(TokenRange tokenRange, Expression inner) {
+        super(tokenRange);
+        setInner(inner);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getInner() {
+        return inner;
+    }
+
+    /**
+     * Sets the inner expression
+     *
+     * @param inner the inner expression, can be null
+     * @return this, the EnclosedExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnclosedExpr setInner(final Expression inner) {
+        assertNotNull(inner);
+        if (inner == this.inner) {
+            return (EnclosedExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.INNER, this.inner, inner);
+        if (this.inner != null)
+            this.inner.setParentNode(null);
+        this.inner = inner;
+        setAsParentNodeOf(inner);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public EnclosedExpr removeInner() {
+        return setInner((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public EnclosedExpr clone() {
+        return (EnclosedExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public EnclosedExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.enclosedExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == inner) {
+            setInner((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEnclosedExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EnclosedExpr asEnclosedExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEnclosedExpr(Consumer<EnclosedExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EnclosedExpr> toEnclosedExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/Expression.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/Expression.java
new file mode 100644
index 0000000..de9e52b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/Expression.java
@@ -0,0 +1,733 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ExpressionMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedType;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import java.util.Optional;
+
+/**
+ * A base class for all expressions.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Expression extends Node {
+
+    @AllFieldsConstructor
+    public Expression() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public Expression(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public Expression clone() {
+        return (Expression) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ExpressionMetaModel getMetaModel() {
+        return JavaParserMetaModel.expressionMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAnnotationExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AnnotationExpr asAnnotationExpr() {
+        throw new IllegalStateException(f("%s is not an AnnotationExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayAccessExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayAccessExpr asArrayAccessExpr() {
+        throw new IllegalStateException(f("%s is not an ArrayAccessExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayCreationExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayCreationExpr asArrayCreationExpr() {
+        throw new IllegalStateException(f("%s is not an ArrayCreationExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayInitializerExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayInitializerExpr asArrayInitializerExpr() {
+        throw new IllegalStateException(f("%s is not an ArrayInitializerExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAssignExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AssignExpr asAssignExpr() {
+        throw new IllegalStateException(f("%s is not an AssignExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBinaryExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BinaryExpr asBinaryExpr() {
+        throw new IllegalStateException(f("%s is not an BinaryExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBooleanLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BooleanLiteralExpr asBooleanLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an BooleanLiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isCastExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public CastExpr asCastExpr() {
+        throw new IllegalStateException(f("%s is not an CastExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isCharLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public CharLiteralExpr asCharLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an CharLiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isClassExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ClassExpr asClassExpr() {
+        throw new IllegalStateException(f("%s is not an ClassExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isConditionalExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ConditionalExpr asConditionalExpr() {
+        throw new IllegalStateException(f("%s is not an ConditionalExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isDoubleLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public DoubleLiteralExpr asDoubleLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an DoubleLiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEnclosedExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EnclosedExpr asEnclosedExpr() {
+        throw new IllegalStateException(f("%s is not an EnclosedExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isFieldAccessExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public FieldAccessExpr asFieldAccessExpr() {
+        throw new IllegalStateException(f("%s is not an FieldAccessExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isInstanceOfExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public InstanceOfExpr asInstanceOfExpr() {
+        throw new IllegalStateException(f("%s is not an InstanceOfExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isIntegerLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public IntegerLiteralExpr asIntegerLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an IntegerLiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLambdaExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LambdaExpr asLambdaExpr() {
+        throw new IllegalStateException(f("%s is not an LambdaExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LiteralExpr asLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an LiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLiteralStringValueExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LiteralStringValueExpr asLiteralStringValueExpr() {
+        throw new IllegalStateException(f("%s is not an LiteralStringValueExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLongLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LongLiteralExpr asLongLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an LongLiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMarkerAnnotationExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MarkerAnnotationExpr asMarkerAnnotationExpr() {
+        throw new IllegalStateException(f("%s is not an MarkerAnnotationExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMethodCallExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MethodCallExpr asMethodCallExpr() {
+        throw new IllegalStateException(f("%s is not an MethodCallExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMethodReferenceExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MethodReferenceExpr asMethodReferenceExpr() {
+        throw new IllegalStateException(f("%s is not an MethodReferenceExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isNameExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public NameExpr asNameExpr() {
+        throw new IllegalStateException(f("%s is not an NameExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isNormalAnnotationExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public NormalAnnotationExpr asNormalAnnotationExpr() {
+        throw new IllegalStateException(f("%s is not an NormalAnnotationExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isNullLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public NullLiteralExpr asNullLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an NullLiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isObjectCreationExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ObjectCreationExpr asObjectCreationExpr() {
+        throw new IllegalStateException(f("%s is not an ObjectCreationExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSingleMemberAnnotationExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SingleMemberAnnotationExpr asSingleMemberAnnotationExpr() {
+        throw new IllegalStateException(f("%s is not an SingleMemberAnnotationExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isStringLiteralExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public StringLiteralExpr asStringLiteralExpr() {
+        throw new IllegalStateException(f("%s is not an StringLiteralExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSuperExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SuperExpr asSuperExpr() {
+        throw new IllegalStateException(f("%s is not an SuperExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isThisExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ThisExpr asThisExpr() {
+        throw new IllegalStateException(f("%s is not an ThisExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTypeExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TypeExpr asTypeExpr() {
+        throw new IllegalStateException(f("%s is not an TypeExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnaryExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnaryExpr asUnaryExpr() {
+        throw new IllegalStateException(f("%s is not an UnaryExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isVariableDeclarationExpr() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public VariableDeclarationExpr asVariableDeclarationExpr() {
+        throw new IllegalStateException(f("%s is not an VariableDeclarationExpr", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAnnotationExpr(Consumer<AnnotationExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayAccessExpr(Consumer<ArrayAccessExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayCreationExpr(Consumer<ArrayCreationExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayInitializerExpr(Consumer<ArrayInitializerExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAssignExpr(Consumer<AssignExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBinaryExpr(Consumer<BinaryExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBooleanLiteralExpr(Consumer<BooleanLiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifCastExpr(Consumer<CastExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifCharLiteralExpr(Consumer<CharLiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifClassExpr(Consumer<ClassExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifConditionalExpr(Consumer<ConditionalExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifDoubleLiteralExpr(Consumer<DoubleLiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEnclosedExpr(Consumer<EnclosedExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifFieldAccessExpr(Consumer<FieldAccessExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifInstanceOfExpr(Consumer<InstanceOfExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifIntegerLiteralExpr(Consumer<IntegerLiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLambdaExpr(Consumer<LambdaExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLiteralExpr(Consumer<LiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLiteralStringValueExpr(Consumer<LiteralStringValueExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLongLiteralExpr(Consumer<LongLiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMarkerAnnotationExpr(Consumer<MarkerAnnotationExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMethodCallExpr(Consumer<MethodCallExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMethodReferenceExpr(Consumer<MethodReferenceExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifNameExpr(Consumer<NameExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifNormalAnnotationExpr(Consumer<NormalAnnotationExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifNullLiteralExpr(Consumer<NullLiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifObjectCreationExpr(Consumer<ObjectCreationExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSingleMemberAnnotationExpr(Consumer<SingleMemberAnnotationExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifStringLiteralExpr(Consumer<StringLiteralExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSuperExpr(Consumer<SuperExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifThisExpr(Consumer<ThisExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTypeExpr(Consumer<TypeExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnaryExpr(Consumer<UnaryExpr> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifVariableDeclarationExpr(Consumer<VariableDeclarationExpr> action) {
+    }
+
+    public ResolvedType calculateResolvedType() {
+        return getSymbolResolver().calculateType(this);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AnnotationExpr> toAnnotationExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayAccessExpr> toArrayAccessExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayCreationExpr> toArrayCreationExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayInitializerExpr> toArrayInitializerExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AssignExpr> toAssignExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BinaryExpr> toBinaryExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BooleanLiteralExpr> toBooleanLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<CastExpr> toCastExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<CharLiteralExpr> toCharLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ClassExpr> toClassExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ConditionalExpr> toConditionalExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<DoubleLiteralExpr> toDoubleLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EnclosedExpr> toEnclosedExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<FieldAccessExpr> toFieldAccessExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<InstanceOfExpr> toInstanceOfExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<IntegerLiteralExpr> toIntegerLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LambdaExpr> toLambdaExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LiteralExpr> toLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LiteralStringValueExpr> toLiteralStringValueExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LongLiteralExpr> toLongLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MarkerAnnotationExpr> toMarkerAnnotationExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MethodCallExpr> toMethodCallExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MethodReferenceExpr> toMethodReferenceExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<NameExpr> toNameExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<NormalAnnotationExpr> toNormalAnnotationExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<NullLiteralExpr> toNullLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ObjectCreationExpr> toObjectCreationExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SingleMemberAnnotationExpr> toSingleMemberAnnotationExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<StringLiteralExpr> toStringLiteralExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SuperExpr> toSuperExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ThisExpr> toThisExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TypeExpr> toTypeExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnaryExpr> toUnaryExpr() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<VariableDeclarationExpr> toVariableDeclarationExpr() {
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/FieldAccessExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/FieldAccessExpr.java
new file mode 100644
index 0000000..c6b9e0a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/FieldAccessExpr.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithScope;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.FieldAccessExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import java.util.function.Consumer;
+
+/**
+ * Access of a field of an object.
+ * <br/>In <code>person.name</code> "name" is the name and "person" is the scope.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class FieldAccessExpr extends Expression implements NodeWithSimpleName<FieldAccessExpr>, NodeWithTypeArguments<FieldAccessExpr>, NodeWithScope<FieldAccessExpr> {
+
+    private Expression scope;
+
+    @OptionalProperty
+    private NodeList<Type> typeArguments;
+
+    private SimpleName name;
+
+    public FieldAccessExpr() {
+        this(null, new ThisExpr(), new NodeList<>(), new SimpleName());
+    }
+
+    public FieldAccessExpr(final Expression scope, final String name) {
+        this(null, scope, new NodeList<>(), new SimpleName(name));
+    }
+
+    @AllFieldsConstructor
+    public FieldAccessExpr(final Expression scope, final NodeList<Type> typeArguments, final SimpleName name) {
+        this(null, scope, typeArguments, name);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public FieldAccessExpr(TokenRange tokenRange, Expression scope, NodeList<Type> typeArguments, SimpleName name) {
+        super(tokenRange);
+        setScope(scope);
+        setTypeArguments(typeArguments);
+        setName(name);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public FieldAccessExpr setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (FieldAccessExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    /**
+     * Use {@link #getName} instead.
+     */
+    @Deprecated
+    public SimpleName getField() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getScope() {
+        return scope;
+    }
+
+    /**
+     * Use {@link #setName} with new SimpleName(field) instead.
+     */
+    @Deprecated
+    public FieldAccessExpr setField(final String field) {
+        setName(new SimpleName(field));
+        return this;
+    }
+
+    /**
+     * Use {@link #setName} instead.
+     */
+    @Deprecated
+    public FieldAccessExpr setFieldExpr(SimpleName inner) {
+        return setName(inner);
+    }
+
+    /**
+     * Sets the scope
+     *
+     * @param scope the scope, can not be null
+     * @return this, the FieldAccessExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public FieldAccessExpr setScope(final Expression scope) {
+        assertNotNull(scope);
+        if (scope == this.scope) {
+            return (FieldAccessExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.SCOPE, this.scope, scope);
+        if (this.scope != null)
+            this.scope.setParentNode(null);
+        this.scope = scope;
+        setAsParentNodeOf(scope);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<NodeList<Type>> getTypeArguments() {
+        return Optional.ofNullable(typeArguments);
+    }
+
+    /**
+     * Sets the type arguments
+     *
+     * @param typeArguments the type arguments, can be null
+     * @return this, the FieldAccessExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public FieldAccessExpr setTypeArguments(final NodeList<Type> typeArguments) {
+        if (typeArguments == this.typeArguments) {
+            return (FieldAccessExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_ARGUMENTS, this.typeArguments, typeArguments);
+        if (this.typeArguments != null)
+            this.typeArguments.setParentNode(null);
+        this.typeArguments = typeArguments;
+        setAsParentNodeOf(typeArguments);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public FieldAccessExpr clone() {
+        return (FieldAccessExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public FieldAccessExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.fieldAccessExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.remove(i);
+                    return true;
+                }
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        if (node == scope) {
+            setScope((Expression) replacementNode);
+            return true;
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.set(i, (Type) replacementNode);
+                    return true;
+                }
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isFieldAccessExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public FieldAccessExpr asFieldAccessExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifFieldAccessExpr(Consumer<FieldAccessExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<FieldAccessExpr> toFieldAccessExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/InstanceOfExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/InstanceOfExpr.java
new file mode 100644
index 0000000..69a505b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/InstanceOfExpr.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithExpression;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.InstanceOfExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Usage of the instanceof operator.
+ * <br/><code>tool instanceof Drill</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class InstanceOfExpr extends Expression implements NodeWithType<InstanceOfExpr, ReferenceType>, NodeWithExpression<InstanceOfExpr> {
+
+    private Expression expression;
+
+    private ReferenceType type;
+
+    public InstanceOfExpr() {
+        this(null, new NameExpr(), new ClassOrInterfaceType());
+    }
+
+    @AllFieldsConstructor
+    public InstanceOfExpr(final Expression expression, final ReferenceType type) {
+        this(null, expression, type);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public InstanceOfExpr(TokenRange tokenRange, Expression expression, ReferenceType type) {
+        super(tokenRange);
+        setExpression(expression);
+        setType(type);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getExpression() {
+        return expression;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ReferenceType getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public InstanceOfExpr setExpression(final Expression expression) {
+        assertNotNull(expression);
+        if (expression == this.expression) {
+            return (InstanceOfExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public InstanceOfExpr setType(final ReferenceType type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (InstanceOfExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public InstanceOfExpr clone() {
+        return (InstanceOfExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public InstanceOfExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.instanceOfExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == expression) {
+            setExpression((Expression) replacementNode);
+            return true;
+        }
+        if (node == type) {
+            setType((ReferenceType) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isInstanceOfExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public InstanceOfExpr asInstanceOfExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifInstanceOfExpr(Consumer<InstanceOfExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<InstanceOfExpr> toInstanceOfExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/IntegerLiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/IntegerLiteralExpr.java
new file mode 100644
index 0000000..a0d3949
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/IntegerLiteralExpr.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.IntegerLiteralExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * All ways to specify an int literal.
+ * <br/><code>8934</code>
+ * <br/><code>0x01</code>
+ * <br/><code>022</code>
+ * <br/><code>0B10101010</code>
+ * <br/><code>99999999L</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class IntegerLiteralExpr extends LiteralStringValueExpr {
+
+    public IntegerLiteralExpr() {
+        this(null, "0");
+    }
+
+    @AllFieldsConstructor
+    public IntegerLiteralExpr(final String value) {
+        this(null, value);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public IntegerLiteralExpr(TokenRange tokenRange, String value) {
+        super(tokenRange, value);
+        customInitialization();
+    }
+
+    public IntegerLiteralExpr(final int value) {
+        this(null, String.valueOf(value));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    /**
+     * @return the literal value as an integer while respecting different number representations
+     */
+    public int asInt() {
+        String result = value.replaceAll("_", "");
+        if (result.startsWith("0x") || result.startsWith("0X")) {
+            return Integer.parseUnsignedInt(result.substring(2), 16);
+        }
+        if (result.startsWith("0b") || result.startsWith("0B")) {
+            return Integer.parseUnsignedInt(result.substring(2), 2);
+        }
+        if (result.length() > 1 && result.startsWith("0")) {
+            return Integer.parseUnsignedInt(result.substring(1), 8);
+        }
+        return Integer.parseInt(result);
+    }
+
+    public IntegerLiteralExpr setInt(int value) {
+        this.value = String.valueOf(value);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public IntegerLiteralExpr clone() {
+        return (IntegerLiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public IntegerLiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.integerLiteralExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isIntegerLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public IntegerLiteralExpr asIntegerLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifIntegerLiteralExpr(Consumer<IntegerLiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<IntegerLiteralExpr> toIntegerLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LambdaExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LambdaExpr.java
new file mode 100644
index 0000000..a69176f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LambdaExpr.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.nodeTypes.NodeWithParameters;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.DerivedProperty;
+import com.github.javaparser.metamodel.LambdaExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+
+/**
+ * <h1>A lambda expression</h1>
+ * <h2>Java 1-7</h2>
+ * Does not exist.
+ * <h2>Java 8+</h2>
+ * <code>(a, b) -> a + b</code>
+ * <br/><code>a -> ...</code>
+ * <br/><code>(Long a) -> { println(a); }</code>
+ * <p/>The parameters are on the left side of the ->.
+ * If a parameter uses type inference (it has no type specified) then its type is set to <code>UnknownType</code>.
+ * If they are in ( ), "isEnclosingParameters" is true.
+ * <br/>The body is to the right of the ->.
+ * The body is either a BlockStatement when it is in { } braces, or an ExpressionStatement when it is not in braces.
+ *
+ * @author Raquel Pau
+ */
+public final class LambdaExpr extends Expression implements NodeWithParameters<LambdaExpr> {
+
+    private NodeList<Parameter> parameters;
+
+    private boolean isEnclosingParameters;
+
+    private Statement body;
+
+    public LambdaExpr() {
+        this(null, new NodeList<>(), new ReturnStmt(), false);
+    }
+
+    @AllFieldsConstructor
+    public LambdaExpr(NodeList<Parameter> parameters, Statement body, boolean isEnclosingParameters) {
+        this(null, parameters, body, isEnclosingParameters);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public LambdaExpr(TokenRange tokenRange, NodeList<Parameter> parameters, Statement body, boolean isEnclosingParameters) {
+        super(tokenRange);
+        setParameters(parameters);
+        setBody(body);
+        setEnclosingParameters(isEnclosingParameters);
+        customInitialization();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Parameter> getParameters() {
+        return parameters;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public LambdaExpr setParameters(final NodeList<Parameter> parameters) {
+        assertNotNull(parameters);
+        if (parameters == this.parameters) {
+            return (LambdaExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.PARAMETERS, this.parameters, parameters);
+        if (this.parameters != null)
+            this.parameters.setParentNode(null);
+        this.parameters = parameters;
+        setAsParentNodeOf(parameters);
+        return this;
+    }
+
+    /**
+     * @return a BlockStatement or an ExpressionStatement. See class Javadoc.
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Statement getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public LambdaExpr setBody(final Statement body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (LambdaExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isEnclosingParameters() {
+        return isEnclosingParameters;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public LambdaExpr setEnclosingParameters(final boolean isEnclosingParameters) {
+        if (isEnclosingParameters == this.isEnclosingParameters) {
+            return (LambdaExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.ENCLOSING_PARAMETERS, this.isEnclosingParameters, isEnclosingParameters);
+        this.isEnclosingParameters = isEnclosingParameters;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < parameters.size(); i++) {
+            if (parameters.get(i) == node) {
+                parameters.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    /**
+     * @return if the body of this lambda is a simple expression, return that expression.
+     * Otherwise (when the body is a block) return Optional.empty().
+     */
+    @DerivedProperty
+    public Optional<Expression> getExpressionBody() {
+        if (body.isExpressionStmt()) {
+            return Optional.of(body.asExpressionStmt().getExpression());
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public LambdaExpr clone() {
+        return (LambdaExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public LambdaExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.lambdaExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((Statement) replacementNode);
+            return true;
+        }
+        for (int i = 0; i < parameters.size(); i++) {
+            if (parameters.get(i) == node) {
+                parameters.set(i, (Parameter) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLambdaExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LambdaExpr asLambdaExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLambdaExpr(Consumer<LambdaExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LambdaExpr> toLambdaExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LiteralExpr.java
new file mode 100644
index 0000000..2c81560
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LiteralExpr.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.LiteralExprMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A base class for all literal expressions.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class LiteralExpr extends Expression {
+
+    @AllFieldsConstructor
+    public LiteralExpr() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public LiteralExpr(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public LiteralExpr clone() {
+        return (LiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public LiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.literalExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LiteralExpr asLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLiteralExpr(Consumer<LiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LiteralExpr> toLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LiteralStringValueExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LiteralStringValueExpr.java
new file mode 100644
index 0000000..4956146
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LiteralStringValueExpr.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.LiteralStringValueExprMetaModel;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Any literal value that is stored internally as a String.
+ */
+public abstract class LiteralStringValueExpr extends LiteralExpr {
+
+    protected String value;
+
+    @AllFieldsConstructor
+    public LiteralStringValueExpr(final String value) {
+        this(null, value);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public LiteralStringValueExpr(TokenRange tokenRange, String value) {
+        super(tokenRange);
+        setValue(value);
+        customInitialization();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public String getValue() {
+        return value;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public LiteralStringValueExpr setValue(final String value) {
+        assertNotNull(value);
+        if (value == this.value) {
+            return (LiteralStringValueExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.VALUE, this.value, value);
+        this.value = value;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public LiteralStringValueExpr clone() {
+        return (LiteralStringValueExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public LiteralStringValueExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.literalStringValueExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLiteralStringValueExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LiteralStringValueExpr asLiteralStringValueExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLiteralStringValueExpr(Consumer<LiteralStringValueExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LiteralStringValueExpr> toLiteralStringValueExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LongLiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LongLiteralExpr.java
new file mode 100644
index 0000000..d15442f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/LongLiteralExpr.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.LongLiteralExprMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * All ways to specify a long literal.
+ * <br/><code>8934l</code>
+ * <br/><code>0x01L</code>
+ * <br/><code>022l</code>
+ * <br/><code>0B10101010L</code>
+ * <br/><code>99999999L</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class LongLiteralExpr extends LiteralStringValueExpr {
+
+    public LongLiteralExpr() {
+        this(null, "0");
+    }
+
+    @AllFieldsConstructor
+    public LongLiteralExpr(final String value) {
+        this(null, value);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public LongLiteralExpr(TokenRange tokenRange, String value) {
+        super(tokenRange, value);
+        customInitialization();
+    }
+
+    public LongLiteralExpr(final long value) {
+        this(null, String.valueOf(value));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    /**
+     * @return the literal value as an long while respecting different number representations
+     */
+    public long asLong() {
+        String result = value.replaceAll("_", "");
+        char lastChar = result.charAt(result.length() - 1);
+        if (lastChar == 'l' || lastChar == 'L') {
+            result = result.substring(0, result.length() - 1);
+        }
+        if (result.startsWith("0x") || result.startsWith("0X")) {
+            return Long.parseUnsignedLong(result.substring(2), 16);
+        }
+        if (result.startsWith("0b") || result.startsWith("0B")) {
+            return Long.parseUnsignedLong(result.substring(2), 2);
+        }
+        if (result.length() > 1 && result.startsWith("0")) {
+            return Long.parseUnsignedLong(result.substring(1), 8);
+        }
+        return Long.parseLong(result);
+    }
+
+    public LongLiteralExpr setLong(long value) {
+        this.value = String.valueOf(value);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public LongLiteralExpr clone() {
+        return (LongLiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public LongLiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.longLiteralExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLongLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LongLiteralExpr asLongLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLongLiteralExpr(Consumer<LongLiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LongLiteralExpr> toLongLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java
new file mode 100644
index 0000000..e9ab894
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.MarkerAnnotationExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import static com.github.javaparser.JavaParser.parseName;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An annotation that uses only the annotation type name.
+ * <br/><code>@Override</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class MarkerAnnotationExpr extends AnnotationExpr {
+
+    public MarkerAnnotationExpr() {
+        this(null, new Name());
+    }
+
+    public MarkerAnnotationExpr(final String name) {
+        this(null, parseName(name));
+    }
+
+    @AllFieldsConstructor
+    public MarkerAnnotationExpr(final Name name) {
+        this(null, name);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public MarkerAnnotationExpr(TokenRange tokenRange, Name name) {
+        super(tokenRange, name);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public MarkerAnnotationExpr clone() {
+        return (MarkerAnnotationExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public MarkerAnnotationExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.markerAnnotationExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMarkerAnnotationExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MarkerAnnotationExpr asMarkerAnnotationExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMarkerAnnotationExpr(Consumer<MarkerAnnotationExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MarkerAnnotationExpr> toMarkerAnnotationExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MemberValuePair.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MemberValuePair.java
new file mode 100644
index 0000000..8accb7b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MemberValuePair.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.MemberValuePairMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+
+/**
+ * A value for a member of an annotation.
+ * In <code>@Counters(a=15)</code> a=15 is a MemberValuePair. Its name is a, and its value is 15.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class MemberValuePair extends Node implements NodeWithSimpleName<MemberValuePair> {
+
+    private SimpleName name;
+
+    private Expression value;
+
+    public MemberValuePair() {
+        this(null, new SimpleName(), new StringLiteralExpr());
+    }
+
+    public MemberValuePair(final String name, final Expression value) {
+        this(null, new SimpleName(name), value);
+    }
+
+    @AllFieldsConstructor
+    public MemberValuePair(final SimpleName name, final Expression value) {
+        this(null, name, value);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public MemberValuePair(TokenRange tokenRange, SimpleName name, Expression value) {
+        super(tokenRange);
+        setName(name);
+        setValue(value);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getValue() {
+        return value;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MemberValuePair setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (MemberValuePair) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MemberValuePair setValue(final Expression value) {
+        assertNotNull(value);
+        if (value == this.value) {
+            return (MemberValuePair) this;
+        }
+        notifyPropertyChange(ObservableProperty.VALUE, this.value, value);
+        if (this.value != null)
+            this.value.setParentNode(null);
+        this.value = value;
+        setAsParentNodeOf(value);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public MemberValuePair clone() {
+        return (MemberValuePair) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public MemberValuePairMetaModel getMetaModel() {
+        return JavaParserMetaModel.memberValuePairMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        if (node == value) {
+            setValue((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MethodCallExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MethodCallExpr.java
new file mode 100644
index 0000000..dc914c9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MethodCallExpr.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithOptionalScope;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.MethodCallExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.resolution.SymbolResolver;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import java.util.function.Consumer;
+
+/**
+ * A method call on an object. <br/><code>circle.circumference()</code> <br/>In <code>a.&lt;String&gt;bb(15);</code> a
+ * is the scope, String is a type argument, bb is the name and 15 is an argument.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class MethodCallExpr extends Expression implements NodeWithTypeArguments<MethodCallExpr>, NodeWithArguments<MethodCallExpr>, NodeWithSimpleName<MethodCallExpr>, NodeWithOptionalScope<MethodCallExpr> {
+
+    @OptionalProperty
+    private Expression scope;
+
+    @OptionalProperty
+    private NodeList<Type> typeArguments;
+
+    private SimpleName name;
+
+    private NodeList<Expression> arguments;
+
+    public MethodCallExpr() {
+        this(null, null, new NodeList<>(), new SimpleName(), new NodeList<>());
+    }
+
+    public MethodCallExpr(String name, Expression... arguments) {
+        this(null, null, new NodeList<>(), new SimpleName(name), new NodeList<>(arguments));
+    }
+
+    public MethodCallExpr(final Expression scope, final String name) {
+        this(null, scope, new NodeList<>(), new SimpleName(name), new NodeList<>());
+    }
+
+    public MethodCallExpr(final Expression scope, final SimpleName name) {
+        this(null, scope, new NodeList<>(), name, new NodeList<>());
+    }
+
+    public MethodCallExpr(final Expression scope, final String name, final NodeList<Expression> arguments) {
+        this(null, scope, new NodeList<>(), new SimpleName(name), arguments);
+    }
+
+    public MethodCallExpr(final Expression scope, final SimpleName name, final NodeList<Expression> arguments) {
+        this(null, scope, new NodeList<>(), name, arguments);
+    }
+
+    @AllFieldsConstructor
+    public MethodCallExpr(final Expression scope, final NodeList<Type> typeArguments, final SimpleName name, final NodeList<Expression> arguments) {
+        this(null, scope, typeArguments, name, arguments);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public MethodCallExpr(TokenRange tokenRange, Expression scope, NodeList<Type> typeArguments, SimpleName name, NodeList<Expression> arguments) {
+        super(tokenRange);
+        setScope(scope);
+        setTypeArguments(typeArguments);
+        setName(name);
+        setArguments(arguments);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getArguments() {
+        return arguments;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getScope() {
+        return Optional.ofNullable(scope);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodCallExpr setArguments(final NodeList<Expression> arguments) {
+        assertNotNull(arguments);
+        if (arguments == this.arguments) {
+            return (MethodCallExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.ARGUMENTS, this.arguments, arguments);
+        if (this.arguments != null)
+            this.arguments.setParentNode(null);
+        this.arguments = arguments;
+        setAsParentNodeOf(arguments);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodCallExpr setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (MethodCallExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodCallExpr setScope(final Expression scope) {
+        if (scope == this.scope) {
+            return (MethodCallExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.SCOPE, this.scope, scope);
+        if (this.scope != null)
+            this.scope.setParentNode(null);
+        this.scope = scope;
+        setAsParentNodeOf(scope);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<NodeList<Type>> getTypeArguments() {
+        return Optional.ofNullable(typeArguments);
+    }
+
+    /**
+     * Sets the typeArguments
+     *
+     * @param typeArguments the typeArguments, can be null
+     * @return this, the MethodCallExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodCallExpr setTypeArguments(final NodeList<Type> typeArguments) {
+        if (typeArguments == this.typeArguments) {
+            return (MethodCallExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_ARGUMENTS, this.typeArguments, typeArguments);
+        if (this.typeArguments != null)
+            this.typeArguments.setParentNode(null);
+        this.typeArguments = typeArguments;
+        setAsParentNodeOf(typeArguments);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.remove(i);
+                return true;
+            }
+        }
+        if (scope != null) {
+            if (node == scope) {
+                removeScope();
+                return true;
+            }
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.remove(i);
+                    return true;
+                }
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public MethodCallExpr removeScope() {
+        return setScope((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public MethodCallExpr clone() {
+        return (MethodCallExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public MethodCallExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.methodCallExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        if (scope != null) {
+            if (node == scope) {
+                setScope((Expression) replacementNode);
+                return true;
+            }
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.set(i, (Type) replacementNode);
+                    return true;
+                }
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMethodCallExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MethodCallExpr asMethodCallExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMethodCallExpr(Consumer<MethodCallExpr> action) {
+        action.accept(this);
+    }
+
+    public ResolvedMethodDeclaration resolveInvokedMethod() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedMethodDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MethodCallExpr> toMethodCallExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MethodReferenceExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MethodReferenceExpr.java
new file mode 100644
index 0000000..8ddaac00
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/MethodReferenceExpr.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithIdentifier;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.MethodReferenceExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import java.util.function.Consumer;
+
+/**
+ * Method reference expressions introduced in Java 8 specifically designed to simplify lambda Expressions.
+ * Note that the field "identifier", indicating the word to the right of the ::, is not always a method name,
+ * it can be "new".
+ * <br/>In <code>System.out::println;</code> the scope is System.out and the identifier is "println"
+ * <br/><code>(test ? stream.map(String::trim) : stream)::toArray;</code>
+ * <br/>In <code>Bar&lt;String>::&lt;Integer>new</code> the String type argument is on the scope,
+ * and the Integer type argument is on this MethodReferenceExpr.
+ *
+ * @author Raquel Pau
+ */
+public final class MethodReferenceExpr extends Expression implements NodeWithTypeArguments<MethodReferenceExpr>, NodeWithIdentifier<MethodReferenceExpr> {
+
+    private Expression scope;
+
+    @OptionalProperty
+    private NodeList<Type> typeArguments;
+
+    @NonEmptyProperty
+    private String identifier;
+
+    public MethodReferenceExpr() {
+        this(null, new ClassExpr(), null, "empty");
+    }
+
+    @AllFieldsConstructor
+    public MethodReferenceExpr(Expression scope, NodeList<Type> typeArguments, String identifier) {
+        this(null, scope, typeArguments, identifier);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public MethodReferenceExpr(TokenRange tokenRange, Expression scope, NodeList<Type> typeArguments, String identifier) {
+        super(tokenRange);
+        setScope(scope);
+        setTypeArguments(typeArguments);
+        setIdentifier(identifier);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getScope() {
+        return scope;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodReferenceExpr setScope(final Expression scope) {
+        assertNotNull(scope);
+        if (scope == this.scope) {
+            return (MethodReferenceExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.SCOPE, this.scope, scope);
+        if (this.scope != null)
+            this.scope.setParentNode(null);
+        this.scope = scope;
+        setAsParentNodeOf(scope);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<NodeList<Type>> getTypeArguments() {
+        return Optional.ofNullable(typeArguments);
+    }
+
+    /**
+     * Sets the typeArguments
+     *
+     * @param typeArguments the typeArguments, can be null
+     * @return this, the MethodReferenceExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodReferenceExpr setTypeArguments(final NodeList<Type> typeArguments) {
+        if (typeArguments == this.typeArguments) {
+            return (MethodReferenceExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_ARGUMENTS, this.typeArguments, typeArguments);
+        if (this.typeArguments != null)
+            this.typeArguments.setParentNode(null);
+        this.typeArguments = typeArguments;
+        setAsParentNodeOf(typeArguments);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public MethodReferenceExpr setIdentifier(final String identifier) {
+        assertNonEmpty(identifier);
+        if (identifier == this.identifier) {
+            return (MethodReferenceExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.IDENTIFIER, this.identifier, identifier);
+        this.identifier = identifier;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.remove(i);
+                    return true;
+                }
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public MethodReferenceExpr clone() {
+        return (MethodReferenceExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public MethodReferenceExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.methodReferenceExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == scope) {
+            setScope((Expression) replacementNode);
+            return true;
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.set(i, (Type) replacementNode);
+                    return true;
+                }
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isMethodReferenceExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public MethodReferenceExpr asMethodReferenceExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifMethodReferenceExpr(Consumer<MethodReferenceExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<MethodReferenceExpr> toMethodReferenceExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/Name.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/Name.java
new file mode 100644
index 0000000..0eeabd3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/Name.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithIdentifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.NameMetaModel;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+
+/**
+ * A name that may consist of multiple identifiers.
+ * In other words: it.may.contain.dots.
+ * <p>
+ * The rightmost identifier is "identifier",
+ * The one to the left of it is "qualifier.identifier", etc.
+ * <p>
+ * You can construct one from a String with the name(...) method.
+ *
+ * @author Julio Vilmar Gesser
+ * @see SimpleName
+ */
+public final class Name extends Node implements NodeWithIdentifier<Name>, NodeWithAnnotations<Name> {
+
+    @NonEmptyProperty
+    private String identifier;
+
+    @OptionalProperty
+    private Name qualifier;
+
+    private NodeList<AnnotationExpr> annotations;
+
+    public Name() {
+        this(null, null, "empty", new NodeList<>());
+    }
+
+    public Name(final String identifier) {
+        this(null, null, identifier, new NodeList<>());
+    }
+
+    public Name(Name qualifier, final String identifier) {
+        this(null, qualifier, identifier, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public Name(Name qualifier, final String identifier, NodeList<AnnotationExpr> annotations) {
+        this(null, qualifier, identifier, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public Name(TokenRange tokenRange, Name qualifier, String identifier, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange);
+        setQualifier(qualifier);
+        setIdentifier(identifier);
+        setAnnotations(annotations);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name setIdentifier(final String identifier) {
+        assertNonEmpty(identifier);
+        if (identifier == this.identifier) {
+            return (Name) this;
+        }
+        notifyPropertyChange(ObservableProperty.IDENTIFIER, this.identifier, identifier);
+        this.identifier = identifier;
+        return this;
+    }
+
+    /**
+     * Creates a new {@link Name} from a qualified name.<br>
+     * The qualified name can contains "." (dot) characters.
+     *
+     * @param qualifiedName qualified name
+     * @return instanceof {@link Name}
+     * @deprecated use JavaParser.parseName instead
+     */
+    @Deprecated
+    public static Name parse(String qualifiedName) {
+        assertNonEmpty(qualifiedName);
+        return JavaParser.parseName(qualifiedName);
+    }
+
+    /**
+     * @return the complete qualified name. Only the identifiers and the dots, so no comments or whitespace.
+     */
+    public String asString() {
+        if (qualifier != null) {
+            return qualifier.asString() + "." + identifier;
+        }
+        return identifier;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Name> getQualifier() {
+        return Optional.ofNullable(qualifier);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name setQualifier(final Name qualifier) {
+        if (qualifier == this.qualifier) {
+            return (Name) this;
+        }
+        notifyPropertyChange(ObservableProperty.QUALIFIER, this.qualifier, qualifier);
+        if (this.qualifier != null)
+            this.qualifier.setParentNode(null);
+        this.qualifier = qualifier;
+        setAsParentNodeOf(qualifier);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        if (qualifier != null) {
+            if (node == qualifier) {
+                removeQualifier();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public Name removeQualifier() {
+        return setQualifier((Name) null);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (Name) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public Name clone() {
+        return (Name) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public NameMetaModel getMetaModel() {
+        return JavaParserMetaModel.nameMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        if (qualifier != null) {
+            if (node == qualifier) {
+                setQualifier((Name) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NameExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NameExpr.java
new file mode 100644
index 0000000..d871589
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NameExpr.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.NameExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Whenever a SimpleName is used in an expression, it is wrapped in NameExpr.
+ * <br/>In <code>int x = a + 3;</code> a is a SimpleName inside a NameExpr.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class NameExpr extends Expression implements NodeWithSimpleName<NameExpr>, Resolvable<ResolvedValueDeclaration> {
+
+    private SimpleName name;
+
+    public NameExpr() {
+        this(null, new SimpleName());
+    }
+
+    public NameExpr(final String name) {
+        this(null, new SimpleName(name));
+    }
+
+    @AllFieldsConstructor
+    public NameExpr(final SimpleName name) {
+        this(name.getTokenRange().orElse(null), name);
+        setRange(name.getRange().orElse(null));
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public NameExpr(TokenRange tokenRange, SimpleName name) {
+        super(tokenRange);
+        setName(name);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NameExpr setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (NameExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public NameExpr clone() {
+        return (NameExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public NameExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.nameExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isNameExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public NameExpr asNameExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifNameExpr(Consumer<NameExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedValueDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedValueDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<NameExpr> toNameExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NormalAnnotationExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NormalAnnotationExpr.java
new file mode 100644
index 0000000..dd0fce5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NormalAnnotationExpr.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.NormalAnnotationExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An annotation that has zero or more key-value pairs.<br/><code>@Mapping(a=5, d=10)</code>
+ * @author Julio Vilmar Gesser
+ */
+public final class NormalAnnotationExpr extends AnnotationExpr {
+
+    private NodeList<MemberValuePair> pairs;
+
+    public NormalAnnotationExpr() {
+        this(null, new Name(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public NormalAnnotationExpr(final Name name, final NodeList<MemberValuePair> pairs) {
+        this(null, name, pairs);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public NormalAnnotationExpr(TokenRange tokenRange, Name name, NodeList<MemberValuePair> pairs) {
+        super(tokenRange, name);
+        setPairs(pairs);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<MemberValuePair> getPairs() {
+        return pairs;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NormalAnnotationExpr setPairs(final NodeList<MemberValuePair> pairs) {
+        assertNotNull(pairs);
+        if (pairs == this.pairs) {
+            return (NormalAnnotationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.PAIRS, this.pairs, pairs);
+        if (this.pairs != null)
+            this.pairs.setParentNode(null);
+        this.pairs = pairs;
+        setAsParentNodeOf(pairs);
+        return this;
+    }
+
+    /**
+     * adds a pair to this annotation
+     *
+     * @return this, the {@link NormalAnnotationExpr}
+     */
+    public NormalAnnotationExpr addPair(String key, String value) {
+        return addPair(key, new NameExpr(value));
+    }
+
+    /**
+     * adds a pair to this annotation
+     *
+     * @return this, the {@link NormalAnnotationExpr}
+     */
+    public NormalAnnotationExpr addPair(String key, NameExpr value) {
+        MemberValuePair memberValuePair = new MemberValuePair(key, value);
+        getPairs().add(memberValuePair);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < pairs.size(); i++) {
+            if (pairs.get(i) == node) {
+                pairs.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public NormalAnnotationExpr clone() {
+        return (NormalAnnotationExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public NormalAnnotationExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.normalAnnotationExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < pairs.size(); i++) {
+            if (pairs.get(i) == node) {
+                pairs.set(i, (MemberValuePair) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isNormalAnnotationExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public NormalAnnotationExpr asNormalAnnotationExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifNormalAnnotationExpr(Consumer<NormalAnnotationExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<NormalAnnotationExpr> toNormalAnnotationExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NullLiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NullLiteralExpr.java
new file mode 100644
index 0000000..b71ed5b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/NullLiteralExpr.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.NullLiteralExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A literal "null".
+ * <br/><code>null</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class NullLiteralExpr extends LiteralExpr {
+
+    @AllFieldsConstructor
+    public NullLiteralExpr() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public NullLiteralExpr(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public NullLiteralExpr clone() {
+        return (NullLiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public NullLiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.nullLiteralExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isNullLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public NullLiteralExpr asNullLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifNullLiteralExpr(Consumer<NullLiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<NullLiteralExpr> toNullLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ObjectCreationExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ObjectCreationExpr.java
new file mode 100644
index 0000000..c4fe045
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ObjectCreationExpr.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.nodeTypes.NodeWithArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithOptionalScope;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ObjectCreationExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import java.util.function.Consumer;
+
+/**
+ * A constructor call.
+ * <br/>In <code>new HashMap.Entry&lt;String, Long>(15) {public String getKey() {return null;}};</code>
+ * HashMap.Entry is the type, String and Long are type arguments, 15 is an argument, and everything in { }
+ * is the anonymous class body.
+ * <p/>In <code>class B { class C { public void a() { new B().new C(); } } }</code> the scope is <code>new B()</code>
+ * of ObjectCreationExpr <code>new B().new C()</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ObjectCreationExpr extends Expression implements NodeWithTypeArguments<ObjectCreationExpr>, NodeWithType<ObjectCreationExpr, ClassOrInterfaceType>, NodeWithArguments<ObjectCreationExpr>, NodeWithOptionalScope<ObjectCreationExpr> {
+
+    @OptionalProperty
+    private Expression scope;
+
+    private ClassOrInterfaceType type;
+
+    @OptionalProperty
+    private NodeList<Type> typeArguments;
+
+    private NodeList<Expression> arguments;
+
+    @OptionalProperty
+    private NodeList<BodyDeclaration<?>> anonymousClassBody;
+
+    public ObjectCreationExpr() {
+        this(null, null, new ClassOrInterfaceType(), new NodeList<>(), new NodeList<>(), null);
+    }
+
+    /**
+     * Defines a call to a constructor.
+     *
+     * @param scope may be null
+     * @param type this is the class that the constructor is being called for.
+     * @param arguments Any arguments to pass to the constructor
+     */
+    public ObjectCreationExpr(final Expression scope, final ClassOrInterfaceType type, final NodeList<Expression> arguments) {
+        this(null, scope, type, new NodeList<>(), arguments, null);
+    }
+
+    @AllFieldsConstructor
+    public ObjectCreationExpr(final Expression scope, final ClassOrInterfaceType type, final NodeList<Type> typeArguments, final NodeList<Expression> arguments, final NodeList<BodyDeclaration<?>> anonymousClassBody) {
+        this(null, scope, type, typeArguments, arguments, anonymousClassBody);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ObjectCreationExpr(TokenRange tokenRange, Expression scope, ClassOrInterfaceType type, NodeList<Type> typeArguments, NodeList<Expression> arguments, NodeList<BodyDeclaration<?>> anonymousClassBody) {
+        super(tokenRange);
+        setScope(scope);
+        setType(type);
+        setTypeArguments(typeArguments);
+        setArguments(arguments);
+        setAnonymousClassBody(anonymousClassBody);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<NodeList<BodyDeclaration<?>>> getAnonymousClassBody() {
+        return Optional.ofNullable(anonymousClassBody);
+    }
+
+    public void addAnonymousClassBody(BodyDeclaration<?> body) {
+        if (anonymousClassBody == null)
+            anonymousClassBody = new NodeList<>();
+        anonymousClassBody.add(body);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getArguments() {
+        return arguments;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getScope() {
+        return Optional.ofNullable(scope);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceType getType() {
+        return type;
+    }
+
+    /**
+     * Sets the anonymousClassBody<br>
+     * Null means no class body<br>
+     * Empty NodeList means new ClassName(){ }
+     *
+     * @param anonymousClassBody the anonymousClassBody, can be null or empty
+     * @return this, the ObjectCreationExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ObjectCreationExpr setAnonymousClassBody(final NodeList<BodyDeclaration<?>> anonymousClassBody) {
+        if (anonymousClassBody == this.anonymousClassBody) {
+            return (ObjectCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANONYMOUS_CLASS_BODY, this.anonymousClassBody, anonymousClassBody);
+        if (this.anonymousClassBody != null)
+            this.anonymousClassBody.setParentNode(null);
+        this.anonymousClassBody = anonymousClassBody;
+        setAsParentNodeOf(anonymousClassBody);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ObjectCreationExpr setArguments(final NodeList<Expression> arguments) {
+        assertNotNull(arguments);
+        if (arguments == this.arguments) {
+            return (ObjectCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.ARGUMENTS, this.arguments, arguments);
+        if (this.arguments != null)
+            this.arguments.setParentNode(null);
+        this.arguments = arguments;
+        setAsParentNodeOf(arguments);
+        return this;
+    }
+
+    /**
+     * Sets the scope
+     *
+     * @param scope the scope, can be null
+     * @return this, the ObjectCreationExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ObjectCreationExpr setScope(final Expression scope) {
+        if (scope == this.scope) {
+            return (ObjectCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.SCOPE, this.scope, scope);
+        if (this.scope != null)
+            this.scope.setParentNode(null);
+        this.scope = scope;
+        setAsParentNodeOf(scope);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ObjectCreationExpr setType(final ClassOrInterfaceType type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (ObjectCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<NodeList<Type>> getTypeArguments() {
+        return Optional.ofNullable(typeArguments);
+    }
+
+    /**
+     * Sets the typeArguments
+     *
+     * @param typeArguments the typeArguments, can be null
+     * @return this, the ObjectCreationExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ObjectCreationExpr setTypeArguments(final NodeList<Type> typeArguments) {
+        if (typeArguments == this.typeArguments) {
+            return (ObjectCreationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_ARGUMENTS, this.typeArguments, typeArguments);
+        if (this.typeArguments != null)
+            this.typeArguments.setParentNode(null);
+        this.typeArguments = typeArguments;
+        setAsParentNodeOf(typeArguments);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (anonymousClassBody != null) {
+            for (int i = 0; i < anonymousClassBody.size(); i++) {
+                if (anonymousClassBody.get(i) == node) {
+                    anonymousClassBody.remove(i);
+                    return true;
+                }
+            }
+        }
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.remove(i);
+                return true;
+            }
+        }
+        if (scope != null) {
+            if (node == scope) {
+                removeScope();
+                return true;
+            }
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.remove(i);
+                    return true;
+                }
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ObjectCreationExpr removeScope() {
+        return setScope((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ObjectCreationExpr clone() {
+        return (ObjectCreationExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ObjectCreationExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.objectCreationExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (anonymousClassBody != null) {
+            for (int i = 0; i < anonymousClassBody.size(); i++) {
+                if (anonymousClassBody.get(i) == node) {
+                    anonymousClassBody.set(i, (BodyDeclaration) replacementNode);
+                    return true;
+                }
+            }
+        }
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        if (scope != null) {
+            if (node == scope) {
+                setScope((Expression) replacementNode);
+                return true;
+            }
+        }
+        if (node == type) {
+            setType((ClassOrInterfaceType) replacementNode);
+            return true;
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.set(i, (Type) replacementNode);
+                    return true;
+                }
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isObjectCreationExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ObjectCreationExpr asObjectCreationExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifObjectCreationExpr(Consumer<ObjectCreationExpr> action) {
+        action.accept(this);
+    }
+
+    public ResolvedConstructorDeclaration resolveInvokedConstructor() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedConstructorDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ObjectCreationExpr> toObjectCreationExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SimpleName.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SimpleName.java
new file mode 100644
index 0000000..faaa541
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SimpleName.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithIdentifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import com.github.javaparser.metamodel.SimpleNameMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+
+/**
+ * A name that consists of a single identifier.
+ * In other words: it.does.NOT.contain.dots.
+ *
+ * @see Name
+ */
+public final class SimpleName extends Node implements NodeWithIdentifier<SimpleName> {
+
+    @NonEmptyProperty
+    private String identifier;
+
+    public SimpleName() {
+        this(null, "empty");
+    }
+
+    @AllFieldsConstructor
+    public SimpleName(final String identifier) {
+        this(null, identifier);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public SimpleName(TokenRange tokenRange, String identifier) {
+        super(tokenRange);
+        setIdentifier(identifier);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName setIdentifier(final String identifier) {
+        assertNonEmpty(identifier);
+        if (identifier == this.identifier) {
+            return (SimpleName) this;
+        }
+        notifyPropertyChange(ObservableProperty.IDENTIFIER, this.identifier, identifier);
+        this.identifier = identifier;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    public String asString() {
+        return identifier;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public SimpleName clone() {
+        return (SimpleName) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public SimpleNameMetaModel getMetaModel() {
+        return JavaParserMetaModel.simpleNameMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java
new file mode 100644
index 0000000..679c714
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.SingleMemberAnnotationExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An annotation that has a single value. <br/><code>@Count(15)</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class SingleMemberAnnotationExpr extends AnnotationExpr {
+
+    private Expression memberValue;
+
+    public SingleMemberAnnotationExpr() {
+        this(null, new Name(), new StringLiteralExpr());
+    }
+
+    @AllFieldsConstructor
+    public SingleMemberAnnotationExpr(final Name name, final Expression memberValue) {
+        this(null, name, memberValue);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public SingleMemberAnnotationExpr(TokenRange tokenRange, Name name, Expression memberValue) {
+        super(tokenRange, name);
+        setMemberValue(memberValue);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getMemberValue() {
+        return memberValue;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SingleMemberAnnotationExpr setMemberValue(final Expression memberValue) {
+        assertNotNull(memberValue);
+        if (memberValue == this.memberValue) {
+            return (SingleMemberAnnotationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.MEMBER_VALUE, this.memberValue, memberValue);
+        if (this.memberValue != null)
+            this.memberValue.setParentNode(null);
+        this.memberValue = memberValue;
+        setAsParentNodeOf(memberValue);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public SingleMemberAnnotationExpr clone() {
+        return (SingleMemberAnnotationExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public SingleMemberAnnotationExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.singleMemberAnnotationExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == memberValue) {
+            setMemberValue((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSingleMemberAnnotationExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SingleMemberAnnotationExpr asSingleMemberAnnotationExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSingleMemberAnnotationExpr(Consumer<SingleMemberAnnotationExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SingleMemberAnnotationExpr> toSingleMemberAnnotationExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/StringLiteralExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/StringLiteralExpr.java
new file mode 100644
index 0000000..a7b4dd5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/StringLiteralExpr.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.StringLiteralExprMetaModel;
+import com.github.javaparser.utils.StringEscapeUtils;
+import com.github.javaparser.utils.Utils;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A literal string.
+ * <br/><code>"Hello World!"</code>
+ * <br/><code>"\"\n"</code>
+ * <br/><code>"\u2122"</code>
+ * <br/><code>"™"</code>
+ * <br/><code>"💩"</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class StringLiteralExpr extends LiteralStringValueExpr {
+
+    public StringLiteralExpr() {
+        this(null, "empty");
+    }
+
+    /**
+     * Creates a string literal expression from given string. Escapes EOL characters.
+     *
+     * @param value the value of the literal
+     */
+    @AllFieldsConstructor
+    public StringLiteralExpr(final String value) {
+        this(null, Utils.escapeEndOfLines(value));
+    }
+
+    /**
+     * Utility method that creates a new StringLiteralExpr. Escapes EOL characters.
+     *
+     * @deprecated Use {@link #StringLiteralExpr(String)} instead.
+     */
+    @Deprecated
+    public static StringLiteralExpr escape(String string) {
+        return new StringLiteralExpr(Utils.escapeEndOfLines(string));
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public StringLiteralExpr(TokenRange tokenRange, String value) {
+        super(tokenRange, value);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    /**
+     * Sets the content of this expressions to given value. Escapes EOL characters.
+     *
+     * @param value the new literal value
+     * @return self
+     */
+    public StringLiteralExpr setEscapedValue(String value) {
+        this.value = Utils.escapeEndOfLines(value);
+        return this;
+    }
+
+    /**
+     * @return the unescaped literal value
+     */
+    public String asString() {
+        return StringEscapeUtils.unescapeJava(value);
+    }
+
+    /**
+     * Escapes the given string from special characters and uses it as the literal value.
+     *
+     * @param value unescaped string
+     * @return this literal expression
+     */
+    public StringLiteralExpr setString(String value) {
+        this.value = StringEscapeUtils.escapeJava(value);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public StringLiteralExpr clone() {
+        return (StringLiteralExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public StringLiteralExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.stringLiteralExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isStringLiteralExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public StringLiteralExpr asStringLiteralExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifStringLiteralExpr(Consumer<StringLiteralExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<StringLiteralExpr> toStringLiteralExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SuperExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SuperExpr.java
new file mode 100644
index 0000000..2de37fb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/SuperExpr.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.metamodel.SuperExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+
+/**
+ * An occurrence of the "super" keyword. <br/><code>World.super.greet()</code> is a MethodCallExpr of method name greet,
+ * and scope "World.super" which is a SuperExpr with classExpr "World". <br/><code>super.name</code> is a
+ * FieldAccessExpr of field greet, and a SuperExpr as its scope. The SuperExpr has no classExpr.
+ *
+ * @author Julio Vilmar Gesser
+ * @see com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+ * @see ThisExpr
+ */
+public final class SuperExpr extends Expression {
+
+    @OptionalProperty
+    private Expression classExpr;
+
+    public SuperExpr() {
+        this(null, null);
+    }
+
+    @AllFieldsConstructor
+    public SuperExpr(final Expression classExpr) {
+        this(null, classExpr);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public SuperExpr(TokenRange tokenRange, Expression classExpr) {
+        super(tokenRange);
+        setClassExpr(classExpr);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getClassExpr() {
+        return Optional.ofNullable(classExpr);
+    }
+
+    /**
+     * Sets the classExpr
+     *
+     * @param classExpr the classExpr, can be null
+     * @return this, the SuperExpr
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SuperExpr setClassExpr(final Expression classExpr) {
+        if (classExpr == this.classExpr) {
+            return (SuperExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.CLASS_EXPR, this.classExpr, classExpr);
+        if (this.classExpr != null)
+            this.classExpr.setParentNode(null);
+        this.classExpr = classExpr;
+        setAsParentNodeOf(classExpr);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (classExpr != null) {
+            if (node == classExpr) {
+                removeClassExpr();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public SuperExpr removeClassExpr() {
+        return setClassExpr((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public SuperExpr clone() {
+        return (SuperExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public SuperExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.superExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (classExpr != null) {
+            if (node == classExpr) {
+                setClassExpr((Expression) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSuperExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SuperExpr asSuperExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSuperExpr(Consumer<SuperExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SuperExpr> toSuperExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ThisExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ThisExpr.java
new file mode 100644
index 0000000..dc9981d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/ThisExpr.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.metamodel.ThisExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import java.util.function.Consumer;
+
+/**
+ * An occurrence of the "this" keyword. <br/><code>World.this.greet()</code> is a MethodCallExpr of method name greet,
+ * and scope "World.super" which is a ThisExpr with classExpr "World". <br/><code>this.name</code> is a
+ * FieldAccessExpr of field greet, and a ThisExpr as its scope. The ThisExpr has no classExpr.
+ *
+ * @author Julio Vilmar Gesser
+ * @see com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+ * @see ThisExpr
+ */
+public final class ThisExpr extends Expression implements Resolvable<ResolvedTypeDeclaration> {
+
+    @OptionalProperty
+    private Expression classExpr;
+
+    public ThisExpr() {
+        this(null, null);
+    }
+
+    @AllFieldsConstructor
+    public ThisExpr(final Expression classExpr) {
+        this(null, classExpr);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ThisExpr(TokenRange tokenRange, Expression classExpr) {
+        super(tokenRange);
+        setClassExpr(classExpr);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getClassExpr() {
+        return Optional.ofNullable(classExpr);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ThisExpr setClassExpr(final Expression classExpr) {
+        if (classExpr == this.classExpr) {
+            return (ThisExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.CLASS_EXPR, this.classExpr, classExpr);
+        if (this.classExpr != null)
+            this.classExpr.setParentNode(null);
+        this.classExpr = classExpr;
+        setAsParentNodeOf(classExpr);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (classExpr != null) {
+            if (node == classExpr) {
+                removeClassExpr();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ThisExpr removeClassExpr() {
+        return setClassExpr((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ThisExpr clone() {
+        return (ThisExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ThisExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.thisExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (classExpr != null) {
+            if (node == classExpr) {
+                setClassExpr((Expression) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isThisExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ThisExpr asThisExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifThisExpr(Consumer<ThisExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedTypeDeclaration resolve() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedTypeDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ThisExpr> toThisExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/TypeExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/TypeExpr.java
new file mode 100644
index 0000000..3d74b6e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/TypeExpr.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.TypeExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * This class is just instantiated as scopes for MethodReferenceExpr nodes to encapsulate Types.
+ * <br/>In <code>World::greet</code> the ClassOrInterfaceType "World" is wrapped in a TypeExpr
+ * before it is set as the scope of the MethodReferenceExpr.
+ *
+ * @author Raquel Pau
+ */
+public final class TypeExpr extends Expression implements NodeWithType<TypeExpr, Type> {
+
+    private Type type;
+
+    public TypeExpr() {
+        this(null, new ClassOrInterfaceType());
+    }
+
+    @AllFieldsConstructor
+    public TypeExpr(Type type) {
+        this(null, type);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public TypeExpr(TokenRange tokenRange, Type type) {
+        super(tokenRange);
+        setType(type);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public TypeExpr setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (TypeExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public TypeExpr clone() {
+        return (TypeExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public TypeExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.typeExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTypeExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TypeExpr asTypeExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTypeExpr(Consumer<TypeExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TypeExpr> toTypeExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/UnaryExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/UnaryExpr.java
new file mode 100644
index 0000000..4008544
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/UnaryExpr.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.nodeTypes.NodeWithExpression;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.DerivedProperty;
+import com.github.javaparser.metamodel.UnaryExprMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.printer.Printable;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An expression where an operator is applied to a single expression.
+ * It supports the operators that are found the the UnaryExpr.Operator enum.
+ * <br/><code>11++</code>
+ * <br/><code>++11</code>
+ * <br/><code>~1</code>
+ * <br/><code>-333</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class UnaryExpr extends Expression implements NodeWithExpression<UnaryExpr> {
+
+    public enum Operator implements Printable {
+
+        PLUS("+", false),
+        MINUS("-", false),
+        PREFIX_INCREMENT("++", false),
+        PREFIX_DECREMENT("--", false),
+        LOGICAL_COMPLEMENT("!", false),
+        BITWISE_COMPLEMENT("~", false),
+        POSTFIX_INCREMENT("++", true),
+        POSTFIX_DECREMENT("--", true);
+
+        private final String codeRepresentation;
+
+        private final boolean isPostfix;
+
+        Operator(String codeRepresentation, boolean isPostfix) {
+            this.codeRepresentation = codeRepresentation;
+            this.isPostfix = isPostfix;
+        }
+
+        public String asString() {
+            return codeRepresentation;
+        }
+
+        public boolean isPostfix() {
+            return isPostfix;
+        }
+
+        public boolean isPrefix() {
+            return !isPostfix();
+        }
+    }
+
+    private Expression expression;
+
+    private Operator operator;
+
+    public UnaryExpr() {
+        this(null, new IntegerLiteralExpr(), Operator.POSTFIX_INCREMENT);
+    }
+
+    @AllFieldsConstructor
+    public UnaryExpr(final Expression expression, final Operator operator) {
+        this(null, expression, operator);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public UnaryExpr(TokenRange tokenRange, Expression expression, Operator operator) {
+        super(tokenRange);
+        setExpression(expression);
+        setOperator(operator);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getExpression() {
+        return expression;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Operator getOperator() {
+        return operator;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public UnaryExpr setExpression(final Expression expression) {
+        assertNotNull(expression);
+        if (expression == this.expression) {
+            return (UnaryExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public UnaryExpr setOperator(final Operator operator) {
+        assertNotNull(operator);
+        if (operator == this.operator) {
+            return (UnaryExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.OPERATOR, this.operator, operator);
+        this.operator = operator;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @DerivedProperty
+    public boolean isPostfix() {
+        return operator.isPostfix();
+    }
+
+    @DerivedProperty
+    public boolean isPrefix() {
+        return !isPostfix();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public UnaryExpr clone() {
+        return (UnaryExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public UnaryExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.unaryExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == expression) {
+            setExpression((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnaryExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnaryExpr asUnaryExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnaryExpr(Consumer<UnaryExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnaryExpr> toUnaryExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/expr/VariableDeclarationExpr.java b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/VariableDeclarationExpr.java
new file mode 100644
index 0000000..8745ce7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/expr/VariableDeclarationExpr.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import com.github.javaparser.metamodel.VariableDeclarationExprMetaModel;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Collectors;
+import static com.github.javaparser.ast.NodeList.nodeList;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A declaration of variables.
+ * It is an expression, so it can be put in places like the initializer of a for loop,
+ * or the resources part of the try statement.
+ * <br/><code>final int x=3, y=55</code>
+ *
+ * <br/>All annotations preceding the type will be set on this object, not on the type.
+ * JavaParser doesn't know if it they are applicable to the method or the type.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclarationExpr extends Expression implements NodeWithFinalModifier<VariableDeclarationExpr>, NodeWithAnnotations<VariableDeclarationExpr>, NodeWithVariables<VariableDeclarationExpr> {
+
+    private EnumSet<Modifier> modifiers;
+
+    private NodeList<AnnotationExpr> annotations;
+
+    @NonEmptyProperty
+    private NodeList<VariableDeclarator> variables;
+
+    public VariableDeclarationExpr() {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), new NodeList<>());
+    }
+
+    public VariableDeclarationExpr(final Type type, String variableName) {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), nodeList(new VariableDeclarator(type, variableName)));
+    }
+
+    public VariableDeclarationExpr(VariableDeclarator var) {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), nodeList(var));
+    }
+
+    public VariableDeclarationExpr(final Type type, String variableName, Modifier... modifiers) {
+        this(null, Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), new NodeList<>(), nodeList(new VariableDeclarator(type, variableName)));
+    }
+
+    public VariableDeclarationExpr(VariableDeclarator var, Modifier... modifiers) {
+        this(null, Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), new NodeList<>(), nodeList(var));
+    }
+
+    public VariableDeclarationExpr(final NodeList<VariableDeclarator> variables) {
+        this(null, EnumSet.noneOf(Modifier.class), new NodeList<>(), variables);
+    }
+
+    public VariableDeclarationExpr(final EnumSet<Modifier> modifiers, final NodeList<VariableDeclarator> variables) {
+        this(null, modifiers, new NodeList<>(), variables);
+    }
+
+    @AllFieldsConstructor
+    public VariableDeclarationExpr(final EnumSet<Modifier> modifiers, final NodeList<AnnotationExpr> annotations, final NodeList<VariableDeclarator> variables) {
+        this(null, modifiers, annotations, variables);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public VariableDeclarationExpr(TokenRange tokenRange, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations, NodeList<VariableDeclarator> variables) {
+        super(tokenRange);
+        setModifiers(modifiers);
+        setAnnotations(annotations);
+        setVariables(variables);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    /**
+     * Return the modifiers of this variable declaration.
+     *
+     * @return modifiers
+     * @see Modifier
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<VariableDeclarator> getVariables() {
+        return variables;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public VariableDeclarationExpr setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (VariableDeclarationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public VariableDeclarationExpr setModifiers(final EnumSet<Modifier> modifiers) {
+        assertNotNull(modifiers);
+        if (modifiers == this.modifiers) {
+            return (VariableDeclarationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers);
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public VariableDeclarationExpr setVariables(final NodeList<VariableDeclarator> variables) {
+        assertNotNull(variables);
+        if (variables == this.variables) {
+            return (VariableDeclarationExpr) this;
+        }
+        notifyPropertyChange(ObservableProperty.VARIABLES, this.variables, variables);
+        if (this.variables != null)
+            this.variables.setParentNode(null);
+        this.variables = variables;
+        setAsParentNodeOf(variables);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < variables.size(); i++) {
+            if (variables.get(i) == node) {
+                variables.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public VariableDeclarationExpr clone() {
+        return (VariableDeclarationExpr) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public VariableDeclarationExprMetaModel getMetaModel() {
+        return JavaParserMetaModel.variableDeclarationExprMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < variables.size(); i++) {
+            if (variables.get(i) == node) {
+                variables.set(i, (VariableDeclarator) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isVariableDeclarationExpr() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public VariableDeclarationExpr asVariableDeclarationExpr() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifVariableDeclarationExpr(Consumer<VariableDeclarationExpr> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<VariableDeclarationExpr> toVariableDeclarationExpr() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleDeclaration.java
new file mode 100644
index 0000000..547c2cc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleDeclaration.java
@@ -0,0 +1,200 @@
+package com.github.javaparser.ast.modules;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ModuleDeclarationMetaModel;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+
+/**
+ * A Java 9 Jigsaw module declaration. <code>@Foo module com.github.abc { requires a.B; }</code>
+ */
+public final class ModuleDeclaration extends Node implements NodeWithName<ModuleDeclaration>, NodeWithAnnotations<ModuleDeclaration> {
+
+    private Name name;
+
+    private NodeList<AnnotationExpr> annotations;
+
+    private boolean isOpen;
+
+    private NodeList<ModuleStmt> moduleStmts;
+
+    public ModuleDeclaration() {
+        this(null, new NodeList<>(), new Name(), false, new NodeList<>());
+    }
+
+    public ModuleDeclaration(Name name, boolean isOpen) {
+        this(null, new NodeList<>(), name, isOpen, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ModuleDeclaration(NodeList<AnnotationExpr> annotations, Name name, boolean isOpen, NodeList<ModuleStmt> moduleStmts) {
+        this(null, annotations, name, isOpen, moduleStmts);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ModuleDeclaration(TokenRange tokenRange, NodeList<AnnotationExpr> annotations, Name name, boolean isOpen, NodeList<ModuleStmt> moduleStmts) {
+        super(tokenRange);
+        setAnnotations(annotations);
+        setName(name);
+        setOpen(isOpen);
+        setModuleStmts(moduleStmts);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleDeclaration setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ModuleDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleDeclaration setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (ModuleDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < moduleStmts.size(); i++) {
+            if (moduleStmts.get(i) == node) {
+                moduleStmts.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isOpen() {
+        return isOpen;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleDeclaration setOpen(final boolean isOpen) {
+        if (isOpen == this.isOpen) {
+            return (ModuleDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.OPEN, this.isOpen, isOpen);
+        this.isOpen = isOpen;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ModuleStmt> getModuleStmts() {
+        return moduleStmts;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleDeclaration setModuleStmts(final NodeList<ModuleStmt> moduleStmts) {
+        assertNotNull(moduleStmts);
+        if (moduleStmts == this.moduleStmts) {
+            return (ModuleDeclaration) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODULE_STMTS, this.moduleStmts, moduleStmts);
+        if (this.moduleStmts != null)
+            this.moduleStmts.setParentNode(null);
+        this.moduleStmts = moduleStmts;
+        setAsParentNodeOf(moduleStmts);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ModuleDeclaration clone() {
+        return (ModuleDeclaration) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ModuleDeclarationMetaModel getMetaModel() {
+        return JavaParserMetaModel.moduleDeclarationMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < moduleStmts.size(); i++) {
+            if (moduleStmts.get(i) == node) {
+                moduleStmts.set(i, (ModuleStmt) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleExportsStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleExportsStmt.java
new file mode 100644
index 0000000..61440b1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleExportsStmt.java
@@ -0,0 +1,164 @@
+package com.github.javaparser.ast.modules;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ModuleExportsStmtMetaModel;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+public final class ModuleExportsStmt extends ModuleStmt implements NodeWithName<ModuleExportsStmt> {
+
+    private Name name;
+
+    private NodeList<Name> moduleNames;
+
+    public ModuleExportsStmt() {
+        this(null, new Name(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ModuleExportsStmt(Name name, NodeList<Name> moduleNames) {
+        this(null, name, moduleNames);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ModuleExportsStmt(TokenRange tokenRange, Name name, NodeList<Name> moduleNames) {
+        super(tokenRange);
+        setName(name);
+        setModuleNames(moduleNames);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < moduleNames.size(); i++) {
+            if (moduleNames.get(i) == node) {
+                moduleNames.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleExportsStmt setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ModuleExportsStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Name> getModuleNames() {
+        return moduleNames;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleExportsStmt setModuleNames(final NodeList<Name> moduleNames) {
+        assertNotNull(moduleNames);
+        if (moduleNames == this.moduleNames) {
+            return (ModuleExportsStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODULE_NAMES, this.moduleNames, moduleNames);
+        if (this.moduleNames != null)
+            this.moduleNames.setParentNode(null);
+        this.moduleNames = moduleNames;
+        setAsParentNodeOf(moduleNames);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ModuleExportsStmt clone() {
+        return (ModuleExportsStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ModuleExportsStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.moduleExportsStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < moduleNames.size(); i++) {
+            if (moduleNames.get(i) == node) {
+                moduleNames.set(i, (Name) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleExportsStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleExportsStmt asModuleExportsStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleExportsStmt(Consumer<ModuleExportsStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleExportsStmt> toModuleExportsStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleOpensStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleOpensStmt.java
new file mode 100644
index 0000000..25565da
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleOpensStmt.java
@@ -0,0 +1,164 @@
+package com.github.javaparser.ast.modules;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ModuleOpensStmtMetaModel;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+public final class ModuleOpensStmt extends ModuleStmt implements NodeWithName<ModuleOpensStmt> {
+
+    private Name name;
+
+    private NodeList<Name> moduleNames;
+
+    public ModuleOpensStmt() {
+        this(null, new Name(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ModuleOpensStmt(Name name, NodeList<Name> moduleNames) {
+        this(null, name, moduleNames);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ModuleOpensStmt(TokenRange tokenRange, Name name, NodeList<Name> moduleNames) {
+        super(tokenRange);
+        setName(name);
+        setModuleNames(moduleNames);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < moduleNames.size(); i++) {
+            if (moduleNames.get(i) == node) {
+                moduleNames.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleOpensStmt setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ModuleOpensStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Name> getModuleNames() {
+        return moduleNames;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleOpensStmt setModuleNames(final NodeList<Name> moduleNames) {
+        assertNotNull(moduleNames);
+        if (moduleNames == this.moduleNames) {
+            return (ModuleOpensStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODULE_NAMES, this.moduleNames, moduleNames);
+        if (this.moduleNames != null)
+            this.moduleNames.setParentNode(null);
+        this.moduleNames = moduleNames;
+        setAsParentNodeOf(moduleNames);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ModuleOpensStmt clone() {
+        return (ModuleOpensStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ModuleOpensStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.moduleOpensStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < moduleNames.size(); i++) {
+            if (moduleNames.get(i) == node) {
+                moduleNames.set(i, (Name) replacementNode);
+                return true;
+            }
+        }
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleOpensStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleOpensStmt asModuleOpensStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleOpensStmt(Consumer<ModuleOpensStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleOpensStmt> toModuleOpensStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleProvidesStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleProvidesStmt.java
new file mode 100644
index 0000000..4ddbced
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleProvidesStmt.java
@@ -0,0 +1,165 @@
+package com.github.javaparser.ast.modules;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ModuleProvidesStmtMetaModel;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+public final class ModuleProvidesStmt extends ModuleStmt implements NodeWithType<ModuleProvidesStmt, Type> {
+
+    private Type type;
+
+    private NodeList<Type> withTypes;
+
+    public ModuleProvidesStmt() {
+        this(null, new ClassOrInterfaceType(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ModuleProvidesStmt(Type type, NodeList<Type> withTypes) {
+        this(null, type, withTypes);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ModuleProvidesStmt(TokenRange tokenRange, Type type, NodeList<Type> withTypes) {
+        super(tokenRange);
+        setType(type);
+        setWithTypes(withTypes);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < withTypes.size(); i++) {
+            if (withTypes.get(i) == node) {
+                withTypes.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleProvidesStmt setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (ModuleProvidesStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Type> getWithTypes() {
+        return withTypes;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleProvidesStmt setWithTypes(final NodeList<Type> withTypes) {
+        assertNotNull(withTypes);
+        if (withTypes == this.withTypes) {
+            return (ModuleProvidesStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.WITH_TYPES, this.withTypes, withTypes);
+        if (this.withTypes != null)
+            this.withTypes.setParentNode(null);
+        this.withTypes = withTypes;
+        setAsParentNodeOf(withTypes);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ModuleProvidesStmt clone() {
+        return (ModuleProvidesStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ModuleProvidesStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.moduleProvidesStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        for (int i = 0; i < withTypes.size(); i++) {
+            if (withTypes.get(i) == node) {
+                withTypes.set(i, (Type) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleProvidesStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleProvidesStmt asModuleProvidesStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleProvidesStmt(Consumer<ModuleProvidesStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleProvidesStmt> toModuleProvidesStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleRequiresStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleRequiresStmt.java
new file mode 100644
index 0000000..cede81c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleRequiresStmt.java
@@ -0,0 +1,161 @@
+package com.github.javaparser.ast.modules;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ModuleRequiresStmtMetaModel;
+import java.util.EnumSet;
+import static com.github.javaparser.ast.Modifier.TRANSITIVE;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A require statement in module-info.java. <code>require a.b.C;</code>
+ */
+public final class ModuleRequiresStmt extends ModuleStmt implements NodeWithStaticModifier<ModuleRequiresStmt>, NodeWithName<ModuleRequiresStmt> {
+
+    private EnumSet<Modifier> modifiers;
+
+    private Name name;
+
+    public ModuleRequiresStmt() {
+        this(null, EnumSet.noneOf(Modifier.class), new Name());
+    }
+
+    @AllFieldsConstructor
+    public ModuleRequiresStmt(EnumSet<Modifier> modifiers, Name name) {
+        this(null, modifiers, name);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ModuleRequiresStmt(TokenRange tokenRange, EnumSet<Modifier> modifiers, Name name) {
+        super(tokenRange);
+        setModifiers(modifiers);
+        setName(name);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleRequiresStmt setModifiers(final EnumSet<Modifier> modifiers) {
+        assertNotNull(modifiers);
+        if (modifiers == this.modifiers) {
+            return (ModuleRequiresStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.MODIFIERS, this.modifiers, modifiers);
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Name getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleRequiresStmt setName(final Name name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ModuleRequiresStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    public boolean isTransitive() {
+        return getModifiers().contains(TRANSITIVE);
+    }
+
+    public ModuleRequiresStmt setTransitive(boolean set) {
+        return setModifier(TRANSITIVE, set);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ModuleRequiresStmt clone() {
+        return (ModuleRequiresStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ModuleRequiresStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.moduleRequiresStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((Name) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleRequiresStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleRequiresStmt asModuleRequiresStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleRequiresStmt(Consumer<ModuleRequiresStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleRequiresStmt> toModuleRequiresStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleStmt.java
new file mode 100644
index 0000000..176c791
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleStmt.java
@@ -0,0 +1,152 @@
+package com.github.javaparser.ast.modules;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ModuleStmtMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import java.util.Optional;
+
+public abstract class ModuleStmt extends Node {
+
+    @AllFieldsConstructor
+    public ModuleStmt() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ModuleStmt(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ModuleStmt clone() {
+        return (ModuleStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ModuleStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.moduleStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleExportsStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleExportsStmt asModuleExportsStmt() {
+        throw new IllegalStateException(f("%s is not an ModuleExportsStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleOpensStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleOpensStmt asModuleOpensStmt() {
+        throw new IllegalStateException(f("%s is not an ModuleOpensStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleProvidesStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleProvidesStmt asModuleProvidesStmt() {
+        throw new IllegalStateException(f("%s is not an ModuleProvidesStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleRequiresStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleRequiresStmt asModuleRequiresStmt() {
+        throw new IllegalStateException(f("%s is not an ModuleRequiresStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleUsesStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleUsesStmt asModuleUsesStmt() {
+        throw new IllegalStateException(f("%s is not an ModuleUsesStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleExportsStmt(Consumer<ModuleExportsStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleOpensStmt(Consumer<ModuleOpensStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleProvidesStmt(Consumer<ModuleProvidesStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleRequiresStmt(Consumer<ModuleRequiresStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleUsesStmt(Consumer<ModuleUsesStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleExportsStmt> toModuleExportsStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleOpensStmt> toModuleOpensStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleProvidesStmt> toModuleProvidesStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleRequiresStmt> toModuleRequiresStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleUsesStmt> toModuleUsesStmt() {
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleUsesStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleUsesStmt.java
new file mode 100644
index 0000000..2bf9856
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/modules/ModuleUsesStmt.java
@@ -0,0 +1,127 @@
+package com.github.javaparser.ast.modules;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ModuleUsesStmtMetaModel;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+public final class ModuleUsesStmt extends ModuleStmt implements NodeWithType<ModuleUsesStmt, Type> {
+
+    private Type type;
+
+    public ModuleUsesStmt() {
+        this(null);
+    }
+
+    @AllFieldsConstructor
+    public ModuleUsesStmt(Type type) {
+        this(null, type);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ModuleUsesStmt(TokenRange tokenRange, Type type) {
+        super(tokenRange);
+        setType(type);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getType() {
+        return type;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ModuleUsesStmt setType(final Type type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (ModuleUsesStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        if (this.type != null)
+            this.type.setParentNode(null);
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ModuleUsesStmt clone() {
+        return (ModuleUsesStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ModuleUsesStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.moduleUsesStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == type) {
+            setType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isModuleUsesStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ModuleUsesStmt asModuleUsesStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifModuleUsesStmt(Consumer<ModuleUsesStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ModuleUsesStmt> toModuleUsesStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithAnnotations.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithAnnotations.java
new file mode 100644
index 0000000..72060c6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithAnnotations.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.*;
+
+import java.lang.annotation.Annotation;
+import java.util.Optional;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+import static com.github.javaparser.JavaParser.parseName;
+
+/**
+ * A node that can be annotated.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public interface NodeWithAnnotations<N extends Node> {
+    NodeList<AnnotationExpr> getAnnotations();
+
+    N setAnnotations(NodeList<AnnotationExpr> annotations);
+
+    void tryAddImportToParentCompilationUnit(Class<?> clazz);
+
+    default AnnotationExpr getAnnotation(int i) {
+        return getAnnotations().get(i);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setAnnotation(int i, AnnotationExpr element) {
+        getAnnotations().set(i, element);
+        return (N) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    default N addAnnotation(AnnotationExpr element) {
+        getAnnotations().add(element);
+        return (N) this;
+    }
+
+    /**
+     * Annotates this
+     *
+     * @param name the name of the annotation
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    default N addAnnotation(String name) {
+        NormalAnnotationExpr annotation = new NormalAnnotationExpr(
+                parseName(name), new NodeList<>());
+        getAnnotations().add(annotation);
+        return (N) this;
+    }
+
+    /**
+     * Annotates this
+     *
+     * @param name the name of the annotation
+     * @return the {@link NormalAnnotationExpr} added
+     */
+    @SuppressWarnings("unchecked")
+    default NormalAnnotationExpr addAndGetAnnotation(String name) {
+        NormalAnnotationExpr annotation = new NormalAnnotationExpr(
+                parseName(name), new NodeList<>());
+        getAnnotations().add(annotation);
+        return annotation;
+    }
+
+    /**
+     * Annotates this node and automatically add the import
+     *
+     * @param clazz the class of the annotation
+     * @return this
+     */
+    default N addAnnotation(Class<? extends Annotation> clazz) {
+        tryAddImportToParentCompilationUnit(clazz);
+        return addAnnotation(clazz.getSimpleName());
+    }
+
+    /**
+     * Annotates this node and automatically add the import
+     *
+     * @param clazz the class of the annotation
+     * @return the {@link NormalAnnotationExpr} added
+     */
+    default NormalAnnotationExpr addAndGetAnnotation(Class<? extends Annotation> clazz) {
+        tryAddImportToParentCompilationUnit(clazz);
+        return addAndGetAnnotation(clazz.getSimpleName());
+    }
+
+    /**
+     * Annotates this with a marker annotation
+     *
+     * @param name the name of the annotation
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    default N addMarkerAnnotation(String name) {
+        MarkerAnnotationExpr markerAnnotationExpr = new MarkerAnnotationExpr(
+                parseName(name));
+        getAnnotations().add(markerAnnotationExpr);
+        return (N) this;
+    }
+
+    /**
+     * Annotates this with a marker annotation and automatically add the import
+     *
+     * @param clazz the class of the annotation
+     * @return this
+     */
+    default N addMarkerAnnotation(Class<? extends Annotation> clazz) {
+        tryAddImportToParentCompilationUnit(clazz);
+        return addMarkerAnnotation(clazz.getSimpleName());
+    }
+
+    /**
+     * Annotates this with a single member annotation
+     *
+     * @param name the name of the annotation
+     * @param expression the part between ()
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    default N addSingleMemberAnnotation(String name, Expression expression) {
+        SingleMemberAnnotationExpr singleMemberAnnotationExpr = new SingleMemberAnnotationExpr(
+                parseName(name), expression);
+        getAnnotations().add(singleMemberAnnotationExpr);
+        return (N) this;
+    }
+
+    /**
+     * Annotates this with a single member annotation
+     *
+     * @param name the name of the annotation
+     * @param value the value, don't forget to add \"\" for a string value
+     * @return this
+     */
+    default N addSingleMemberAnnotation(String name, String value) {
+        return addSingleMemberAnnotation(name, parseExpression(value));
+    }
+
+    /**
+     * Annotates this with a single member annotation and automatically add the import
+     *
+     * @param clazz the class of the annotation
+     * @param value the value, don't forget to add \"\" for a string value
+     * @return this
+     */
+    default N addSingleMemberAnnotation(Class<? extends Annotation> clazz,
+                                        String value) {
+        tryAddImportToParentCompilationUnit(clazz);
+        return addSingleMemberAnnotation(clazz.getSimpleName(), value);
+    }
+
+    /**
+     * Check whether an annotation with this name is present on this element
+     *
+     * @param annotationName the name of the annotation
+     * @return true if found, false if not
+     */
+    default boolean isAnnotationPresent(String annotationName) {
+        return getAnnotations().stream().anyMatch(a -> a.getName().getIdentifier().equals(annotationName));
+    }
+
+    /**
+     * Check whether an annotation with this class is present on this element
+     *
+     * @param annotationClass the class of the annotation
+     * @return true if found, false if not
+     */
+    default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return isAnnotationPresent(annotationClass.getSimpleName());
+    }
+
+    /**
+     * Try to find an annotation by its name
+     *
+     * @param annotationName the name of the annotation
+     */
+    default Optional<AnnotationExpr> getAnnotationByName(String annotationName) {
+        return getAnnotations().stream().filter(a -> a.getName().getIdentifier().equals(annotationName)).findFirst();
+    }
+
+    /**
+     * Try to find an annotation by its class
+     *
+     * @param annotationClass the class of the annotation
+     */
+    default Optional<AnnotationExpr> getAnnotationByClass(Class<? extends Annotation> annotationClass) {
+        return getAnnotationByName(annotationClass.getSimpleName());
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithArguments.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithArguments.java
new file mode 100644
index 0000000..702707c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithArguments.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Expression;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+
+/**
+ * A node with arguments.
+ */
+public interface NodeWithArguments<N extends Node> {
+    N setArguments(NodeList<Expression> arguments);
+
+    NodeList<Expression> getArguments();
+
+    default Expression getArgument(int i) {
+        return getArguments().get(i);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N addArgument(String arg) {
+        return addArgument(parseExpression(arg));
+    }
+
+    @SuppressWarnings("unchecked")
+    default N addArgument(Expression arg) {
+        getArguments().add(arg);
+        return (N) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setArgument(int i, Expression arg) {
+        getArguments().set(i, arg);
+        return (N) this;
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt.java
new file mode 100644
index 0000000..a23e3e2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt.java
@@ -0,0 +1,40 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.stmt.BlockStmt;

+

+/**

+ * A node with a body that is a BlockStmt.

+ */

+public interface NodeWithBlockStmt<N extends Node> {

+    BlockStmt getBody();

+

+    N setBody(BlockStmt block);

+

+    default BlockStmt createBody() {

+        BlockStmt block = new BlockStmt();

+        setBody(block);

+        return block;

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithBody.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithBody.java
new file mode 100644
index 0000000..2388824
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithBody.java
@@ -0,0 +1,38 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.stmt.BlockStmt;

+import com.github.javaparser.ast.stmt.Statement;

+

+public interface NodeWithBody<N extends Node> {

+    Statement getBody();

+

+    N setBody(final Statement body);

+

+    default BlockStmt createBlockStatementAsBody() {

+        BlockStmt b = new BlockStmt();

+        setBody(b);

+        return b;

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithCondition.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithCondition.java
new file mode 100644
index 0000000..4113f8b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithCondition.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+
+public interface NodeWithCondition<N extends Node> {
+    Expression getCondition();
+
+    N setCondition(Expression condition);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithConstructors.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithConstructors.java
new file mode 100644
index 0000000..b2f2507
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithConstructors.java
@@ -0,0 +1,71 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Optional;
+
+import static java.util.Collections.unmodifiableList;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
+
+public interface NodeWithConstructors<N extends Node> extends NodeWithSimpleName<N>, NodeWithMembers<N> {
+    /**
+     * Try to find a {@link ConstructorDeclaration} with no parameters by its name
+     *
+     * @return the constructors found (multiple in case of polymorphism)
+     */
+    default Optional<ConstructorDeclaration> getDefaultConstructor() {
+        return getMembers().stream().filter(bd -> bd instanceof ConstructorDeclaration).map(bd -> (ConstructorDeclaration) bd).filter(cd -> cd.getParameters().isEmpty()).findFirst();
+    }
+
+    /**
+     * Adds a constructor to this
+     *
+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}
+     * @return the created constructor
+     */
+    default ConstructorDeclaration addConstructor(Modifier... modifiers) {
+        ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration();
+        constructorDeclaration.setModifiers(Arrays.stream(modifiers).collect(toCollection(() -> EnumSet.noneOf(Modifier.class))));
+        constructorDeclaration.setName(getName());
+        getMembers().add(constructorDeclaration);
+        return constructorDeclaration;
+    }
+
+    /**
+     * Find all constructors for this class.
+     *
+     * @return the constructors found. This list is immutable.
+     */
+    default List<ConstructorDeclaration> getConstructors() {
+        return unmodifiableList(getMembers().stream().filter(m -> m instanceof ConstructorDeclaration).map(m -> (ConstructorDeclaration) m).collect(toList()));
+    }
+
+    /**
+     * Try to find a {@link ConstructorDeclaration} by its parameters types
+     *
+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br> void
+     * foo(Map&lt;Integer,String&gt; myMap,int number)
+     * @return the constructor found (multiple in case of overloading)
+     */
+    default Optional<ConstructorDeclaration> getConstructorByParameterTypes(String... paramTypes) {
+        return getConstructors().stream().filter(m -> m.hasParametersOfType(paramTypes)).findFirst();
+    }
+
+    /**
+     * Try to find a {@link ConstructorDeclaration} by its parameters types
+     *
+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br> void
+     * foo(Map&lt;Integer,String&gt; myMap,int number)
+     * @return the constructors found (multiple in case of overloading)
+     */
+    default Optional<ConstructorDeclaration> getConstructorByParameterTypes(Class<?>... paramTypes) {
+        return getConstructors().stream().filter(m -> m.hasParametersOfType(paramTypes)).findFirst();
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithDeclaration.java
new file mode 100644
index 0000000..d490ed1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithDeclaration.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+/**
+ * Node with a declaration representable as a String.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public interface NodeWithDeclaration {
+
+    /**
+     * As {@link NodeWithDeclaration#getDeclarationAsString(boolean, boolean, boolean)} including
+     * the modifiers, the throws clause and the parameters with both type and name.
+     *
+     * @return String representation of declaration
+     */
+    String getDeclarationAsString();
+
+    /**
+     * As {@link NodeWithDeclaration#getDeclarationAsString(boolean, boolean, boolean)} including
+     * the parameters with both type and name.
+     *
+     * @param includingModifiers flag to include the modifiers (if present) in the string produced
+     * @param includingThrows flag to include the throws clause (if present) in the string produced
+     * @return String representation of declaration based on parameter flags
+     */
+    String getDeclarationAsString(boolean includingModifiers, boolean includingThrows);
+
+    /**
+     * A simple representation of the element declaration.
+     * It should fit one string.
+     *
+     * @param includingModifiers flag to include the modifiers (if present) in the string produced
+     * @param includingThrows flag to include the throws clause (if present) in the string produced
+     * @param includingParameterName flag to include the parameter name (while the parameter type is always included) in
+     * the string produced
+     * @return String representation of declaration based on parameter flags
+     */
+    String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithExpression.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithExpression.java
new file mode 100644
index 0000000..3a1dd71
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithExpression.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+
+/**
+ * A node that has an expression in it.
+ */
+public interface NodeWithExpression<N extends Node> {
+    Expression getExpression();
+
+    N setExpression(Expression expression);
+
+    default N setExpression(String expression) {
+        return setExpression(parseExpression(expression));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithExtends.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithExtends.java
new file mode 100644
index 0000000..af4adf8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithExtends.java
@@ -0,0 +1,92 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.NodeList;

+import com.github.javaparser.ast.type.ClassOrInterfaceType;

+

+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;

+

+/**

+ * A node that extends other types.

+ */

+public interface NodeWithExtends<N extends Node> {

+    NodeList<ClassOrInterfaceType> getExtendedTypes();

+

+    void tryAddImportToParentCompilationUnit(Class<?> clazz);

+

+    default ClassOrInterfaceType getExtendedTypes(int i) {

+        return getExtendedTypes().get(i);

+    }

+

+    N setExtendedTypes(NodeList<ClassOrInterfaceType> extendsList);

+

+    @SuppressWarnings("unchecked")

+    default N setExtendedType(int i, ClassOrInterfaceType extend) {

+        getExtendedTypes().set(i, extend);

+        return (N) this;

+    }

+

+    @SuppressWarnings("unchecked")

+    default N addExtendedType(ClassOrInterfaceType extend) {

+        getExtendedTypes().add(extend);

+        return (N) this;

+    }

+

+    /**

+     * @deprecated use addExtendedType

+     */

+    default N addExtends(Class<?> clazz) {

+        return addExtendedType(clazz);

+    }

+

+    /**

+     * @deprecated use addExtendedType

+     */

+    default N addExtends(String name) {

+        return addExtendedType(name);

+    }

+

+    /**

+     * Add an "extends" to this and automatically add the import

+     *

+     * @param clazz the class to extand from

+     * @return this

+     */

+    default N addExtendedType(Class<?> clazz) {

+        tryAddImportToParentCompilationUnit(clazz);

+        return addExtendedType(clazz.getSimpleName());

+    }

+

+    /**

+     * Add an "extends" to this

+     *

+     * @param name the name of the type to extends from

+     * @return this

+     */

+    @SuppressWarnings("unchecked")

+    default N addExtendedType(String name) {

+        getExtendedTypes().add(parseClassOrInterfaceType(name));

+        return (N) this;

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithIdentifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithIdentifier.java
new file mode 100644
index 0000000..22a583a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithIdentifier.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+
+public interface NodeWithIdentifier<N extends Node> {
+    String getIdentifier();
+
+    N setIdentifier(String identifier);
+
+    default String getId() {
+        return getIdentifier();
+    }
+
+    default N setId(String identifier) {
+        assertNonEmpty(identifier);
+        return setIdentifier(identifier);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithImplements.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithImplements.java
new file mode 100644
index 0000000..84cee4d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithImplements.java
@@ -0,0 +1,88 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.NodeList;

+import com.github.javaparser.ast.type.ClassOrInterfaceType;

+

+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;

+

+/**

+ * A node that implements other types.

+ */

+public interface NodeWithImplements<N extends Node> {

+    NodeList<ClassOrInterfaceType> getImplementedTypes();

+

+    default ClassOrInterfaceType getImplementedTypes(int i) {

+        return getImplementedTypes().get(i);

+    }

+

+    N setImplementedTypes(NodeList<ClassOrInterfaceType> implementsList);

+    

+    void tryAddImportToParentCompilationUnit(Class<?> clazz);

+    

+    @SuppressWarnings("unchecked")

+    default N setImplementedType(int i, ClassOrInterfaceType implement) {

+        getImplementedTypes().set(i, implement);

+        return (N) this;

+    }

+

+    @SuppressWarnings("unchecked")

+    default N addImplementedType(ClassOrInterfaceType implement) {

+        getImplementedTypes().add(implement);

+        return (N) this;

+    }

+

+    /** @deprecated use addImplementedType instead */

+    default N addImplements(String name) {

+        return addImplementedType(name);

+    }

+

+    /** @deprecated use addImplementedType instead */

+    default N addImplements(Class<?> clazz) {

+        return addImplementedType(clazz);

+    }

+

+    /**

+     * Add an implements to this

+     *

+     * @param name the name of the type to extends from

+     * @return this

+     */

+    @SuppressWarnings("unchecked")

+    default N addImplementedType(String name) {

+        getImplementedTypes().add(parseClassOrInterfaceType(name));

+        return (N) this;

+    }

+

+    /**

+     * Add an implements to this and automatically add the import

+     *

+     * @param clazz the type to implements from

+     * @return this

+     */

+    default N addImplementedType(Class<?> clazz) {

+        tryAddImportToParentCompilationUnit(clazz);

+        return addImplementedType(clazz.getSimpleName());

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithJavadoc.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithJavadoc.java
new file mode 100644
index 0000000..592947e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithJavadoc.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.javadoc.Javadoc;
+
+import java.util.Optional;
+
+/**
+ * A node that can be documented with a Javadoc comment.
+ */
+public interface NodeWithJavadoc<N extends Node> {
+    Optional<Comment> getComment();
+
+    Node setComment(Comment comment);
+
+    /**
+     * Gets the JavadocComment for this node. You can set the JavadocComment by calling setJavadocComment passing a
+     * JavadocComment.
+     *
+     * @return The JavadocComment for this node wrapped in an optional as it may be absent.
+     */
+    default Optional<JavadocComment> getJavadocComment() {
+        return getComment()
+                .filter(comment -> comment instanceof JavadocComment)
+                .map(comment -> (JavadocComment) comment);
+    }
+
+    /**
+     * Gets the Javadoc for this node. You can set the Javadoc by calling setJavadocComment passing a Javadoc.
+     *
+     * @return The Javadoc for this node wrapped in an optional as it may be absent.
+     */
+    default Optional<Javadoc> getJavadoc() {
+        return getJavadocComment().map(JavadocComment::parse);
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    @SuppressWarnings("unchecked")
+    default N setJavadocComment(String comment) {
+        return setJavadocComment(new JavadocComment(" " + comment));
+    }
+
+    default N setJavadocComment(JavadocComment comment) {
+        setComment(comment);
+        return (N) this;
+    }
+
+    default N setJavadocComment(String indentation, Javadoc javadoc) {
+        return setJavadocComment(javadoc.toComment(indentation));
+    }
+
+    default N setJavadocComment(Javadoc javadoc) {
+        return setJavadocComment(javadoc.toComment());
+    }
+
+    default boolean removeJavaDocComment() {
+        return hasJavaDocComment() && getComment().get().remove();
+    }
+
+    default boolean hasJavaDocComment() {
+        return getComment().isPresent() && getComment().get() instanceof JavadocComment;
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
new file mode 100644
index 0000000..6d5f0c3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
@@ -0,0 +1,328 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.Modifier;

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.NodeList;

+import com.github.javaparser.ast.body.*;

+import com.github.javaparser.ast.expr.Expression;

+import com.github.javaparser.ast.stmt.BlockStmt;

+import com.github.javaparser.ast.type.Type;

+import com.github.javaparser.ast.type.VoidType;

+

+import java.util.Arrays;

+import java.util.EnumSet;

+import java.util.List;

+import java.util.Optional;

+

+import static com.github.javaparser.JavaParser.parseType;

+import static java.util.Collections.unmodifiableList;

+import static java.util.stream.Collectors.toCollection;

+import static java.util.stream.Collectors.toList;

+

+/**

+ * A node having members.

+ * <p>

+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with a getMembers

+ * method.

+ */

+public interface NodeWithMembers<N extends Node> {

+    /**

+     * @return all members inside the braces of this node,

+     * like fields, methods, nested types, etc.

+     */

+    NodeList<BodyDeclaration<?>> getMembers();

+

+    void tryAddImportToParentCompilationUnit(Class<?> clazz);

+

+    default BodyDeclaration<?> getMember(int i) {

+        return getMembers().get(i);

+    }

+

+    @SuppressWarnings("unchecked")

+    default N setMember(int i, BodyDeclaration<?> member) {

+        getMembers().set(i, member);

+        return (N) this;

+    }

+

+    @SuppressWarnings("unchecked")

+    default N addMember(BodyDeclaration<?> member) {

+        getMembers().add(member);

+        return (N) this;

+    }

+

+    N setMembers(NodeList<BodyDeclaration<?>> members);

+

+    /**

+     * Add a field to this and automatically add the import of the type if needed

+     *

+     * @param typeClass the type of the field

+     * @param name the name of the field

+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addField(Class<?> typeClass, String name, Modifier... modifiers) {

+        tryAddImportToParentCompilationUnit(typeClass);

+        return addField(typeClass.getSimpleName(), name, modifiers);

+    }

+

+    /**

+     * Add a field to this.

+     *

+     * @param type the type of the field

+     * @param name the name of the field

+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addField(String type, String name, Modifier... modifiers) {

+        return addField(parseType(type), name, modifiers);

+    }

+

+    /**

+     * Add a field to this.

+     *

+     * @param type the type of the field

+     * @param name the name of the field

+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addField(Type type, String name, Modifier... modifiers) {

+        FieldDeclaration fieldDeclaration = new FieldDeclaration();

+        VariableDeclarator variable = new VariableDeclarator(type, name);

+        fieldDeclaration.getVariables().add(variable);

+        fieldDeclaration.setModifiers(Arrays.stream(modifiers)

+                .collect(toCollection(() -> EnumSet.noneOf(Modifier.class))));

+        getMembers().add(fieldDeclaration);

+        return fieldDeclaration;

+    }

+

+    /**

+     * Add a field to this.

+     *

+     * @param type the type of the field

+     * @param name the name of the field

+     * @param initializer the initializer of the field

+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addFieldWithInitializer(Type type, String name, Expression initializer, Modifier... modifiers) {

+        FieldDeclaration declaration = addField(type, name, modifiers);

+        declaration.getVariables().iterator().next().setInitializer(initializer);

+        return declaration;

+    }

+

+    /**

+     * Add a private field to this.

+     *

+     * @param typeClass the type of the field

+     * @param name the name of the field

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addPrivateField(Class<?> typeClass, String name) {

+        return addField(typeClass, name, Modifier.PRIVATE);

+    }

+

+    /**

+     * Add a private field to this and automatically add the import of the type if

+     * needed.

+     *

+     * @param type the type of the field

+     * @param name the name of the field

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addPrivateField(String type, String name) {

+        return addField(type, name, Modifier.PRIVATE);

+    }

+

+    /**

+     * Add a public field to this.

+     *

+     * @param typeClass the type of the field

+     * @param name the name of the field

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addPublicField(Class<?> typeClass, String name) {

+        return addField(typeClass, name, Modifier.PUBLIC);

+    }

+

+    /**

+     * Add a public field to this and automatically add the import of the type if

+     * needed.

+     *

+     * @param type the type of the field

+     * @param name the name of the field

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addPublicField(String type, String name) {

+        return addField(type, name, Modifier.PUBLIC);

+    }

+

+    /**

+     * Add a protected field to this.

+     *

+     * @param typeClass the type of the field

+     * @param name the name of the field

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addProtectedField(Class<?> typeClass, String name) {

+        return addField(typeClass, name, Modifier.PROTECTED);

+    }

+

+    /**

+     * Add a protected field to this and automatically add the import of the type

+     * if needed.

+     *

+     * @param type the type of the field

+     * @param name the name of the field

+     * @return the {@link FieldDeclaration} created

+     */

+    default FieldDeclaration addProtectedField(String type, String name) {

+        return addField(type, name, Modifier.PROTECTED);

+    }

+

+    /**

+     * Adds a methods with void return by default to this.

+     *

+     * @param methodName the method name

+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}

+     * @return the {@link MethodDeclaration} created

+     */

+    default MethodDeclaration addMethod(String methodName, Modifier... modifiers) {

+        MethodDeclaration methodDeclaration = new MethodDeclaration();

+        methodDeclaration.setName(methodName);

+        methodDeclaration.setType(new VoidType());

+        methodDeclaration.setModifiers(Arrays.stream(modifiers)

+                .collect(toCollection(() -> EnumSet.noneOf(Modifier.class))));

+        getMembers().add(methodDeclaration);

+        return methodDeclaration;

+    }

+

+    /**

+     * Add an initializer block ({@link InitializerDeclaration}) to this.

+     */

+    default BlockStmt addInitializer() {

+        BlockStmt block = new BlockStmt();

+        InitializerDeclaration initializerDeclaration = new InitializerDeclaration(false, block);

+        getMembers().add(initializerDeclaration);

+        return block;

+    }

+

+    /**

+     * Add a static initializer block ({@link InitializerDeclaration}) to this.

+     */

+    default BlockStmt addStaticInitializer() {

+        BlockStmt block = new BlockStmt();

+        InitializerDeclaration initializerDeclaration = new InitializerDeclaration(true, block);

+        getMembers().add(initializerDeclaration);

+        return block;

+    }

+

+    /**

+     * Try to find a {@link MethodDeclaration} by its name

+     *

+     * @param name the name of the method

+     * @return the methods found (multiple in case of overloading)

+     */

+    default List<MethodDeclaration> getMethodsByName(String name) {

+        return unmodifiableList(getMethods().stream()

+                .filter(m -> m.getNameAsString().equals(name))

+                .collect(toList()));

+    }

+

+    /**

+     * Find all methods in the members of this node.

+     *

+     * @return the methods found. This list is immutable.

+     */

+    default List<MethodDeclaration> getMethods() {

+        return unmodifiableList(getMembers().stream()

+                .filter(m -> m instanceof MethodDeclaration)

+                .map(m -> (MethodDeclaration) m)

+                .collect(toList()));

+    }

+

+    /**

+     * Try to find a {@link MethodDeclaration} by its parameters types

+     *

+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br> void

+     * foo(Map&lt;Integer,String&gt; myMap,int number)

+     * @return the methods found (multiple in case of overloading)

+     */

+    default List<MethodDeclaration> getMethodsByParameterTypes(String... paramTypes) {

+        return unmodifiableList(getMethods().stream()

+                .filter(m -> m.hasParametersOfType(paramTypes))

+                .collect(toList()));

+    }

+

+    /**

+     * Try to find {@link MethodDeclaration}s by their name and parameters types

+     *

+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br> void

+     * foo(Map&lt;Integer,String&gt; myMap,int number)

+     * @return the methods found (multiple in case of overloading)

+     */

+    default List<MethodDeclaration> getMethodsBySignature(String name, String... paramTypes) {

+        return unmodifiableList(getMethodsByName(name).stream()

+                .filter(m -> m.hasParametersOfType(paramTypes))

+                .collect(toList()));

+    }

+

+    /**

+     * Try to find a {@link MethodDeclaration} by its parameters types

+     *

+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br> void

+     * foo(Map&lt;Integer,String&gt; myMap,int number)

+     * @return the methods found (multiple in case of overloading)

+     */

+    default List<MethodDeclaration> getMethodsByParameterTypes(Class<?>... paramTypes) {

+        return unmodifiableList(getMethods().stream()

+                .filter(m -> m.hasParametersOfType(paramTypes))

+                .collect(toList()));

+    }

+

+    /**

+     * Try to find a {@link FieldDeclaration} by its name

+     *

+     * @param name the name of the field

+     * @return null if not found, the FieldDeclaration otherwise

+     */

+    default Optional<FieldDeclaration> getFieldByName(String name) {

+        return getMembers().stream()

+                .filter(m -> m instanceof FieldDeclaration)

+                .map(f -> (FieldDeclaration) f)

+                .filter(f -> f.getVariables().stream()

+                        .anyMatch(var -> var.getNameAsString().equals(name)))

+                .findFirst();

+    }

+

+    /**

+     * Find all fields in the members of this node.

+     *

+     * @return the fields found. This list is immutable.

+     */

+    default List<FieldDeclaration> getFields() {

+        return unmodifiableList(getMembers().stream()

+                .filter(m -> m instanceof FieldDeclaration)

+                .map(m -> (FieldDeclaration) m)

+                .collect(toList()));

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithModifiers.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithModifiers.java
new file mode 100644
index 0000000..3a499bf
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithModifiers.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.stream.Collectors;
+
+/**
+ * A Node with Modifiers.
+ * Note that not all modifiers may be valid for this node.
+ */
+public interface NodeWithModifiers<N extends Node> {
+    /**
+     * Return the modifiers of this variable declaration.
+     * Warning: modifying the returned set will not trigger observers,
+     * you have to use setModifiers for that.
+     *
+     * @return modifiers
+     * @see Modifier
+     */
+    EnumSet<Modifier> getModifiers();
+
+    N setModifiers(EnumSet<Modifier> modifiers);
+
+    @SuppressWarnings("unchecked")
+    default N addModifier(Modifier... modifiers) {
+        EnumSet<Modifier> newModifiers = getModifiers().clone();
+        newModifiers.addAll(Arrays.stream(modifiers)
+                .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))));
+        setModifiers(newModifiers);
+        return (N) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    default N removeModifier(Modifier... m) {
+        EnumSet<Modifier> newModifiers = getModifiers().clone();
+        newModifiers.removeAll(Arrays.stream(m)
+                .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))));
+        setModifiers(newModifiers);
+        return (N) this;
+    }
+    default N setModifier(Modifier m, boolean set) {
+        if (set) {
+            return addModifier(m);
+        } else {
+            return removeModifier(m);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithName.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithName.java
new file mode 100644
index 0000000..bc25cad
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithName.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Name;
+
+import static com.github.javaparser.JavaParser.parseName;
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+
+/**
+ * A node with a (qualified) name.
+ * <p>
+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with a getName method.
+ *
+ * @since 2.0.1
+ */
+public interface NodeWithName<N extends Node> {
+    Name getName();
+
+    N setName(Name name);
+
+    @SuppressWarnings("unchecked")
+    default N setName(String name) {
+        assertNonEmpty(name);
+        return setName(parseName(name));
+    }
+
+    default String getNameAsString() {
+        return getName().asString();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalBlockStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalBlockStmt.java
new file mode 100644
index 0000000..0bf89a4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalBlockStmt.java
@@ -0,0 +1,44 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.stmt.BlockStmt;

+

+import java.util.Optional;

+

+/**

+ * A node with a body that is a BlockStmt, which is optional.

+ */

+public interface NodeWithOptionalBlockStmt<N extends Node> {

+    Optional<BlockStmt> getBody();

+

+    N setBody(BlockStmt block);

+

+    N removeBody();

+

+    default BlockStmt createBody() {

+        BlockStmt block = new BlockStmt();

+        setBody(block);

+        return block;

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalLabel.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalLabel.java
new file mode 100644
index 0000000..93ab11a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalLabel.java
@@ -0,0 +1,28 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.SimpleName;
+
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+
+/**
+ * A node that has an optional label.
+ */
+public interface NodeWithOptionalLabel<T extends Node> {
+    Optional<SimpleName> getLabel();
+
+    T setLabel(SimpleName label);
+    
+    T removeLabel();
+
+    default T setLabel(String label) {
+        assertNonEmpty(label);
+        return setLabel(new SimpleName(label));
+    }
+
+    default Optional<String> getLabelAsString() {
+        return getLabel().flatMap(l -> Optional.of(l.getIdentifier()));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalScope.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalScope.java
new file mode 100644
index 0000000..46bd59c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalScope.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+
+import java.util.Optional;
+
+/**
+ * Represents a node which has an optional scope expression eg. method calls (object.method()).
+ */
+public interface NodeWithOptionalScope<N extends Node> extends NodeWithTraversableScope {
+
+    Optional<Expression> getScope();
+
+    N setScope(Expression scope);
+    
+    N removeScope();
+
+    default Optional<Expression> traverseScope() {
+        return getScope();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithParameters.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithParameters.java
new file mode 100644
index 0000000..517d8f5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithParameters.java
@@ -0,0 +1,162 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.NodeList;

+import com.github.javaparser.ast.body.Parameter;

+import com.github.javaparser.ast.type.Type;

+

+import java.util.Optional;

+import java.util.stream.Stream;

+

+import static com.github.javaparser.JavaParser.parseType;

+import static java.util.stream.Collectors.toSet;

+

+public interface NodeWithParameters<N extends Node> {

+    NodeList<Parameter> getParameters();

+

+    default Parameter getParameter(int i) {

+        return getParameters().get(i);

+    }

+

+    void tryAddImportToParentCompilationUnit(Class<?> clazz);

+

+    @SuppressWarnings("unchecked")

+    default N setParameter(int i, Parameter parameter) {

+        getParameters().set(i, parameter);

+        return (N) this;

+    }

+

+    N setParameters(NodeList<Parameter> parameters);

+

+    default N addParameter(Type type, String name) {

+        return addParameter(new Parameter(type, name));

+    }

+

+    default N addParameter(Class<?> paramClass, String name) {

+        tryAddImportToParentCompilationUnit(paramClass);

+        return addParameter(parseType(paramClass.getSimpleName()), name);

+    }

+

+    /**

+     * Remember to import the class in the compilation unit yourself

+     *

+     * @param className the name of the class, ex : org.test.Foo or Foo if you added manually the import

+     * @param name the name of the parameter

+     */

+    default N addParameter(String className, String name) {

+        return addParameter(parseType(className), name);

+    }

+

+    @SuppressWarnings("unchecked")

+    default N addParameter(Parameter parameter) {

+        getParameters().add(parameter);

+        return (N) this;

+    }

+

+    default Parameter addAndGetParameter(Type type, String name) {

+        return addAndGetParameter(new Parameter(type, name));

+    }

+

+    default Parameter addAndGetParameter(Class<?> paramClass, String name) {

+        tryAddImportToParentCompilationUnit(paramClass);

+        return addAndGetParameter(parseType(paramClass.getSimpleName()), name);

+    }

+

+    /**

+     * Remember to import the class in the compilation unit yourself

+     *

+     * @param className the name of the class, ex : org.test.Foo or Foo if you added manually the import

+     * @param name the name of the parameter

+     * @return the {@link Parameter} created

+     */

+    default Parameter addAndGetParameter(String className, String name) {

+        return addAndGetParameter(parseType(className), name);

+    }

+

+    default Parameter addAndGetParameter(Parameter parameter) {

+        getParameters().add(parameter);

+        return parameter;

+    }

+

+    /**

+     * Try to find a {@link Parameter} by its name

+     *

+     * @param name the name of the param

+     * @return null if not found, the param found otherwise

+     */

+    default Optional<Parameter> getParameterByName(String name) {

+        return getParameters().stream()

+                .filter(p -> p.getNameAsString().equals(name)).findFirst();

+    }

+

+    /**

+     * Try to find a {@link Parameter} by its type

+     *

+     * @param type the type of the param

+     * @return null if not found, the param found otherwise

+     */

+    default Optional<Parameter> getParameterByType(String type) {

+        return getParameters().stream()

+                .filter(p -> p.getType().toString().equals(type)).findFirst();

+    }

+

+    /**

+     * Try to find a {@link Parameter} by its type

+     *

+     * @param type the type of the param <b>take care about generics, it wont work</b>

+     * @return null if not found, the param found otherwise

+     */

+    default Optional<Parameter> getParameterByType(Class<?> type) {

+        return getParameters().stream()

+                .filter(p -> p.getType().toString().equals(type.getSimpleName())).findFirst();

+    }

+

+    /**

+     * Check if the parameters have certain types.

+     *

+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br> void

+     * foo(Map&lt;Integer,String&gt; myMap,int number)

+     * @return true if all parameters match

+     */

+    default boolean hasParametersOfType(String... paramTypes) {

+        return getParameters().stream()

+                .map(p -> p.getType().toString())

+                .collect(toSet())

+                .equals(Stream.of(paramTypes).collect(toSet()));

+    }

+

+    /**

+     * Check if the parameters have certain types. Note that this is a match in SimpleName, so "java.awt.List" and

+     * "java.util.List" are identical to this algorithm.

+     *

+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br> void

+     * foo(Map&lt;Integer,String&gt; myMap,int number)

+     * @return true if all parameters match

+     */

+    default boolean hasParametersOfType(Class<?>... paramTypes) {

+        return getParameters().stream().map(p -> p.getType().toString())

+                .collect(toSet())

+                .equals(Stream.of(paramTypes).map(Class::getSimpleName).collect(toSet()));

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithRange.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithRange.java
new file mode 100644
index 0000000..d1e2fb7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithRange.java
@@ -0,0 +1,54 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.Position;
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+
+import java.util.Optional;
+
+/**
+ * A node that has a Range, which is every Node.
+ * 
+ */
+public interface NodeWithRange<N> {
+    Optional<Range> getRange();
+
+    N setRange(Range range);
+
+    /**
+     * The begin position of this node in the source file.
+     */
+    default Optional<Position> getBegin() {
+        return getRange().map(r -> r.begin);
+    }
+
+    /**
+     * The end position of this node in the source file.
+     */
+    default Optional<Position> getEnd() {
+        return getRange().map(r -> r.end);
+    }
+
+    default boolean containsWithin(Node other) {
+        if (getRange().isPresent() && other.getRange().isPresent()) {
+            return getRange().get().contains(other.getRange().get());
+        }
+        return false;
+    }
+
+    /**
+     * @deprecated use isAfter() on range
+     */
+    @Deprecated
+    default boolean isPositionedAfter(Position position) {
+        return getRange().map(r -> r.isAfter(position)).orElse(false);
+    }
+
+    /**
+     * @deprecated use isBefore() on range
+     */
+    @Deprecated
+    default boolean isPositionedBefore(Position position) {
+        return getRange().map(r -> r.isBefore(position)).orElse(false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithScope.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithScope.java
new file mode 100644
index 0000000..15ea3ac
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithScope.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+
+import java.util.Optional;
+
+/**
+ * Represents a node which has a required scope expression eg. field access (object.method).
+ */
+public interface NodeWithScope<N extends Node> extends NodeWithTraversableScope {
+
+    Expression getScope();
+
+    N setScope(Expression scope);
+
+    default Optional<Expression> traverseScope() {
+        return Optional.of(getScope());
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithSimpleName.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithSimpleName.java
new file mode 100644
index 0000000..ebd3957
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithSimpleName.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+
+import static com.github.javaparser.utils.Utils.assertNonEmpty;
+
+/**
+ * A node with a name.
+ * <p>
+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with a getName method.
+ */
+public interface NodeWithSimpleName<N extends Node> {
+    SimpleName getName();
+
+    N setName(SimpleName name);
+
+    @SuppressWarnings("unchecked")
+    default N setName(String name) {
+        assertNonEmpty(name);
+        return setName(new SimpleName(name));
+    }
+
+    default String getNameAsString() {
+        return getName().getIdentifier();
+    }
+
+    default NameExpr getNameAsExpression() {
+        return new NameExpr(getName());
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithStatements.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithStatements.java
new file mode 100644
index 0000000..4d2c90c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithStatements.java
@@ -0,0 +1,114 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.NodeList;

+import com.github.javaparser.ast.expr.Expression;

+import com.github.javaparser.ast.expr.NameExpr;

+import com.github.javaparser.ast.stmt.ExpressionStmt;

+import com.github.javaparser.ast.stmt.Statement;

+

+import static com.github.javaparser.JavaParser.*;

+

+/**

+ * A node that contains a list of statements.

+ */

+public interface NodeWithStatements<N extends Node> {

+    NodeList<Statement> getStatements();

+

+    default Statement getStatement(int i) {

+        return getStatements().get(i);

+    }

+

+    @SuppressWarnings("unchecked")

+    default N setStatement(int i, Statement statement) {

+        getStatements().set(i, statement);

+        return (N) this;

+    }

+

+    N setStatements(final NodeList<Statement> statements);

+

+    @SuppressWarnings("unchecked")

+    default N addStatement(Statement statement) {

+        getStatements().add(statement);

+        return (N) this;

+    }

+

+    @SuppressWarnings("unchecked")

+    default N addStatement(int index, final Statement statement) {

+        getStatements().add(index, statement);

+        return (N) this;

+    }

+

+    default N addStatement(Expression expr) {

+        return addStatement(new ExpressionStmt(expr));

+    }

+

+    /**

+     * It will use {@link JavaParser#parseStatement(String)} inside, so it should end with a semi column

+     */

+    default N addStatement(String statement) {

+        return addStatement(parseStatement(statement));

+    }

+

+    default N addStatement(int index, final Expression expr) {

+        Statement stmt = new ExpressionStmt(expr);

+        return addStatement(index, stmt);

+    }

+

+    default <A extends Statement> A addAndGetStatement(A statement) {

+        getStatements().add(statement);

+        return statement;

+    }

+

+    default Statement addAndGetStatement(int index, final Statement statement) {

+        getStatements().add(index, statement);

+        return statement;

+    }

+

+    default ExpressionStmt addAndGetStatement(Expression expr) {

+        ExpressionStmt statement = new ExpressionStmt(expr);

+        return addAndGetStatement(statement);

+    }

+

+    default ExpressionStmt addAndGetStatement(String statement) {

+        return addAndGetStatement(new NameExpr(statement));

+    }

+

+    default boolean isEmpty() {

+        return getStatements().isEmpty();

+    }

+

+    @SuppressWarnings("unchecked")

+    default N copyStatements(NodeList<Statement> nodeList) {

+        for (Statement n : nodeList) {

+            addStatement(n.clone());

+        }

+        return (N) this;

+    }

+

+    default N copyStatements(NodeWithStatements<?> other) {

+        return copyStatements(other.getStatements());

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithThrownExceptions.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithThrownExceptions.java
new file mode 100644
index 0000000..e1b9007
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithThrownExceptions.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.type.ReferenceType;
+
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+
+/**
+ * A node that declares the types of exception it throws.
+ */
+public interface NodeWithThrownExceptions<N extends Node> {
+    N setThrownExceptions(NodeList<ReferenceType> thrownExceptions);
+
+    NodeList<ReferenceType> getThrownExceptions();
+
+    void tryAddImportToParentCompilationUnit(Class<?> clazz);
+
+    default ReferenceType getThrownException(int i) {
+        return getThrownExceptions().get(i);
+    }
+
+    /**
+     * Adds this type to the throws clause
+     *
+     * @param throwType the exception type
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    default N addThrownException(ReferenceType throwType) {
+        getThrownExceptions().add(throwType);
+        return (N) this;
+    }
+
+    /**
+     * Adds this class to the throws clause
+     *
+     * @param clazz the exception class
+     * @return this
+     */
+    default N addThrownException(Class<? extends Throwable> clazz) {
+        tryAddImportToParentCompilationUnit(clazz);
+        return addThrownException(parseClassOrInterfaceType(clazz.getSimpleName()));
+    }
+
+    /**
+     * Check whether this elements throws this exception class.
+     * Note that this is simply a text compare of the simple name of the class,
+     * no actual type resolution takes place.
+     *
+     * @param clazz the class of the exception
+     * @return true if found in throws clause, false if not
+     */
+    default boolean isThrown(Class<? extends Throwable> clazz) {
+        return isThrown(clazz.getSimpleName());
+    }
+
+    /**
+     * Check whether this elements throws this exception class
+     * Note that this is simply a text compare,
+     * no actual type resolution takes place.
+     *
+     * @param throwableName the class of the exception
+     * @return true if found in throws clause, false if not
+     */
+    default boolean isThrown(String throwableName) {
+        return getThrownExceptions().stream().anyMatch(t -> t.toString().equals(throwableName));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTokenRange.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTokenRange.java
new file mode 100644
index 0000000..b043f64
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTokenRange.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.TokenRange;
+
+import java.util.Optional;
+
+/**
+ * A node that has a Range, which is every Node.
+ * 
+ */
+public interface NodeWithTokenRange<N> {
+    Optional<TokenRange> getTokenRange();
+
+    N setTokenRange(TokenRange range);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTraversableScope.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTraversableScope.java
new file mode 100644
index 0000000..a1b9b3b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTraversableScope.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.expr.Expression;
+
+import java.util.Optional;
+
+/**
+ * Represents a node which has a scope expression that can be traversed/walked.
+ * This unifies scope access for NodeWithScope and NodeWithOptionalScope.
+ */
+public interface NodeWithTraversableScope {
+
+    /**
+     * @return the scope of this node, regardless of optionality.
+     * An optional scope is returned directly.
+     * A required scope is returned in an "Optional", but will never be empty.
+     */
+    Optional<Expression> traverseScope();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithType.java
new file mode 100644
index 0000000..06e66fb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithType.java
@@ -0,0 +1,78 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.nodeTypes;

+

+import com.github.javaparser.ast.CompilationUnit;

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.type.Type;

+

+import static com.github.javaparser.JavaParser.parseType;

+import static com.github.javaparser.utils.Utils.assertNonEmpty;

+

+/**

+ * A node with a type.

+ * <p>

+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with getType/setType

+ * methods

+ *

+ * @since 2.3.1

+ */

+public interface NodeWithType<N extends Node, T extends Type> {

+    /**

+     * Gets the type

+     *

+     * @return the type

+     */

+    T getType();

+

+    /**

+     * Sets the type

+     *

+     * @param type the type

+     * @return this

+     */

+    N setType(T type);

+

+    void tryAddImportToParentCompilationUnit(Class<?> clazz);

+

+    /**

+     * Sets this type to this class and try to import it to the {@link CompilationUnit} if needed

+     *

+     * @param typeClass the type

+     * @return this

+     */

+    @SuppressWarnings("unchecked")

+    default N setType(Class<?> typeClass) {

+        tryAddImportToParentCompilationUnit(typeClass);

+        return setType((T) parseType(typeClass.getSimpleName()));

+    }

+

+    @SuppressWarnings("unchecked")

+    default N setType(final String typeString) {

+        assertNonEmpty(typeString);

+        return setType((T) parseType(typeString));

+    }

+

+    default String getTypeAsString() {

+        return getType().asString();

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments.java
new file mode 100644
index 0000000..0c72b22
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.metamodel.DerivedProperty;
+
+import java.util.Optional;
+
+import static com.github.javaparser.ast.NodeList.nodeList;
+
+/**
+ * A node that can have type arguments.
+ * <p>
+ * <pre>
+ *     new X();        --> typeArguments == Optional is empty
+ *     new X&lt;>();      --> typeArguments = [], diamondOperator = true
+ *     new X&lt;C,D>();   --> typeArguments = [C,D], diamondOperator = false
+ * </pre>
+ */
+public interface NodeWithTypeArguments<N extends Node> {
+    /**
+     * @return the types that can be found in the type arguments: &lt;String, Integer&gt;.
+     */
+    Optional<NodeList<Type>> getTypeArguments();
+
+    /**
+     * Allows you to set the generic arguments
+     *
+     * @param typeArguments The list of types of the generics, can be null
+     */
+    N setTypeArguments(NodeList<Type> typeArguments);
+
+    /**
+     * @return whether the type arguments look like &lt;>.
+     */
+    @DerivedProperty
+    default boolean isUsingDiamondOperator() {
+        return getTypeArguments().isPresent() && getTypeArguments().get().isEmpty();
+    }
+
+    /**
+     * Sets the type arguments to &lt>.
+     */
+    @SuppressWarnings("unchecked")
+    default N setDiamondOperator() {
+        return setTypeArguments(new NodeList<>());
+    }
+
+    /**
+     * Removes all type arguments, including the surrounding &lt;>.
+     */
+    @SuppressWarnings("unchecked")
+    default N removeTypeArguments() {
+        return setTypeArguments((NodeList<Type>) null);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setTypeArguments(Type... typeArguments) {
+        return setTypeArguments(nodeList(typeArguments));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTypeParameters.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTypeParameters.java
new file mode 100644
index 0000000..8817a76
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithTypeParameters.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.type.TypeParameter;
+
+/**
+ * A node that can have type parameters.
+ * <pre>
+ *     class X {}        --> typeParameters == []
+ *     class X&lt;> {}      --> does not occur.
+ *     class X&lt;C,D> {}   --> typeParameters = [C,D]
+ * </pre>
+ */
+public interface NodeWithTypeParameters<N extends Node> {
+    NodeList<TypeParameter> getTypeParameters();
+
+    default TypeParameter getTypeParameter(int i) {
+        return getTypeParameters().get(i);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setTypeParameter(int i, TypeParameter typeParameter) {
+        getTypeParameters().set(i, typeParameter);
+        return (N) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    default N addTypeParameter(TypeParameter typeParameter) {
+        getTypeParameters().add(typeParameter);
+        return (N) this;
+    }
+
+    N setTypeParameters(NodeList<TypeParameter> typeParameters);
+
+    default boolean isGeneric() {
+        return getTypeParameters().size() > 0;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java
new file mode 100644
index 0000000..5daf38a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.metamodel.DerivedProperty;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * A node which has a list of variables.
+ */
+public interface NodeWithVariables<N extends Node> {
+    NodeList<VariableDeclarator> getVariables();
+
+    N setVariables(NodeList<VariableDeclarator> variables);
+
+    default VariableDeclarator getVariable(int i) {
+        return getVariables().get(i);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setVariable(int i, VariableDeclarator variableDeclarator) {
+        getVariables().set(i, variableDeclarator);
+        return (N) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    default N addVariable(VariableDeclarator variableDeclarator) {
+        getVariables().add(variableDeclarator);
+        return (N) this;
+    }
+
+    /**
+     * Returns the type that is shared between all variables.
+     * This is a shortcut for when you are certain that all variables share one type.
+     * What makes this difficult is arrays, and being able to set the type.
+     * <br/>For <code>int a;</code> this is int.
+     * <br/>For <code>int a,b,c,d;</code> this is also int.
+     * <br/>For <code>int a,b[],c;</code> this is an assertion error since b is an int[], not an int.
+     * <br/>For <code>int a,b;</code>, then doing setType(String) on b, this is an assertion error. It is also a situation that you don't really want.
+     */
+    default Type getCommonType() {
+        NodeList<VariableDeclarator> variables = getVariables();
+        if (variables.isEmpty()) {
+            throw new AssertionError("There is no common type since there are no variables.");
+        }
+        Type type = variables.get(0).getType();
+        for (int i = 1; i < variables.size(); i++) {
+            if (!variables.get(i).getType().equals(type)) {
+                throw new AssertionError("The variables do not have a common type.");
+            }
+        }
+        return type;
+    }
+
+    /**
+     * Returns the element type.
+     * <br/>For <code>int a;</code> this is int.
+     * <br/>For <code>int a,b,c,d;</code> this is also int.
+     * <br/>For <code>int a,b[],c;</code> this is also int. Note: no mention of b being an array.
+     * <br/>For <code>int a,b;</code>, then doing setType(String) on b, then calling getElementType(). This is an assertion error. It is also a situation that you don't really want.
+     */
+    default Type getElementType() {
+        NodeList<VariableDeclarator> variables = getVariables();
+        if (variables.isEmpty()) {
+            throw new AssertionError("There is no element type since there are no variables.");
+        }
+        Type type = variables.get(0).getType().getElementType();
+        for (int i = 1; i < variables.size(); i++) {
+            if (!variables.get(i).getType().getElementType().equals(type)) {
+                throw new AssertionError("The variables do not have a common type.");
+            }
+        }
+        return type;
+    }
+
+    /**
+     * Returns the type that maximum shared type between all variables.
+     * The minimum common type does never include annotations on the array level.
+     * <p>
+     * <br/>For <code>int a;</code> this is int.
+     * <br/>For <code>int a,b,c,d;</code> this is also int.
+     * <br/>For <code>int a,b[],c;</code> this is also int.
+     * <br/>For <code>int[] a[][],b[],c[][];</code> this is int[][].
+     */
+    @DerivedProperty
+    default Optional<Type> getMaximumCommonType() {
+        return calculateMaximumCommonType(getVariables().stream().map(v -> v.getType()).collect(Collectors.toList()));
+    }
+
+    static Optional<Type> calculateMaximumCommonType(List<Type> types) {
+        // we use a local class because we cannot use an helper static method in an interface
+        class Helper {
+            // Conceptually: given a type we start from the Element Type and get as many array levels as indicated
+            // From the implementation point of view we start from the actual type and we remove how many array
+            // levels as needed to get the target level of arrays
+            // It returns null if the type has less array levels then the desired target
+            private Optional<Type> toArrayLevel(Type type, int level) {
+                if (level > type.getArrayLevel()) {
+                    return Optional.empty();
+                }
+                for (int i = type.getArrayLevel(); i > level; i--) {
+                    if (!(type instanceof ArrayType)) {
+                        return Optional.empty();
+                    }
+                    type = ((ArrayType) type).getComponentType();
+                }
+                return Optional.of(type);
+            }
+        }
+
+        Helper helper = new Helper();
+        int level = 0;
+        boolean keepGoing = true;
+        // In practice we want to check for how many levels of arrays all the variables have the same type,
+        // including also the annotations
+        while (keepGoing) {
+            final int currentLevel = level;
+            // Now, given that equality on nodes consider the position the simplest way is to compare
+            // the pretty-printed string got for a node. We just check all them are the same and if they
+            // are we just just is not null
+            Object[] values = types.stream().map(v -> {
+                Optional<Type> t = helper.toArrayLevel(v, currentLevel);
+                return t.map(Node::toString).orElse(null);
+            }).distinct().toArray();
+            if (values.length == 1 && values[0] != null) {
+                level++;
+            } else {
+                keepGoing = false;
+            }
+        }
+        return helper.toArrayLevel(types.get(0), --level);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithAbstractModifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithAbstractModifier.java
new file mode 100644
index 0000000..c81c4c6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithAbstractModifier.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+
+import static com.github.javaparser.ast.Modifier.ABSTRACT;
+
+/**
+ * A node that can be abstract.
+ */
+public interface NodeWithAbstractModifier<N extends Node> extends NodeWithModifiers<N> {
+    default boolean isAbstract() {
+        return getModifiers().contains(ABSTRACT);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setAbstract(boolean set) {
+        return setModifier(ABSTRACT, set);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithAccessModifiers.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithAccessModifiers.java
new file mode 100644
index 0000000..9569624
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithAccessModifiers.java
@@ -0,0 +1,9 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * A node that can be public, protected, and/or private.
+ */
+public interface NodeWithAccessModifiers<N extends Node> extends NodeWithPublicModifier<N>, NodeWithPrivateModifier<N>, NodeWithProtectedModifier<N> {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithFinalModifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithFinalModifier.java
new file mode 100644
index 0000000..91aae40
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithFinalModifier.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+
+import static com.github.javaparser.ast.Modifier.FINAL;
+
+/**
+ * A node that can be final.
+ */
+public interface NodeWithFinalModifier<N extends Node> extends NodeWithModifiers<N> {
+    default boolean isFinal() {
+        return getModifiers().contains(FINAL);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setFinal(boolean set) {
+        return setModifier(FINAL, set);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithPrivateModifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithPrivateModifier.java
new file mode 100644
index 0000000..4aa022c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithPrivateModifier.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+
+import static com.github.javaparser.ast.Modifier.*;
+
+/**
+ * A node that can be private.
+ */
+public interface NodeWithPrivateModifier<N extends Node> extends NodeWithModifiers<N> {
+    default boolean isPrivate() {
+        return getModifiers().contains(PRIVATE);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setPrivate(boolean set) {
+        return setModifier(PRIVATE, set);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithProtectedModifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithProtectedModifier.java
new file mode 100644
index 0000000..d2200b7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithProtectedModifier.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+
+import static com.github.javaparser.ast.Modifier.*;
+
+/**
+ * A node that can be protected.
+ */
+public interface NodeWithProtectedModifier<N extends Node> extends NodeWithModifiers<N> {
+    default boolean isProtected() {
+        return getModifiers().contains(PROTECTED);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setProtected(boolean set) {
+        return setModifier(PROTECTED, set);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithPublicModifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithPublicModifier.java
new file mode 100644
index 0000000..64b4067
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithPublicModifier.java
@@ -0,0 +1,21 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+
+import static com.github.javaparser.ast.Modifier.*;
+
+/**
+ * A node that can be public.
+ */
+public interface NodeWithPublicModifier<N extends Node> extends NodeWithModifiers<N> {
+    default boolean isPublic() {
+        return getModifiers().contains(PUBLIC);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setPublic(boolean set) {
+        return setModifier(PUBLIC, set);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithStaticModifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithStaticModifier.java
new file mode 100644
index 0000000..5ac63ea
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithStaticModifier.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+
+import static com.github.javaparser.ast.Modifier.STATIC;
+
+/**
+ * A node that can be static.
+ */
+public interface NodeWithStaticModifier<N extends Node> extends NodeWithModifiers<N> {
+
+    default boolean isStatic() {
+        return getModifiers().contains(STATIC);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setStatic(boolean set) {
+        return setModifier(STATIC, set);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithStrictfpModifier.java b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithStrictfpModifier.java
new file mode 100644
index 0000000..1d8fb41
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/nodeTypes/modifiers/NodeWithStrictfpModifier.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.ast.nodeTypes.modifiers;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+
+import static com.github.javaparser.ast.Modifier.STRICTFP;
+
+/**
+ * A node that can be strictfp.
+ */
+public interface NodeWithStrictfpModifier<N extends Node> extends NodeWithModifiers<N> {
+    default boolean isStrictfp() {
+        return getModifiers().contains(STRICTFP);
+    }
+
+    @SuppressWarnings("unchecked")
+    default N setStrictfp(boolean set) {
+        return setModifier(STRICTFP, set);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserver.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserver.java
new file mode 100644
index 0000000..6c41f4b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+
+/**
+ * An Observer for an AST element (either a Node or a NodeList).
+ */
+public interface AstObserver {
+
+    /**
+     * Type of change occurring on a List
+     */
+    enum ListChangeType {
+        ADDITION,
+        REMOVAL
+    }
+
+    /**
+     * The value of a property is changed
+     *
+     * @param observedNode owner of the property
+     * @param property property changed
+     * @param oldValue value of the property before the change
+     * @param newValue value of the property after the change
+     */
+    void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue);
+
+    /**
+     * The parent of a node is changed
+     *
+     * @param observedNode node of which the parent is changed
+     * @param previousParent previous parent
+     * @param newParent new parent
+     */
+    void parentChange(Node observedNode, Node previousParent, Node newParent);
+
+    /**
+     * A list is changed
+     *
+     * @param observedNode list changed
+     * @param type type of change
+     * @param index position at which the changed occurred
+     * @param nodeAddedOrRemoved element added or removed
+     */
+    void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved);
+
+    void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserverAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserverAdapter.java
new file mode 100644
index 0000000..82b9194
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/AstObserverAdapter.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+
+public abstract class AstObserverAdapter implements AstObserver {
+
+    @Override
+    public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+        // do nothing
+    }
+
+    @Override
+    public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+        // do nothing
+    }
+
+    @Override
+    public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+        // do nothing
+    }
+
+    @Override
+    public void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode) {
+        // do nothing
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/Observable.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/Observable.java
new file mode 100644
index 0000000..ce0f926
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/Observable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+/**
+ * Observable element.
+ */
+public interface Observable {
+
+    /**
+     * Register an observer.
+     */
+    void register(AstObserver observer);
+
+    /**
+     * Unregister an observer. If the given observer was not registered there are no effects.
+     */
+    void unregister(AstObserver observer);
+
+    /**
+     * Was this observer registered?
+     * Note that equals is used to determine if the given observer was registered.
+     */
+    boolean isRegistered(AstObserver observer);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java
new file mode 100644
index 0000000..d7f82f3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/ObservableProperty.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.utils.Utils;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.Arrays;
+import javax.annotation.Generated;
+
+/**
+ * Properties considered by the AstObserver
+ */
+@Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+public enum ObservableProperty {
+
+    ANNOTATIONS(Type.MULTIPLE_REFERENCE),
+    ANONYMOUS_CLASS_BODY(Type.MULTIPLE_REFERENCE),
+    ARGUMENTS(Type.MULTIPLE_REFERENCE),
+    ASTERISK(Type.SINGLE_ATTRIBUTE),
+    BODY(Type.SINGLE_REFERENCE),
+    CATCH_CLAUSES(Type.MULTIPLE_REFERENCE),
+    CHECK(Type.SINGLE_REFERENCE),
+    CLASS_BODY(Type.MULTIPLE_REFERENCE),
+    CLASS_DECLARATION(Type.SINGLE_REFERENCE),
+    CLASS_EXPR(Type.SINGLE_REFERENCE),
+    COMMENT(Type.SINGLE_REFERENCE),
+    COMPARE(Type.SINGLE_REFERENCE),
+    COMPONENT_TYPE(Type.SINGLE_REFERENCE),
+    CONDITION(Type.SINGLE_REFERENCE),
+    CONTENT(Type.SINGLE_ATTRIBUTE),
+    DEFAULT_VALUE(Type.SINGLE_REFERENCE),
+    DIMENSION(Type.SINGLE_REFERENCE),
+    ELEMENTS(Type.MULTIPLE_REFERENCE),
+    ELEMENT_TYPE(Type.SINGLE_REFERENCE),
+    ELSE_EXPR(Type.SINGLE_REFERENCE),
+    ELSE_STMT(Type.SINGLE_REFERENCE),
+    ENCLOSING_PARAMETERS(Type.SINGLE_ATTRIBUTE),
+    ENTRIES(Type.MULTIPLE_REFERENCE),
+    EXPRESSION(Type.SINGLE_REFERENCE),
+    EXTENDED_TYPE(Type.SINGLE_REFERENCE),
+    EXTENDED_TYPES(Type.MULTIPLE_REFERENCE),
+    FINALLY_BLOCK(Type.SINGLE_REFERENCE),
+    IDENTIFIER(Type.SINGLE_ATTRIBUTE),
+    IMPLEMENTED_TYPES(Type.MULTIPLE_REFERENCE),
+    IMPORTS(Type.MULTIPLE_REFERENCE),
+    INDEX(Type.SINGLE_REFERENCE),
+    INITIALIZATION(Type.MULTIPLE_REFERENCE),
+    INITIALIZER(Type.SINGLE_REFERENCE),
+    INNER(Type.SINGLE_REFERENCE),
+    INTERFACE(Type.SINGLE_ATTRIBUTE),
+    ITERABLE(Type.SINGLE_REFERENCE),
+    LABEL(Type.SINGLE_REFERENCE),
+    LEFT(Type.SINGLE_REFERENCE),
+    LEVELS(Type.MULTIPLE_REFERENCE),
+    MEMBERS(Type.MULTIPLE_REFERENCE),
+    MEMBER_VALUE(Type.SINGLE_REFERENCE),
+    MESSAGE(Type.SINGLE_REFERENCE),
+    MODIFIERS(Type.MULTIPLE_ATTRIBUTE),
+    MODULE(Type.SINGLE_REFERENCE),
+    MODULE_NAMES(Type.MULTIPLE_REFERENCE),
+    MODULE_STMTS(Type.MULTIPLE_REFERENCE),
+    NAME(Type.SINGLE_REFERENCE),
+    OPEN(Type.SINGLE_ATTRIBUTE),
+    OPERATOR(Type.SINGLE_ATTRIBUTE),
+    ORIGIN(Type.SINGLE_ATTRIBUTE),
+    PACKAGE_DECLARATION(Type.SINGLE_REFERENCE),
+    PAIRS(Type.MULTIPLE_REFERENCE),
+    PARAMETER(Type.SINGLE_REFERENCE),
+    PARAMETERS(Type.MULTIPLE_REFERENCE),
+    QUALIFIER(Type.SINGLE_REFERENCE),
+    RECEIVER_PARAMETER(Type.SINGLE_REFERENCE),
+    RESOURCES(Type.MULTIPLE_REFERENCE),
+    RIGHT(Type.SINGLE_REFERENCE),
+    SCOPE(Type.SINGLE_REFERENCE),
+    SELECTOR(Type.SINGLE_REFERENCE),
+    STATEMENT(Type.SINGLE_REFERENCE),
+    STATEMENTS(Type.MULTIPLE_REFERENCE),
+    STATIC(Type.SINGLE_ATTRIBUTE),
+    SUPER_TYPE(Type.SINGLE_REFERENCE),
+    TARGET(Type.SINGLE_REFERENCE),
+    THEN_EXPR(Type.SINGLE_REFERENCE),
+    THEN_STMT(Type.SINGLE_REFERENCE),
+    THIS(Type.SINGLE_ATTRIBUTE),
+    THROWN_EXCEPTIONS(Type.MULTIPLE_REFERENCE),
+    TRY_BLOCK(Type.SINGLE_REFERENCE),
+    TYPE(Type.SINGLE_REFERENCE),
+    TYPES(Type.MULTIPLE_REFERENCE),
+    TYPE_ARGUMENTS(Type.MULTIPLE_REFERENCE),
+    TYPE_BOUND(Type.MULTIPLE_REFERENCE),
+    TYPE_PARAMETERS(Type.MULTIPLE_REFERENCE),
+    UPDATE(Type.MULTIPLE_REFERENCE),
+    VALUE(Type.SINGLE_REFERENCE),
+    VALUES(Type.MULTIPLE_REFERENCE),
+    VARIABLE(Type.SINGLE_REFERENCE),
+    VARIABLES(Type.MULTIPLE_REFERENCE),
+    VAR_ARGS(Type.SINGLE_ATTRIBUTE),
+    VAR_ARGS_ANNOTATIONS(Type.MULTIPLE_REFERENCE),
+    WITH_TYPES(Type.MULTIPLE_REFERENCE),
+    CASCADING_IF_STMT(Type.SINGLE_ATTRIBUTE, true),
+    ELSE_BLOCK(Type.SINGLE_ATTRIBUTE, true),
+    ELSE_BRANCH(Type.SINGLE_ATTRIBUTE, true),
+    EXPRESSION_BODY(Type.SINGLE_REFERENCE, true),
+    MAXIMUM_COMMON_TYPE(Type.SINGLE_REFERENCE, true),
+    POSTFIX(Type.SINGLE_ATTRIBUTE, true),
+    PREFIX(Type.SINGLE_ATTRIBUTE, true),
+    THEN_BLOCK(Type.SINGLE_ATTRIBUTE, true),
+    USING_DIAMOND_OPERATOR(Type.SINGLE_ATTRIBUTE, true),
+    RANGE,
+    COMMENTED_NODE;
+
+    enum Type {
+
+        SINGLE_ATTRIBUTE(false, false), SINGLE_REFERENCE(false, true), MULTIPLE_ATTRIBUTE(true, false), MULTIPLE_REFERENCE(true, true);
+
+        private boolean multiple;
+
+        private boolean node;
+
+        Type(boolean multiple, boolean node) {
+            this.multiple = multiple;
+            this.node = node;
+        }
+    }
+
+    private Type type;
+
+    private boolean derived;
+
+    public static ObservableProperty fromCamelCaseName(String camelCaseName) {
+        Optional<ObservableProperty> observableProperty = Arrays.stream(values()).filter(v -> v.camelCaseName().equals(camelCaseName)).findFirst();
+        if (observableProperty.isPresent()) {
+            return observableProperty.get();
+        } else {
+            throw new IllegalArgumentException("No property found with the given camel case name: " + camelCaseName);
+        }
+    }
+
+    ObservableProperty(Type type) {
+        this.type = type;
+        this.derived = false;
+    }
+
+    ObservableProperty(Type type, boolean derived) {
+        this.type = type;
+        this.derived = derived;
+    }
+
+    ObservableProperty() {
+        this(Type.SINGLE_REFERENCE, false);
+    }
+
+    public boolean isDerived() {
+        return derived;
+    }
+
+    public boolean isAboutNodes() {
+        return type.node;
+    }
+
+    public boolean isAboutValues() {
+        return !isAboutNodes();
+    }
+
+    public boolean isMultiple() {
+        return type.multiple;
+    }
+
+    public boolean isSingle() {
+        return !isMultiple();
+    }
+
+    public String camelCaseName() {
+        return Utils.screamingToCamelCase(name());
+    }
+
+    public Node getValueAsSingleReference(Node node) {
+        Object rawValue = getRawValue(node);
+        try {
+            if (rawValue instanceof Node) {
+                return (Node) rawValue;
+            } else if (rawValue instanceof Optional) {
+                Optional<Node> opt = (Optional<Node>) rawValue;
+                if (opt.isPresent()) {
+                    return opt.get();
+                } else {
+                    return null;
+                }
+            } else {
+                throw new RuntimeException(String.format("Property %s returned %s (%s)", this.name(), rawValue.toString(), rawValue.getClass().getCanonicalName()));
+            }
+        } catch (ClassCastException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private boolean hasMethod(Node node, String name) {
+        try {
+            node.getClass().getMethod(name);
+            return true;
+        } catch (NoSuchMethodException e) {
+            return false;
+        }
+    }
+
+    public NodeList<? extends Node> getValueAsMultipleReference(Node node) {
+        Object rawValue = getRawValue(node);
+        try {
+            if (rawValue == null) {
+                return null;
+            }
+            if (rawValue instanceof NodeList) {
+                return (NodeList) rawValue;
+            } else {
+                Optional<NodeList> opt = (Optional<NodeList>) rawValue;
+                if (opt.isPresent()) {
+                    return opt.get();
+                } else {
+                    return null;
+                }
+            }
+        } catch (ClassCastException e) {
+            throw new RuntimeException("Unable to get list value for " + this.name() + " from " + node + " (class: " + node.getClass().getSimpleName() + ")", e);
+        }
+    }
+
+    public Collection<?> getValueAsCollection(Node node) {
+        Object rawValue = getRawValue(node);
+        try {
+            return (Collection) rawValue;
+        } catch (ClassCastException e) {
+            throw new RuntimeException("Unable to get list value for " + this.name() + " from " + node + " (class: " + node.getClass().getSimpleName() + ")", e);
+        }
+    }
+
+    public String getValueAsStringAttribute(Node node) {
+        return (String) getRawValue(node);
+    }
+
+    public Boolean getValueAsBooleanAttribute(Node node) {
+        return (Boolean) getRawValue(node);
+    }
+
+    public Object getRawValue(Node node) {
+        String getterName = "get" + Utils.capitalize(camelCaseName());
+        if (!hasMethod(node, getterName)) {
+            getterName = "is" + Utils.capitalize(camelCaseName());
+            if (!hasMethod(node, getterName)) {
+                getterName = "has" + Utils.capitalize(camelCaseName());
+            }
+        }
+        try {
+            return node.getClass().getMethod(getterName).invoke(node);
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            throw new RuntimeException("Unable to get value for " + this.name() + " from " + node + " (" + node.getClass().getSimpleName() + ")", e);
+        }
+    }
+
+    public boolean isNull(Node node) {
+        return null == getRawValue(node);
+    }
+
+    public boolean isNullOrNotPresent(Node node) {
+        Object result = getRawValue(node);
+        if (result == null) {
+            return true;
+        }
+        if (result instanceof Optional) {
+            return !((Optional) result).isPresent();
+        }
+        return false;
+    }
+
+    public boolean isNullOrEmpty(Node node) {
+        return Utils.valueIsNullOrEmpty(getRawValue(node));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/observer/PropagatingAstObserver.java b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/PropagatingAstObserver.java
new file mode 100644
index 0000000..1579474
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/observer/PropagatingAstObserver.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+
+/**
+ * This AstObserver attach itself to all new nodes added to the nodes already observed.
+ */
+public abstract class PropagatingAstObserver implements AstObserver {
+
+    /**
+     * Wrap a given observer to make it self-propagating. If the given observer is an instance of PropagatingAstObserver
+     * the observer is returned without changes.
+     */
+    public static PropagatingAstObserver transformInPropagatingObserver(final AstObserver observer) {
+        if (observer instanceof PropagatingAstObserver) {
+            return (PropagatingAstObserver) observer;
+        }
+        return new PropagatingAstObserver() {
+            @Override
+            public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                observer.propertyChange(observedNode, property, oldValue, newValue);
+            }
+
+            @Override
+            public void concreteListChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+                observer.listChange(observedNode, type, index, nodeAddedOrRemoved);
+            }
+
+            @Override
+            public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+                observer.parentChange(observedNode, previousParent, newParent);
+            }
+        };
+    }
+
+    @Override
+    public final void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+        considerRemoving(oldValue);
+        considerAdding(newValue);
+        concretePropertyChange(observedNode, property, oldValue, newValue);
+    }
+
+    @Override
+    public final void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+        if (type == ListChangeType.REMOVAL) {
+            considerRemoving(nodeAddedOrRemoved);
+        } else if (type == ListChangeType.ADDITION) {
+            considerAdding(nodeAddedOrRemoved);
+        }
+        concreteListChange(observedNode, type, index, nodeAddedOrRemoved);
+    }
+
+    @Override
+    public void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode) {
+        if (oldNode == newNode) {
+            return;
+        }
+        considerRemoving(oldNode);
+        considerAdding(newNode);
+        concreteListReplacement(observedNode, index, oldNode, newNode);
+    }
+
+    public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+        // do nothing
+    }
+
+    public void concreteListChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+        // do nothing
+    }
+
+    public void concreteListReplacement(NodeList observedNode, int index, Node oldValue, Node newValue) {
+        // do nothing
+    }
+
+    @Override
+    public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+        // do nothing
+    }
+
+    private void considerRemoving(Object element) {
+        if (element instanceof Observable) {
+            if (((Observable) element).isRegistered(this)) {
+                ((Observable) element).unregister(this);
+            }
+        }
+    }
+
+    private void considerAdding(Object element) {
+        if (element instanceof Node) {
+            ((Node) element).registerForSubtree(this);
+        } else if (element instanceof Observable) {
+            ((Observable) element).register(this);
+        }
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/AssertStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/AssertStmt.java
new file mode 100644
index 0000000..a6eb59f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/AssertStmt.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.AssertStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import java.util.function.Consumer;
+
+/**
+ * A usage of the keyword "assert"
+ * <br/>In <code>assert dead : "Wasn't expecting to be dead here";</code> the check is "dead" and the message is the string.
+ * @author Julio Vilmar Gesser
+ */
+public final class AssertStmt extends Statement {
+
+    private Expression check;
+
+    @OptionalProperty
+    private Expression message;
+
+    public AssertStmt() {
+        this(null, new BooleanLiteralExpr(), null);
+    }
+
+    public AssertStmt(final Expression check) {
+        this(null, check, null);
+    }
+
+    @AllFieldsConstructor
+    public AssertStmt(final Expression check, final Expression message) {
+        this(null, check, message);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public AssertStmt(TokenRange tokenRange, Expression check, Expression message) {
+        super(tokenRange);
+        setCheck(check);
+        setMessage(message);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getCheck() {
+        return check;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getMessage() {
+        return Optional.ofNullable(message);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AssertStmt setCheck(final Expression check) {
+        assertNotNull(check);
+        if (check == this.check) {
+            return (AssertStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.CHECK, this.check, check);
+        if (this.check != null)
+            this.check.setParentNode(null);
+        this.check = check;
+        setAsParentNodeOf(check);
+        return this;
+    }
+
+    /**
+     * Sets the message
+     *
+     * @param message the message, can be null
+     * @return this, the AssertStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public AssertStmt setMessage(final Expression message) {
+        if (message == this.message) {
+            return (AssertStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.MESSAGE, this.message, message);
+        if (this.message != null)
+            this.message.setParentNode(null);
+        this.message = message;
+        setAsParentNodeOf(message);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (message != null) {
+            if (node == message) {
+                removeMessage();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public AssertStmt removeMessage() {
+        return setMessage((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public AssertStmt clone() {
+        return (AssertStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public AssertStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.assertStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == check) {
+            setCheck((Expression) replacementNode);
+            return true;
+        }
+        if (message != null) {
+            if (node == message) {
+                setMessage((Expression) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAssertStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AssertStmt asAssertStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAssertStmt(Consumer<AssertStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AssertStmt> toAssertStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/BlockStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/BlockStmt.java
new file mode 100644
index 0000000..3e25b96
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/BlockStmt.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.BlockStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Statements in between { and }.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class BlockStmt extends Statement implements NodeWithStatements<BlockStmt> {
+
+    private NodeList<Statement> statements;
+
+    public BlockStmt() {
+        this(null, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public BlockStmt(final NodeList<Statement> statements) {
+        this(null, statements);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public BlockStmt(TokenRange tokenRange, NodeList<Statement> statements) {
+        super(tokenRange);
+        setStatements(statements);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Statement> getStatements() {
+        return statements;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BlockStmt setStatements(final NodeList<Statement> statements) {
+        assertNotNull(statements);
+        if (statements == this.statements) {
+            return (BlockStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.STATEMENTS, this.statements, statements);
+        if (this.statements != null)
+            this.statements.setParentNode(null);
+        this.statements = statements;
+        setAsParentNodeOf(statements);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < statements.size(); i++) {
+            if (statements.get(i) == node) {
+                statements.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public BlockStmt clone() {
+        return (BlockStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public BlockStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.blockStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < statements.size(); i++) {
+            if (statements.get(i) == node) {
+                statements.set(i, (Statement) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBlockStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BlockStmt asBlockStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBlockStmt(Consumer<BlockStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BlockStmt> toBlockStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/BreakStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/BreakStmt.java
new file mode 100644
index 0000000..4a0b411
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/BreakStmt.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.BreakStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import java.util.function.Consumer;
+
+/**
+ * A usage of the break keyword.
+ * <br/>In <code>break abc;</code> the label is abc.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class BreakStmt extends Statement {
+
+    @OptionalProperty
+    private SimpleName label;
+
+    public BreakStmt() {
+        this(null, new SimpleName());
+    }
+
+    public BreakStmt(final String label) {
+        this(null, new SimpleName(label));
+    }
+
+    @AllFieldsConstructor
+    public BreakStmt(final SimpleName label) {
+        this(null, label);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public BreakStmt(TokenRange tokenRange, SimpleName label) {
+        super(tokenRange);
+        setLabel(label);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<SimpleName> getLabel() {
+        return Optional.ofNullable(label);
+    }
+
+    /**
+     * Sets the label
+     *
+     * @param label the label, can be null
+     * @return this, the BreakStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BreakStmt setLabel(final SimpleName label) {
+        if (label == this.label) {
+            return (BreakStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.LABEL, this.label, label);
+        if (this.label != null)
+            this.label.setParentNode(null);
+        this.label = label;
+        setAsParentNodeOf(label);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (label != null) {
+            if (node == label) {
+                removeLabel();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public BreakStmt removeLabel() {
+        return setLabel((SimpleName) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public BreakStmt clone() {
+        return (BreakStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public BreakStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.breakStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (label != null) {
+            if (node == label) {
+                setLabel((SimpleName) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBreakStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BreakStmt asBreakStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBreakStmt(Consumer<BreakStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BreakStmt> toBreakStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/CatchClause.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/CatchClause.java
new file mode 100644
index 0000000..9eaa30e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/CatchClause.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.EnumSet;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.CatchClauseMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+
+/**
+ * The catch part of a try-catch-finally. <br/>In <code>try { ... } catch (Exception e) { ... }</code> the CatchClause
+ * is <code>catch (Exception e) { ... }</code>. Exception e is the parameter. The { ... } is the body.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class CatchClause extends Node implements NodeWithBlockStmt<CatchClause> {
+
+    private Parameter parameter;
+
+    private BlockStmt body;
+
+    public CatchClause() {
+        this(null, new Parameter(), new BlockStmt());
+    }
+
+    public CatchClause(final EnumSet<Modifier> exceptModifier, final NodeList<AnnotationExpr> exceptAnnotations, final ClassOrInterfaceType exceptType, final SimpleName exceptName, final BlockStmt body) {
+        this(null, new Parameter(null, exceptModifier, exceptAnnotations, exceptType, false, new NodeList<>(), exceptName), body);
+    }
+
+    @AllFieldsConstructor
+    public CatchClause(final Parameter parameter, final BlockStmt body) {
+        this(null, parameter, body);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public CatchClause(TokenRange tokenRange, Parameter parameter, BlockStmt body) {
+        super(tokenRange);
+        setParameter(parameter);
+        setBody(body);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Note that the type of the Parameter can be a UnionType. In this case, any annotations found at the start of the
+     * catch(@X A a |...) are found directly in the Parameter. Annotations that are on the second or later type -
+     * catch(A a | @X B b ...) are found on those types.
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Parameter getParameter() {
+        return parameter;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CatchClause setParameter(final Parameter parameter) {
+        assertNotNull(parameter);
+        if (parameter == this.parameter) {
+            return (CatchClause) this;
+        }
+        notifyPropertyChange(ObservableProperty.PARAMETER, this.parameter, parameter);
+        if (this.parameter != null)
+            this.parameter.setParentNode(null);
+        this.parameter = parameter;
+        setAsParentNodeOf(parameter);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BlockStmt getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public CatchClause setBody(final BlockStmt body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (CatchClause) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public CatchClause clone() {
+        return (CatchClause) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public CatchClauseMetaModel getMetaModel() {
+        return JavaParserMetaModel.catchClauseMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((BlockStmt) replacementNode);
+            return true;
+        }
+        if (node == parameter) {
+            setParameter((Parameter) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ContinueStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ContinueStmt.java
new file mode 100644
index 0000000..b829950
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ContinueStmt.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithOptionalLabel;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ContinueStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import java.util.function.Consumer;
+
+/**
+ * A continue statement with an optional label;
+ * <br/><code>continue brains;</code>
+ * <br/><code>continue;</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ContinueStmt extends Statement implements NodeWithOptionalLabel<ContinueStmt> {
+
+    @OptionalProperty
+    private SimpleName label;
+
+    public ContinueStmt() {
+        this(null, null);
+    }
+
+    public ContinueStmt(final String label) {
+        this(null, new SimpleName(label));
+    }
+
+    @AllFieldsConstructor
+    public ContinueStmt(final SimpleName label) {
+        this(null, label);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ContinueStmt(TokenRange tokenRange, SimpleName label) {
+        super(tokenRange);
+        setLabel(label);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<SimpleName> getLabel() {
+        return Optional.ofNullable(label);
+    }
+
+    /**
+     * Sets the label
+     *
+     * @param label the label, can be null
+     * @return this, the ContinueStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ContinueStmt setLabel(final SimpleName label) {
+        if (label == this.label) {
+            return (ContinueStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.LABEL, this.label, label);
+        if (this.label != null)
+            this.label.setParentNode(null);
+        this.label = label;
+        setAsParentNodeOf(label);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (label != null) {
+            if (node == label) {
+                removeLabel();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ContinueStmt removeLabel() {
+        return setLabel((SimpleName) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ContinueStmt clone() {
+        return (ContinueStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ContinueStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.continueStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (label != null) {
+            if (node == label) {
+                setLabel((SimpleName) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isContinueStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ContinueStmt asContinueStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifContinueStmt(Consumer<ContinueStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ContinueStmt> toContinueStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/DoStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/DoStmt.java
new file mode 100644
index 0000000..7c161ff
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/DoStmt.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.nodeTypes.NodeWithCondition;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.DoStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A do-while.
+ * <br/><code>do { ... } while ( a==0 );</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class DoStmt extends Statement implements NodeWithBody<DoStmt>, NodeWithCondition<DoStmt> {
+
+    private Statement body;
+
+    private Expression condition;
+
+    public DoStmt() {
+        this(null, new ReturnStmt(), new BooleanLiteralExpr());
+    }
+
+    @AllFieldsConstructor
+    public DoStmt(final Statement body, final Expression condition) {
+        this(null, body, condition);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public DoStmt(TokenRange tokenRange, Statement body, Expression condition) {
+        super(tokenRange);
+        setBody(body);
+        setCondition(condition);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Statement getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getCondition() {
+        return condition;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public DoStmt setBody(final Statement body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (DoStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public DoStmt setCondition(final Expression condition) {
+        assertNotNull(condition);
+        if (condition == this.condition) {
+            return (DoStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.CONDITION, this.condition, condition);
+        if (this.condition != null)
+            this.condition.setParentNode(null);
+        this.condition = condition;
+        setAsParentNodeOf(condition);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public DoStmt clone() {
+        return (DoStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public DoStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.doStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((Statement) replacementNode);
+            return true;
+        }
+        if (node == condition) {
+            setCondition((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isDoStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public DoStmt asDoStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifDoStmt(Consumer<DoStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<DoStmt> toDoStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/EmptyStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/EmptyStmt.java
new file mode 100644
index 0000000..d73ede6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/EmptyStmt.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.EmptyStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An empty statement is a ";" where a statement is expected.
+ * @author Julio Vilmar Gesser
+ */
+public final class EmptyStmt extends Statement {
+
+    @AllFieldsConstructor
+    public EmptyStmt() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public EmptyStmt(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public EmptyStmt clone() {
+        return (EmptyStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public EmptyStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.emptyStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEmptyStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EmptyStmt asEmptyStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEmptyStmt(Consumer<EmptyStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EmptyStmt> toEmptyStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java
new file mode 100644
index 0000000..2b9b9c2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ExplicitConstructorInvocationStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import java.util.function.Consumer;
+
+/**
+ * A call to super or this in a constructor or initializer.
+ * <br/><code>class X { X() { super(15); } }</code>
+ * <br/><code>class X { X() { this(1, 2); } }</code>
+ *
+ * @author Julio Vilmar Gesser
+ * @see com.github.javaparser.ast.expr.SuperExpr
+ * @see com.github.javaparser.ast.expr.ThisExpr
+ */
+public final class ExplicitConstructorInvocationStmt extends Statement implements NodeWithTypeArguments<ExplicitConstructorInvocationStmt> {
+
+    @OptionalProperty
+    private NodeList<Type> typeArguments;
+
+    private boolean isThis;
+
+    @OptionalProperty
+    private Expression expression;
+
+    private NodeList<Expression> arguments;
+
+    public ExplicitConstructorInvocationStmt() {
+        this(null, new NodeList<>(), true, null, new NodeList<>());
+    }
+
+    public ExplicitConstructorInvocationStmt(final boolean isThis, final Expression expression, final NodeList<Expression> arguments) {
+        this(null, new NodeList<>(), isThis, expression, arguments);
+    }
+
+    @AllFieldsConstructor
+    public ExplicitConstructorInvocationStmt(final NodeList<Type> typeArguments, final boolean isThis, final Expression expression, final NodeList<Expression> arguments) {
+        this(null, typeArguments, isThis, expression, arguments);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ExplicitConstructorInvocationStmt(TokenRange tokenRange, NodeList<Type> typeArguments, boolean isThis, Expression expression, NodeList<Expression> arguments) {
+        super(tokenRange);
+        setTypeArguments(typeArguments);
+        setThis(isThis);
+        setExpression(expression);
+        setArguments(arguments);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getArguments() {
+        return arguments;
+    }
+
+    public Expression getArgument(int i) {
+        return getArguments().get(i);
+    }
+
+    public ExplicitConstructorInvocationStmt setArgument(int i, Expression argument) {
+        getArguments().set(i, argument);
+        return this;
+    }
+
+    public ExplicitConstructorInvocationStmt addArgument(Expression argument) {
+        getArguments().add(argument);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getExpression() {
+        return Optional.ofNullable(expression);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public boolean isThis() {
+        return isThis;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ExplicitConstructorInvocationStmt setArguments(final NodeList<Expression> arguments) {
+        assertNotNull(arguments);
+        if (arguments == this.arguments) {
+            return (ExplicitConstructorInvocationStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.ARGUMENTS, this.arguments, arguments);
+        if (this.arguments != null)
+            this.arguments.setParentNode(null);
+        this.arguments = arguments;
+        setAsParentNodeOf(arguments);
+        return this;
+    }
+
+    /**
+     * Sets the expression
+     *
+     * @param expression the expression, can be null
+     * @return this, the ExplicitConstructorInvocationStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ExplicitConstructorInvocationStmt setExpression(final Expression expression) {
+        if (expression == this.expression) {
+            return (ExplicitConstructorInvocationStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ExplicitConstructorInvocationStmt setThis(final boolean isThis) {
+        if (isThis == this.isThis) {
+            return (ExplicitConstructorInvocationStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.THIS, this.isThis, isThis);
+        this.isThis = isThis;
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<NodeList<Type>> getTypeArguments() {
+        return Optional.ofNullable(typeArguments);
+    }
+
+    /**
+     * Sets the typeArguments
+     *
+     * @param typeArguments the typeArguments, can be null
+     * @return this, the ExplicitConstructorInvocationStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ExplicitConstructorInvocationStmt setTypeArguments(final NodeList<Type> typeArguments) {
+        if (typeArguments == this.typeArguments) {
+            return (ExplicitConstructorInvocationStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_ARGUMENTS, this.typeArguments, typeArguments);
+        if (this.typeArguments != null)
+            this.typeArguments.setParentNode(null);
+        this.typeArguments = typeArguments;
+        setAsParentNodeOf(typeArguments);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.remove(i);
+                return true;
+            }
+        }
+        if (expression != null) {
+            if (node == expression) {
+                removeExpression();
+                return true;
+            }
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.remove(i);
+                    return true;
+                }
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ExplicitConstructorInvocationStmt removeExpression() {
+        return setExpression((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ExplicitConstructorInvocationStmt clone() {
+        return (ExplicitConstructorInvocationStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ExplicitConstructorInvocationStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.explicitConstructorInvocationStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < arguments.size(); i++) {
+            if (arguments.get(i) == node) {
+                arguments.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        if (expression != null) {
+            if (node == expression) {
+                setExpression((Expression) replacementNode);
+                return true;
+            }
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.set(i, (Type) replacementNode);
+                    return true;
+                }
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isExplicitConstructorInvocationStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ExplicitConstructorInvocationStmt asExplicitConstructorInvocationStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifExplicitConstructorInvocationStmt(Consumer<ExplicitConstructorInvocationStmt> action) {
+        action.accept(this);
+    }
+
+    public ResolvedConstructorDeclaration resolveInvokedConstructor() {
+        return getSymbolResolver().resolveDeclaration(this, ResolvedConstructorDeclaration.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ExplicitConstructorInvocationStmt> toExplicitConstructorInvocationStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ExpressionStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ExpressionStmt.java
new file mode 100644
index 0000000..483c45d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ExpressionStmt.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithExpression;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ExpressionStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Used to wrap an expression so that it can take the place of a statement.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ExpressionStmt extends Statement implements NodeWithExpression<ExpressionStmt> {
+
+    private Expression expression;
+
+    public ExpressionStmt() {
+        this(null, new BooleanLiteralExpr());
+    }
+
+    @AllFieldsConstructor
+    public ExpressionStmt(final Expression expression) {
+        this(null, expression);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ExpressionStmt(TokenRange tokenRange, Expression expression) {
+        super(tokenRange);
+        setExpression(expression);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getExpression() {
+        return expression;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ExpressionStmt setExpression(final Expression expression) {
+        assertNotNull(expression);
+        if (expression == this.expression) {
+            return (ExpressionStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ExpressionStmt clone() {
+        return (ExpressionStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ExpressionStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.expressionStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == expression) {
+            setExpression((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isExpressionStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ExpressionStmt asExpressionStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifExpressionStmt(Consumer<ExpressionStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ExpressionStmt> toExpressionStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ForStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ForStmt.java
new file mode 100644
index 0000000..d288991
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ForStmt.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.ForStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.OptionalProperty;
+import javax.annotation.Generated;
+import java.util.Optional;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * <h1>The classic for statement</h1>
+ * Examples:
+ * <ol>
+ * <li><code>for(int a=3, b=5; a<99; a++, b++) hello();</code></li>
+ * <li><code>for(a=3, b=5; a<99; a++) { hello(); }</code> </li>
+ * <li><code>for(a(),b();;) hello();</code> </li>
+ * </ol>
+ * <ul>
+ * <li><i>initialization</i> is a list of expressions.
+ * These can be any kind of expression as can be seen in example 3,
+ * but the common ones are a single VariableDeclarationExpr (which declares multiple variables) in example 1,
+ * or a list of AssignExpr's in example 2.</li>
+ * <li><i>compare</i> is an expression,
+ * in example 1 and 2 it is a BinaryExpr.
+ * In example 3 there is no expression, it is empty.</li>
+ * <li><i>update</i> is a list of expressions,
+ * in example 1 and 2 they are UnaryExpr's.
+ * In example 3 there is no expression, the list empty.</li>
+ * <li><i>body</i> is a statement,
+ * in example 1 and 3 it is an ExpressionStmt.
+ * in example 2 it is a BlockStmt.</li>
+ * </ul>
+ *
+ * @author Julio Vilmar Gesser
+ * @see com.github.javaparser.ast.expr.VariableDeclarationExpr
+ */
+public final class ForStmt extends Statement implements NodeWithBody<ForStmt> {
+
+    private NodeList<Expression> initialization;
+
+    @OptionalProperty
+    private Expression compare;
+
+    private NodeList<Expression> update;
+
+    private Statement body;
+
+    public ForStmt() {
+        this(null, new NodeList<>(), new BooleanLiteralExpr(), new NodeList<>(), new ReturnStmt());
+    }
+
+    @AllFieldsConstructor
+    public ForStmt(final NodeList<Expression> initialization, final Expression compare, final NodeList<Expression> update, final Statement body) {
+        this(null, initialization, compare, update, body);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ForStmt(TokenRange tokenRange, NodeList<Expression> initialization, Expression compare, NodeList<Expression> update, Statement body) {
+        super(tokenRange);
+        setInitialization(initialization);
+        setCompare(compare);
+        setUpdate(update);
+        setBody(body);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Statement getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getCompare() {
+        return Optional.ofNullable(compare);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getInitialization() {
+        return initialization;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getUpdate() {
+        return update;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ForStmt setBody(final Statement body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (ForStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    /**
+     * Sets the compare
+     *
+     * @param compare the compare, can be null
+     * @return this, the ForStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ForStmt setCompare(final Expression compare) {
+        if (compare == this.compare) {
+            return (ForStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.COMPARE, this.compare, compare);
+        if (this.compare != null)
+            this.compare.setParentNode(null);
+        this.compare = compare;
+        setAsParentNodeOf(compare);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ForStmt setInitialization(final NodeList<Expression> initialization) {
+        assertNotNull(initialization);
+        if (initialization == this.initialization) {
+            return (ForStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.INITIALIZATION, this.initialization, initialization);
+        if (this.initialization != null)
+            this.initialization.setParentNode(null);
+        this.initialization = initialization;
+        setAsParentNodeOf(initialization);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ForStmt setUpdate(final NodeList<Expression> update) {
+        assertNotNull(update);
+        if (update == this.update) {
+            return (ForStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.UPDATE, this.update, update);
+        if (this.update != null)
+            this.update.setParentNode(null);
+        this.update = update;
+        setAsParentNodeOf(update);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (compare != null) {
+            if (node == compare) {
+                removeCompare();
+                return true;
+            }
+        }
+        for (int i = 0; i < initialization.size(); i++) {
+            if (initialization.get(i) == node) {
+                initialization.remove(i);
+                return true;
+            }
+        }
+        for (int i = 0; i < update.size(); i++) {
+            if (update.get(i) == node) {
+                update.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ForStmt removeCompare() {
+        return setCompare((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ForStmt clone() {
+        return (ForStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ForStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.forStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((Statement) replacementNode);
+            return true;
+        }
+        if (compare != null) {
+            if (node == compare) {
+                setCompare((Expression) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < initialization.size(); i++) {
+            if (initialization.get(i) == node) {
+                initialization.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < update.size(); i++) {
+            if (update.get(i) == node) {
+                update.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isForStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ForStmt asForStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifForStmt(Consumer<ForStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ForStmt> toForStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ForeachStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ForeachStmt.java
new file mode 100644
index 0000000..7a04e5b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ForeachStmt.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ForeachStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A for-each statement.
+ * <br/><code>for(Object o: objects) { ... }</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ForeachStmt extends Statement implements NodeWithBody<ForeachStmt> {
+
+    private VariableDeclarationExpr variable;
+
+    private Expression iterable;
+
+    private Statement body;
+
+    public ForeachStmt() {
+        this(null, new VariableDeclarationExpr(), new NameExpr(), new ReturnStmt());
+    }
+
+    @AllFieldsConstructor
+    public ForeachStmt(final VariableDeclarationExpr variable, final Expression iterable, final Statement body) {
+        this(null, variable, iterable, body);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ForeachStmt(TokenRange tokenRange, VariableDeclarationExpr variable, Expression iterable, Statement body) {
+        super(tokenRange);
+        setVariable(variable);
+        setIterable(iterable);
+        setBody(body);
+        customInitialization();
+    }
+
+    public ForeachStmt(VariableDeclarationExpr variable, String iterable, BlockStmt body) {
+        this(null, variable, new NameExpr(iterable), body);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Statement getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getIterable() {
+        return iterable;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public VariableDeclarationExpr getVariable() {
+        return variable;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ForeachStmt setBody(final Statement body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (ForeachStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ForeachStmt setIterable(final Expression iterable) {
+        assertNotNull(iterable);
+        if (iterable == this.iterable) {
+            return (ForeachStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.ITERABLE, this.iterable, iterable);
+        if (this.iterable != null)
+            this.iterable.setParentNode(null);
+        this.iterable = iterable;
+        setAsParentNodeOf(iterable);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ForeachStmt setVariable(final VariableDeclarationExpr variable) {
+        assertNotNull(variable);
+        if (variable == this.variable) {
+            return (ForeachStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.VARIABLE, this.variable, variable);
+        if (this.variable != null)
+            this.variable.setParentNode(null);
+        this.variable = variable;
+        setAsParentNodeOf(variable);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ForeachStmt clone() {
+        return (ForeachStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ForeachStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.foreachStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((Statement) replacementNode);
+            return true;
+        }
+        if (node == iterable) {
+            setIterable((Expression) replacementNode);
+            return true;
+        }
+        if (node == variable) {
+            setVariable((VariableDeclarationExpr) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isForeachStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ForeachStmt asForeachStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifForeachStmt(Consumer<ForeachStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ForeachStmt> toForeachStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/IfStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/IfStmt.java
new file mode 100644
index 0000000..f873ff8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/IfStmt.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithCondition;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.DerivedProperty;
+import com.github.javaparser.metamodel.IfStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import java.util.function.Consumer;
+
+/**
+ * An if-then-else statement. The else is optional.
+ * <br/>In <code>if(a==5) hurray() else boo();</code> the condition is a==5,
+ * hurray() is the thenStmt, and boo() is the elseStmt.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class IfStmt extends Statement implements NodeWithCondition<IfStmt> {
+
+    private Expression condition;
+
+    private Statement thenStmt;
+
+    @OptionalProperty
+    private Statement elseStmt;
+
+    public IfStmt() {
+        this(null, new BooleanLiteralExpr(), new ReturnStmt(), null);
+    }
+
+    @AllFieldsConstructor
+    public IfStmt(final Expression condition, final Statement thenStmt, final Statement elseStmt) {
+        this(null, condition, thenStmt, elseStmt);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public IfStmt(TokenRange tokenRange, Expression condition, Statement thenStmt, Statement elseStmt) {
+        super(tokenRange);
+        setCondition(condition);
+        setThenStmt(thenStmt);
+        setElseStmt(elseStmt);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getCondition() {
+        return condition;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Statement> getElseStmt() {
+        return Optional.ofNullable(elseStmt);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Statement getThenStmt() {
+        return thenStmt;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public IfStmt setCondition(final Expression condition) {
+        assertNotNull(condition);
+        if (condition == this.condition) {
+            return (IfStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.CONDITION, this.condition, condition);
+        if (this.condition != null)
+            this.condition.setParentNode(null);
+        this.condition = condition;
+        setAsParentNodeOf(condition);
+        return this;
+    }
+
+    /**
+     * Sets the elseStmt
+     *
+     * @param elseStmt the elseStmt, can be null
+     * @return this, the IfStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public IfStmt setElseStmt(final Statement elseStmt) {
+        if (elseStmt == this.elseStmt) {
+            return (IfStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.ELSE_STMT, this.elseStmt, elseStmt);
+        if (this.elseStmt != null)
+            this.elseStmt.setParentNode(null);
+        this.elseStmt = elseStmt;
+        setAsParentNodeOf(elseStmt);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public IfStmt setThenStmt(final Statement thenStmt) {
+        assertNotNull(thenStmt);
+        if (thenStmt == this.thenStmt) {
+            return (IfStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.THEN_STMT, this.thenStmt, thenStmt);
+        if (this.thenStmt != null)
+            this.thenStmt.setParentNode(null);
+        this.thenStmt = thenStmt;
+        setAsParentNodeOf(thenStmt);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (elseStmt != null) {
+            if (node == elseStmt) {
+                removeElseStmt();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public IfStmt removeElseStmt() {
+        return setElseStmt((Statement) null);
+    }
+
+    /**
+     * This method returns true if the then branch (which should be always present) is a block statement.
+     */
+    @DerivedProperty
+    public boolean hasThenBlock() {
+        return thenStmt instanceof BlockStmt;
+    }
+
+    /**
+     * This method returns true if the If Statement has an else branch and that branch is a block statement.
+     */
+    @DerivedProperty
+    public boolean hasElseBlock() {
+        return elseStmt instanceof BlockStmt;
+    }
+
+    /**
+     * This method returns true if the If Statement has an else branch and that branch is another If Statement.
+     */
+    @DerivedProperty
+    public boolean hasCascadingIfStmt() {
+        return elseStmt instanceof IfStmt;
+    }
+
+    /**
+     * This method returns true if the If Statement has an else branch.
+     */
+    @DerivedProperty
+    public boolean hasElseBranch() {
+        return elseStmt != null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public IfStmt clone() {
+        return (IfStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public IfStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.ifStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == condition) {
+            setCondition((Expression) replacementNode);
+            return true;
+        }
+        if (elseStmt != null) {
+            if (node == elseStmt) {
+                setElseStmt((Statement) replacementNode);
+                return true;
+            }
+        }
+        if (node == thenStmt) {
+            setThenStmt((Statement) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isIfStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public IfStmt asIfStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifIfStmt(Consumer<IfStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<IfStmt> toIfStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/LabeledStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/LabeledStmt.java
new file mode 100644
index 0000000..7906d0c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/LabeledStmt.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.LabeledStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A statement that is labeled, like <code>label123: println("continuing");</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class LabeledStmt extends Statement {
+
+    private SimpleName label;
+
+    private Statement statement;
+
+    public LabeledStmt() {
+        this(null, new SimpleName(), new ReturnStmt());
+    }
+
+    public LabeledStmt(final String label, final Statement statement) {
+        this(null, new SimpleName(label), statement);
+    }
+
+    @AllFieldsConstructor
+    public LabeledStmt(final SimpleName label, final Statement statement) {
+        this(null, label, statement);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public LabeledStmt(TokenRange tokenRange, SimpleName label, Statement statement) {
+        super(tokenRange);
+        setLabel(label);
+        setStatement(statement);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Statement getStatement() {
+        return statement;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public LabeledStmt setStatement(final Statement statement) {
+        assertNotNull(statement);
+        if (statement == this.statement) {
+            return (LabeledStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.STATEMENT, this.statement, statement);
+        if (this.statement != null)
+            this.statement.setParentNode(null);
+        this.statement = statement;
+        setAsParentNodeOf(statement);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getLabel() {
+        return label;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public LabeledStmt setLabel(final SimpleName label) {
+        assertNotNull(label);
+        if (label == this.label) {
+            return (LabeledStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.LABEL, this.label, label);
+        if (this.label != null)
+            this.label.setParentNode(null);
+        this.label = label;
+        setAsParentNodeOf(label);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public LabeledStmt clone() {
+        return (LabeledStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public LabeledStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.labeledStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == label) {
+            setLabel((SimpleName) replacementNode);
+            return true;
+        }
+        if (node == statement) {
+            setStatement((Statement) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLabeledStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LabeledStmt asLabeledStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLabeledStmt(Consumer<LabeledStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LabeledStmt> toLabeledStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/LocalClassDeclarationStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/LocalClassDeclarationStmt.java
new file mode 100644
index 0000000..f78eebc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/LocalClassDeclarationStmt.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.LocalClassDeclarationStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * <h1>A class declaration inside a method.</h1>
+ * <h2>Java 1.0</h2>
+ * Not available.
+ * <h2>Java 1.1+</h2>
+ * A statement consisting of a class declaration.
+ * <br/><code>class X { void m() { <b>class Y { }</b> } }</code>
+ *
+ * @see ClassOrInterfaceDeclaration
+ * @author Julio Vilmar Gesser
+ */
+public final class LocalClassDeclarationStmt extends Statement {
+
+    private ClassOrInterfaceDeclaration classDeclaration;
+
+    public LocalClassDeclarationStmt() {
+        this(null, new ClassOrInterfaceDeclaration());
+    }
+
+    @AllFieldsConstructor
+    public LocalClassDeclarationStmt(final ClassOrInterfaceDeclaration classDeclaration) {
+        this(null, classDeclaration);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public LocalClassDeclarationStmt(TokenRange tokenRange, ClassOrInterfaceDeclaration classDeclaration) {
+        super(tokenRange);
+        setClassDeclaration(classDeclaration);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceDeclaration getClassDeclaration() {
+        return classDeclaration;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public LocalClassDeclarationStmt setClassDeclaration(final ClassOrInterfaceDeclaration classDeclaration) {
+        assertNotNull(classDeclaration);
+        if (classDeclaration == this.classDeclaration) {
+            return (LocalClassDeclarationStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.CLASS_DECLARATION, this.classDeclaration, classDeclaration);
+        if (this.classDeclaration != null)
+            this.classDeclaration.setParentNode(null);
+        this.classDeclaration = classDeclaration;
+        setAsParentNodeOf(classDeclaration);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public LocalClassDeclarationStmt clone() {
+        return (LocalClassDeclarationStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public LocalClassDeclarationStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.localClassDeclarationStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == classDeclaration) {
+            setClassDeclaration((ClassOrInterfaceDeclaration) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLocalClassDeclarationStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LocalClassDeclarationStmt asLocalClassDeclarationStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLocalClassDeclarationStmt(Consumer<LocalClassDeclarationStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LocalClassDeclarationStmt> toLocalClassDeclarationStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ReturnStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ReturnStmt.java
new file mode 100644
index 0000000..c9bdb45
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ReturnStmt.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.metamodel.ReturnStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+
+/**
+ * The return statement, with an optional expression to return.
+ * <br/><code>return 5 * 5;</code>
+ * @author Julio Vilmar Gesser
+ */
+public final class ReturnStmt extends Statement {
+
+    @OptionalProperty
+    private Expression expression;
+
+    public ReturnStmt() {
+        this(null, null);
+    }
+
+    @AllFieldsConstructor
+    public ReturnStmt(final Expression expression) {
+        this(null, expression);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ReturnStmt(TokenRange tokenRange, Expression expression) {
+        super(tokenRange);
+        setExpression(expression);
+        customInitialization();
+    }
+
+    /**
+     * Will create a NameExpr with the string param
+     */
+    public ReturnStmt(String expression) {
+        this(null, new NameExpr(expression));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getExpression() {
+        return Optional.ofNullable(expression);
+    }
+
+    /**
+     * Sets the expression
+     *
+     * @param expression the expression, can be null
+     * @return this, the ReturnStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ReturnStmt setExpression(final Expression expression) {
+        if (expression == this.expression) {
+            return (ReturnStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (expression != null) {
+            if (node == expression) {
+                removeExpression();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ReturnStmt removeExpression() {
+        return setExpression((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ReturnStmt clone() {
+        return (ReturnStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ReturnStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.returnStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (expression != null) {
+            if (node == expression) {
+                setExpression((Expression) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isReturnStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ReturnStmt asReturnStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifReturnStmt(Consumer<ReturnStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ReturnStmt> toReturnStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/Statement.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/Statement.java
new file mode 100644
index 0000000..75100e8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/Statement.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.StatementMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import java.util.Optional;
+
+/**
+ * A base class for all statements.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Statement extends Node {
+
+    @AllFieldsConstructor
+    public Statement() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public Statement(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public Statement clone() {
+        return (Statement) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public StatementMetaModel getMetaModel() {
+        return JavaParserMetaModel.statementMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isAssertStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public AssertStmt asAssertStmt() {
+        throw new IllegalStateException(f("%s is not an AssertStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBlockStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BlockStmt asBlockStmt() {
+        throw new IllegalStateException(f("%s is not an BlockStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isBreakStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public BreakStmt asBreakStmt() {
+        throw new IllegalStateException(f("%s is not an BreakStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isContinueStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ContinueStmt asContinueStmt() {
+        throw new IllegalStateException(f("%s is not an ContinueStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isDoStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public DoStmt asDoStmt() {
+        throw new IllegalStateException(f("%s is not an DoStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isEmptyStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public EmptyStmt asEmptyStmt() {
+        throw new IllegalStateException(f("%s is not an EmptyStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isExplicitConstructorInvocationStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ExplicitConstructorInvocationStmt asExplicitConstructorInvocationStmt() {
+        throw new IllegalStateException(f("%s is not an ExplicitConstructorInvocationStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isExpressionStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ExpressionStmt asExpressionStmt() {
+        throw new IllegalStateException(f("%s is not an ExpressionStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isForStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ForStmt asForStmt() {
+        throw new IllegalStateException(f("%s is not an ForStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isForeachStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ForeachStmt asForeachStmt() {
+        throw new IllegalStateException(f("%s is not an ForeachStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isIfStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public IfStmt asIfStmt() {
+        throw new IllegalStateException(f("%s is not an IfStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLabeledStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LabeledStmt asLabeledStmt() {
+        throw new IllegalStateException(f("%s is not an LabeledStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isLocalClassDeclarationStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public LocalClassDeclarationStmt asLocalClassDeclarationStmt() {
+        throw new IllegalStateException(f("%s is not an LocalClassDeclarationStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isReturnStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ReturnStmt asReturnStmt() {
+        throw new IllegalStateException(f("%s is not an ReturnStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSwitchEntryStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SwitchEntryStmt asSwitchEntryStmt() {
+        throw new IllegalStateException(f("%s is not an SwitchEntryStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSwitchStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SwitchStmt asSwitchStmt() {
+        throw new IllegalStateException(f("%s is not an SwitchStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSynchronizedStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SynchronizedStmt asSynchronizedStmt() {
+        throw new IllegalStateException(f("%s is not an SynchronizedStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isThrowStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ThrowStmt asThrowStmt() {
+        throw new IllegalStateException(f("%s is not an ThrowStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTryStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TryStmt asTryStmt() {
+        throw new IllegalStateException(f("%s is not an TryStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnparsableStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnparsableStmt asUnparsableStmt() {
+        throw new IllegalStateException(f("%s is not an UnparsableStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isWhileStmt() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public WhileStmt asWhileStmt() {
+        throw new IllegalStateException(f("%s is not an WhileStmt", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifAssertStmt(Consumer<AssertStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBlockStmt(Consumer<BlockStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifBreakStmt(Consumer<BreakStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifContinueStmt(Consumer<ContinueStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifDoStmt(Consumer<DoStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifEmptyStmt(Consumer<EmptyStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifExplicitConstructorInvocationStmt(Consumer<ExplicitConstructorInvocationStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifExpressionStmt(Consumer<ExpressionStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifForStmt(Consumer<ForStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifForeachStmt(Consumer<ForeachStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifIfStmt(Consumer<IfStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLabeledStmt(Consumer<LabeledStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifLocalClassDeclarationStmt(Consumer<LocalClassDeclarationStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifReturnStmt(Consumer<ReturnStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSwitchEntryStmt(Consumer<SwitchEntryStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSwitchStmt(Consumer<SwitchStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSynchronizedStmt(Consumer<SynchronizedStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifThrowStmt(Consumer<ThrowStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTryStmt(Consumer<TryStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnparsableStmt(Consumer<UnparsableStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifWhileStmt(Consumer<WhileStmt> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<AssertStmt> toAssertStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BlockStmt> toBlockStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<BreakStmt> toBreakStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ContinueStmt> toContinueStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<DoStmt> toDoStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<EmptyStmt> toEmptyStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ExplicitConstructorInvocationStmt> toExplicitConstructorInvocationStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ExpressionStmt> toExpressionStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ForStmt> toForStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ForeachStmt> toForeachStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<IfStmt> toIfStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LabeledStmt> toLabeledStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<LocalClassDeclarationStmt> toLocalClassDeclarationStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ReturnStmt> toReturnStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SwitchEntryStmt> toSwitchEntryStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SwitchStmt> toSwitchStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SynchronizedStmt> toSynchronizedStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ThrowStmt> toThrowStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TryStmt> toTryStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnparsableStmt> toUnparsableStmt() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<WhileStmt> toWhileStmt() {
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SwitchEntryStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SwitchEntryStmt.java
new file mode 100644
index 0000000..afa8fce
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SwitchEntryStmt.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.metamodel.SwitchEntryStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+
+/**
+ * One case in a switch statement.
+ * <br/><pre>
+ * switch (i) {
+ * case 1:
+ * case 2:
+ * System.out.println(444);
+ * break;
+ * default:
+ * System.out.println(0);
+ * }
+ * </pre>
+ * This contains three SwitchEntryStmts.
+ * <br/>The first one has label 1 and no statements.
+ * <br/>The second has label 2 and two statements (the println and the break).
+ * <br/>The third, the default, has no label and one statement.
+ *
+ * @author Julio Vilmar Gesser
+ * @see SwitchStmt
+ */
+public final class SwitchEntryStmt extends Statement implements NodeWithStatements<SwitchEntryStmt> {
+
+    @OptionalProperty
+    private Expression label;
+
+    private NodeList<Statement> statements;
+
+    public SwitchEntryStmt() {
+        this(null, null, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public SwitchEntryStmt(final Expression label, final NodeList<Statement> statements) {
+        this(null, label, statements);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public SwitchEntryStmt(TokenRange tokenRange, Expression label, NodeList<Statement> statements) {
+        super(tokenRange);
+        setLabel(label);
+        setStatements(statements);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<Expression> getLabel() {
+        return Optional.ofNullable(label);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Statement> getStatements() {
+        return statements;
+    }
+
+    /**
+     * Sets the label
+     *
+     * @param label the label, can be null
+     * @return this, the SwitchEntryStmt
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SwitchEntryStmt setLabel(final Expression label) {
+        if (label == this.label) {
+            return (SwitchEntryStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.LABEL, this.label, label);
+        if (this.label != null)
+            this.label.setParentNode(null);
+        this.label = label;
+        setAsParentNodeOf(label);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SwitchEntryStmt setStatements(final NodeList<Statement> statements) {
+        assertNotNull(statements);
+        if (statements == this.statements) {
+            return (SwitchEntryStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.STATEMENTS, this.statements, statements);
+        if (this.statements != null)
+            this.statements.setParentNode(null);
+        this.statements = statements;
+        setAsParentNodeOf(statements);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (label != null) {
+            if (node == label) {
+                removeLabel();
+                return true;
+            }
+        }
+        for (int i = 0; i < statements.size(); i++) {
+            if (statements.get(i) == node) {
+                statements.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public SwitchEntryStmt removeLabel() {
+        return setLabel((Expression) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public SwitchEntryStmt clone() {
+        return (SwitchEntryStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public SwitchEntryStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.switchEntryStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (label != null) {
+            if (node == label) {
+                setLabel((Expression) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < statements.size(); i++) {
+            if (statements.get(i) == node) {
+                statements.set(i, (Statement) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSwitchEntryStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SwitchEntryStmt asSwitchEntryStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSwitchEntryStmt(Consumer<SwitchEntryStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SwitchEntryStmt> toSwitchEntryStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SwitchStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SwitchStmt.java
new file mode 100644
index 0000000..36e88b2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SwitchStmt.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.SwitchStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A switch statement.
+ * <br/>In <code>switch(a) { ... }</code> the selector is "a",
+ * and the contents of the { ... } are the entries.
+ *
+ * @author Julio Vilmar Gesser
+ * @see SwitchEntryStmt
+ */
+public final class SwitchStmt extends Statement {
+
+    private Expression selector;
+
+    private NodeList<SwitchEntryStmt> entries;
+
+    public SwitchStmt() {
+        this(null, new NameExpr(), new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public SwitchStmt(final Expression selector, final NodeList<SwitchEntryStmt> entries) {
+        this(null, selector, entries);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public SwitchStmt(TokenRange tokenRange, Expression selector, NodeList<SwitchEntryStmt> entries) {
+        super(tokenRange);
+        setSelector(selector);
+        setEntries(entries);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<SwitchEntryStmt> getEntries() {
+        return entries;
+    }
+
+    public SwitchEntryStmt getEntry(int i) {
+        return getEntries().get(i);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getSelector() {
+        return selector;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SwitchStmt setEntries(final NodeList<SwitchEntryStmt> entries) {
+        assertNotNull(entries);
+        if (entries == this.entries) {
+            return (SwitchStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.ENTRIES, this.entries, entries);
+        if (this.entries != null)
+            this.entries.setParentNode(null);
+        this.entries = entries;
+        setAsParentNodeOf(entries);
+        return this;
+    }
+
+    /**
+     * @deprecated use a method on getEntries instead
+     */
+    @Deprecated
+    public SwitchStmt setEntry(int i, SwitchEntryStmt entry) {
+        getEntries().set(i, entry);
+        return this;
+    }
+
+    /**
+     * @deprecated use a method on getEntries instead
+     */
+    @Deprecated
+    public SwitchStmt addEntry(SwitchEntryStmt entry) {
+        getEntries().add(entry);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SwitchStmt setSelector(final Expression selector) {
+        assertNotNull(selector);
+        if (selector == this.selector) {
+            return (SwitchStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.SELECTOR, this.selector, selector);
+        if (this.selector != null)
+            this.selector.setParentNode(null);
+        this.selector = selector;
+        setAsParentNodeOf(selector);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < entries.size(); i++) {
+            if (entries.get(i) == node) {
+                entries.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public SwitchStmt clone() {
+        return (SwitchStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public SwitchStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.switchStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < entries.size(); i++) {
+            if (entries.get(i) == node) {
+                entries.set(i, (SwitchEntryStmt) replacementNode);
+                return true;
+            }
+        }
+        if (node == selector) {
+            setSelector((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSwitchStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SwitchStmt asSwitchStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSwitchStmt(Consumer<SwitchStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SwitchStmt> toSwitchStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SynchronizedStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SynchronizedStmt.java
new file mode 100644
index 0000000..376d525
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/SynchronizedStmt.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt;
+import com.github.javaparser.ast.nodeTypes.NodeWithExpression;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.SynchronizedStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Usage of the synchronized keyword.
+ * <br/>In <code>synchronized (a123) { ... }</code> the expression is a123 and { ... } is the body
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class SynchronizedStmt extends Statement implements NodeWithBlockStmt<SynchronizedStmt>, NodeWithExpression<SynchronizedStmt> {
+
+    private Expression expression;
+
+    private BlockStmt body;
+
+    public SynchronizedStmt() {
+        this(null, new NameExpr(), new BlockStmt());
+    }
+
+    @AllFieldsConstructor
+    public SynchronizedStmt(final Expression expression, final BlockStmt body) {
+        this(null, expression, body);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public SynchronizedStmt(TokenRange tokenRange, Expression expression, BlockStmt body) {
+        super(tokenRange);
+        setExpression(expression);
+        setBody(body);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getExpression() {
+        return expression;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SynchronizedStmt setExpression(final Expression expression) {
+        assertNotNull(expression);
+        if (expression == this.expression) {
+            return (SynchronizedStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BlockStmt getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SynchronizedStmt setBody(final BlockStmt body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (SynchronizedStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public SynchronizedStmt clone() {
+        return (SynchronizedStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public SynchronizedStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.synchronizedStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((BlockStmt) replacementNode);
+            return true;
+        }
+        if (node == expression) {
+            setExpression((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isSynchronizedStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public SynchronizedStmt asSynchronizedStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifSynchronizedStmt(Consumer<SynchronizedStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<SynchronizedStmt> toSynchronizedStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ThrowStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ThrowStmt.java
new file mode 100644
index 0000000..736b835
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/ThrowStmt.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithExpression;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.ThrowStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Usage of the throw statement.
+ * <br/><code>throw new Exception()</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ThrowStmt extends Statement implements NodeWithExpression<ThrowStmt> {
+
+    private Expression expression;
+
+    public ThrowStmt() {
+        this(null, new NameExpr());
+    }
+
+    @AllFieldsConstructor
+    public ThrowStmt(final Expression expression) {
+        this(null, expression);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ThrowStmt(TokenRange tokenRange, Expression expression) {
+        super(tokenRange);
+        setExpression(expression);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getExpression() {
+        return expression;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ThrowStmt setExpression(final Expression expression) {
+        assertNotNull(expression);
+        if (expression == this.expression) {
+            return (ThrowStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXPRESSION, this.expression, expression);
+        if (this.expression != null)
+            this.expression.setParentNode(null);
+        this.expression = expression;
+        setAsParentNodeOf(expression);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ThrowStmt clone() {
+        return (ThrowStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ThrowStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.throwStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == expression) {
+            setExpression((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isThrowStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ThrowStmt asThrowStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifThrowStmt(Consumer<ThrowStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ThrowStmt> toThrowStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/TryStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/TryStmt.java
new file mode 100644
index 0000000..6e4a81a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/TryStmt.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.metamodel.TryStmtMetaModel;
+import javax.annotation.Generated;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import java.util.function.Consumer;
+
+/**
+ * <h1>The try statement</h1>
+ * <h2>Java 1.0-6</h2>
+ * <pre>
+ * try {
+ * // ...
+ * } catch (IOException e) {
+ * // ...
+ * } finally {
+ * // ...
+ * }
+ * </pre>
+ * In this code, "// do things" is the content of the tryBlock, there is one catch clause that catches IOException e,
+ * and there is a finally block.
+ * <p>
+ * The catch and finally blocks are optional, but they should not be empty at the same time.
+ * <h2>Java 7-8</h2>
+ * <pre>
+ * try (InputStream i = new FileInputStream("file")) {
+ * // ...
+ * } catch (IOException|NullPointerException e) {
+ * // ...
+ * } finally {
+ * // ...
+ * }
+ * </pre>
+ * Java 7 introduced two things:
+ * <ul>
+ * <li>Resources can be specified after "try", but only variable declarations (VariableDeclarationExpr.)</li>
+ * <li>A single catch can catch multiple exception types. This uses the IntersectionType.</li>
+ * </ul>
+ * <h2>Java 9+</h2>
+ * <pre>
+ * try (r) {
+ * // ...
+ * } catch (IOException|NullPointerException e) {
+ * // ...
+ * } finally {
+ * // ...
+ * }
+ * </pre>
+ * Java 9 finishes resources: you can now refer to a resource that was declared somewhere else.
+ * The following types are allowed:
+ * <ul>
+ * <li>VariableDeclarationExpr: "X x = new X()" like in Java 7-8.</li>
+ * <li>NameExpr: "a".</li>
+ * <li>FieldAccessExpr: "x.y.z", "super.test" etc.</li>
+ * </ul>
+ *
+ * @author Julio Vilmar Gesser
+ * @see CatchClause
+ * @see com.github.javaparser.ast.type.IntersectionType
+ * @see com.github.javaparser.ast.expr.FieldAccessExpr
+ * @see com.github.javaparser.ast.expr.NameExpr
+ */
+public final class TryStmt extends Statement {
+
+    private NodeList<Expression> resources;
+
+    private BlockStmt tryBlock;
+
+    private NodeList<CatchClause> catchClauses;
+
+    @OptionalProperty
+    private BlockStmt finallyBlock;
+
+    public TryStmt() {
+        this(null, new NodeList<>(), new BlockStmt(), new NodeList<>(), null);
+    }
+
+    public TryStmt(final BlockStmt tryBlock, final NodeList<CatchClause> catchClauses, final BlockStmt finallyBlock) {
+        this(null, new NodeList<>(), tryBlock, catchClauses, finallyBlock);
+    }
+
+    @AllFieldsConstructor
+    public TryStmt(NodeList<Expression> resources, final BlockStmt tryBlock, final NodeList<CatchClause> catchClauses, final BlockStmt finallyBlock) {
+        this(null, resources, tryBlock, catchClauses, finallyBlock);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public TryStmt(TokenRange tokenRange, NodeList<Expression> resources, BlockStmt tryBlock, NodeList<CatchClause> catchClauses, BlockStmt finallyBlock) {
+        super(tokenRange);
+        setResources(resources);
+        setTryBlock(tryBlock);
+        setCatchClauses(catchClauses);
+        setFinallyBlock(finallyBlock);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<CatchClause> getCatchClauses() {
+        return catchClauses;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<BlockStmt> getFinallyBlock() {
+        return Optional.ofNullable(finallyBlock);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public BlockStmt getTryBlock() {
+        return tryBlock;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<Expression> getResources() {
+        return resources;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public TryStmt setCatchClauses(final NodeList<CatchClause> catchClauses) {
+        assertNotNull(catchClauses);
+        if (catchClauses == this.catchClauses) {
+            return (TryStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.CATCH_CLAUSES, this.catchClauses, catchClauses);
+        if (this.catchClauses != null)
+            this.catchClauses.setParentNode(null);
+        this.catchClauses = catchClauses;
+        setAsParentNodeOf(catchClauses);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public TryStmt setFinallyBlock(final BlockStmt finallyBlock) {
+        if (finallyBlock == this.finallyBlock) {
+            return (TryStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.FINALLY_BLOCK, this.finallyBlock, finallyBlock);
+        if (this.finallyBlock != null)
+            this.finallyBlock.setParentNode(null);
+        this.finallyBlock = finallyBlock;
+        setAsParentNodeOf(finallyBlock);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public TryStmt setTryBlock(final BlockStmt tryBlock) {
+        assertNotNull(tryBlock);
+        if (tryBlock == this.tryBlock) {
+            return (TryStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.TRY_BLOCK, this.tryBlock, tryBlock);
+        if (this.tryBlock != null)
+            this.tryBlock.setParentNode(null);
+        this.tryBlock = tryBlock;
+        setAsParentNodeOf(tryBlock);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public TryStmt setResources(final NodeList<Expression> resources) {
+        assertNotNull(resources);
+        if (resources == this.resources) {
+            return (TryStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.RESOURCES, this.resources, resources);
+        if (this.resources != null)
+            this.resources.setParentNode(null);
+        this.resources = resources;
+        setAsParentNodeOf(resources);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < catchClauses.size(); i++) {
+            if (catchClauses.get(i) == node) {
+                catchClauses.remove(i);
+                return true;
+            }
+        }
+        if (finallyBlock != null) {
+            if (node == finallyBlock) {
+                removeFinallyBlock();
+                return true;
+            }
+        }
+        for (int i = 0; i < resources.size(); i++) {
+            if (resources.get(i) == node) {
+                resources.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public TryStmt removeFinallyBlock() {
+        return setFinallyBlock((BlockStmt) null);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public TryStmt removeTryBlock() {
+        return setTryBlock((BlockStmt) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public TryStmt clone() {
+        return (TryStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public TryStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.tryStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < catchClauses.size(); i++) {
+            if (catchClauses.get(i) == node) {
+                catchClauses.set(i, (CatchClause) replacementNode);
+                return true;
+            }
+        }
+        if (finallyBlock != null) {
+            if (node == finallyBlock) {
+                setFinallyBlock((BlockStmt) replacementNode);
+                return true;
+            }
+        }
+        for (int i = 0; i < resources.size(); i++) {
+            if (resources.get(i) == node) {
+                resources.set(i, (Expression) replacementNode);
+                return true;
+            }
+        }
+        if (node == tryBlock) {
+            setTryBlock((BlockStmt) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTryStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TryStmt asTryStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTryStmt(Consumer<TryStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TryStmt> toTryStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/UnparsableStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/UnparsableStmt.java
new file mode 100644
index 0000000..2a7fc01
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/UnparsableStmt.java
@@ -0,0 +1,103 @@
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.Node;
+import javax.annotation.Generated;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.UnparsableStmtMetaModel;
+import static com.github.javaparser.ast.Node.Parsedness.*;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A statement that had parse errors.
+ * Nothing is known about it except the tokens it covers.
+ */
+public final class UnparsableStmt extends Statement {
+
+    @AllFieldsConstructor
+    public UnparsableStmt() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public UnparsableStmt(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public UnparsableStmt clone() {
+        return (UnparsableStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public UnparsableStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.unparsableStmtMetaModel;
+    }
+
+    @Override
+    public Parsedness getParsed() {
+        return UNPARSABLE;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnparsableStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnparsableStmt asUnparsableStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnparsableStmt(Consumer<UnparsableStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnparsableStmt> toUnparsableStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/WhileStmt.java b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/WhileStmt.java
new file mode 100644
index 0000000..5fb1f99
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/stmt/WhileStmt.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.nodeTypes.NodeWithCondition;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.WhileStmtMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A while statement.
+ * <br/><code>while(true) { ... }</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class WhileStmt extends Statement implements NodeWithBody<WhileStmt>, NodeWithCondition<WhileStmt> {
+
+    private Expression condition;
+
+    private Statement body;
+
+    public WhileStmt() {
+        this(null, new BooleanLiteralExpr(), new ReturnStmt());
+    }
+
+    @AllFieldsConstructor
+    public WhileStmt(final Expression condition, final Statement body) {
+        this(null, condition, body);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public WhileStmt(TokenRange tokenRange, Expression condition, Statement body) {
+        super(tokenRange);
+        setCondition(condition);
+        setBody(body);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Statement getBody() {
+        return body;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Expression getCondition() {
+        return condition;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public WhileStmt setBody(final Statement body) {
+        assertNotNull(body);
+        if (body == this.body) {
+            return (WhileStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.BODY, this.body, body);
+        if (this.body != null)
+            this.body.setParentNode(null);
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public WhileStmt setCondition(final Expression condition) {
+        assertNotNull(condition);
+        if (condition == this.condition) {
+            return (WhileStmt) this;
+        }
+        notifyPropertyChange(ObservableProperty.CONDITION, this.condition, condition);
+        if (this.condition != null)
+            this.condition.setParentNode(null);
+        this.condition = condition;
+        setAsParentNodeOf(condition);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public WhileStmt clone() {
+        return (WhileStmt) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public WhileStmtMetaModel getMetaModel() {
+        return JavaParserMetaModel.whileStmtMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == body) {
+            setBody((Statement) replacementNode);
+            return true;
+        }
+        if (node == condition) {
+            setCondition((Expression) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isWhileStmt() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public WhileStmt asWhileStmt() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifWhileStmt(Consumer<WhileStmt> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<WhileStmt> toWhileStmt() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java
new file mode 100644
index 0000000..76dba1f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ArrayType.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.ArrayTypeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.utils.Pair;
+import javax.annotation.Generated;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.ast.NodeList.nodeList;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import java.util.function.Consumer;
+
+/**
+ * To indicate that a type is an array, it gets wrapped in an ArrayType for every array level it has.
+ * So, int[][] becomes ArrayType(ArrayType(int)).
+ */
+public final class ArrayType extends ReferenceType implements NodeWithAnnotations<ArrayType> {
+
+    @Override
+    public ResolvedArrayType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedArrayType.class);
+    }
+
+    /**
+     * The origin of a pair of array brackets [].
+     */
+    public enum Origin {
+
+        /**
+         * The [] were found on the name, like "int a[]" or "String abc()[][]"
+         */
+        NAME,
+        /**
+         * The [] were found on the type, like "int[] a" or "String[][] abc()"
+         */
+        TYPE
+    }
+
+    private Type componentType;
+
+    private Origin origin;
+
+    @AllFieldsConstructor
+    public ArrayType(Type componentType, Origin origin, NodeList<AnnotationExpr> annotations) {
+        this(null, componentType, origin, annotations);
+    }
+
+    public ArrayType(Type type, AnnotationExpr... annotations) {
+        this(type, Origin.TYPE, nodeList(annotations));
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ArrayType(TokenRange tokenRange, Type componentType, Origin origin, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange, annotations);
+        setComponentType(componentType);
+        setOrigin(origin);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type getComponentType() {
+        return componentType;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayType setComponentType(final Type componentType) {
+        assertNotNull(componentType);
+        if (componentType == this.componentType) {
+            return (ArrayType) this;
+        }
+        notifyPropertyChange(ObservableProperty.COMPONENT_TYPE, this.componentType, componentType);
+        if (this.componentType != null)
+            this.componentType.setParentNode(null);
+        this.componentType = componentType;
+        setAsParentNodeOf(componentType);
+        return this;
+    }
+
+    /**
+     * Takes lists of arrayBracketPairs, assumes the lists are ordered left to right and the pairs are ordered left to
+     * right, mirroring the actual code. The type gets wrapped in ArrayTypes so that the outermost ArrayType corresponds
+     * to the rightmost ArrayBracketPair.
+     */
+    @SafeVarargs
+    public static Type wrapInArrayTypes(Type type, List<ArrayBracketPair>... arrayBracketPairLists) {
+        for (int i = arrayBracketPairLists.length - 1; i >= 0; i--) {
+            final List<ArrayBracketPair> arrayBracketPairList = arrayBracketPairLists[i];
+            if (arrayBracketPairList != null) {
+                for (int j = arrayBracketPairList.size() - 1; j >= 0; j--) {
+                    ArrayBracketPair pair = arrayBracketPairList.get(j);
+                    TokenRange tokenRange = null;
+                    if (type.getTokenRange().isPresent() && pair.getTokenRange().isPresent()) {
+                        tokenRange = new TokenRange(type.getTokenRange().get().getBegin(), pair.getTokenRange().get().getEnd());
+                    }
+                    type = new ArrayType(tokenRange, type, pair.getOrigin(), pair.getAnnotations());
+                    if (tokenRange != null) {
+                        type.setRange(tokenRange.toRange().get());
+                    }
+                }
+            }
+        }
+        return type;
+    }
+
+    /**
+     * Takes a type that may be an ArrayType. Unwraps ArrayTypes until the element type is found.
+     *
+     * @return a pair of the element type, and the unwrapped ArrayTypes, if any.
+     */
+    public static Pair<Type, List<ArrayBracketPair>> unwrapArrayTypes(Type type) {
+        final List<ArrayBracketPair> arrayBracketPairs = new ArrayList<>(0);
+        while (type instanceof ArrayType) {
+            ArrayType arrayType = (ArrayType) type;
+            arrayBracketPairs.add(new ArrayBracketPair(type.getTokenRange().orElse(null), arrayType.getOrigin(), arrayType.getAnnotations()));
+            type = arrayType.getComponentType();
+        }
+        return new Pair<>(type, arrayBracketPairs);
+    }
+
+    /**
+     * Helper class that stores information about a pair of brackets in a non-recursive way
+     * (unlike ArrayType.)
+     */
+    public static class ArrayBracketPair {
+
+        private TokenRange tokenRange;
+
+        private NodeList<AnnotationExpr> annotations = new NodeList<>();
+
+        private Origin origin;
+
+        public ArrayBracketPair(TokenRange tokenRange, Origin origin, NodeList<AnnotationExpr> annotations) {
+            setTokenRange(tokenRange);
+            setAnnotations(annotations);
+            setOrigin(origin);
+        }
+
+        public NodeList<AnnotationExpr> getAnnotations() {
+            return annotations;
+        }
+
+        public ArrayBracketPair setAnnotations(NodeList<AnnotationExpr> annotations) {
+            this.annotations = assertNotNull(annotations);
+            return this;
+        }
+
+        public ArrayBracketPair setTokenRange(TokenRange range) {
+            this.tokenRange = range;
+            return this;
+        }
+
+        public Optional<TokenRange> getTokenRange() {
+            return Optional.ofNullable(tokenRange);
+        }
+
+        public Origin getOrigin() {
+            return origin;
+        }
+
+        public ArrayBracketPair setOrigin(Origin origin) {
+            this.origin = assertNotNull(origin);
+            return this;
+        }
+    }
+
+    @Override
+    public ArrayType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (ArrayType) super.setAnnotations(annotations);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Origin getOrigin() {
+        return origin;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ArrayType setOrigin(final Origin origin) {
+        assertNotNull(origin);
+        if (origin == this.origin) {
+            return (ArrayType) this;
+        }
+        notifyPropertyChange(ObservableProperty.ORIGIN, this.origin, origin);
+        this.origin = origin;
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        return componentType.asString() + "[]";
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ArrayType clone() {
+        return (ArrayType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ArrayTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.arrayTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == componentType) {
+            setComponentType((Type) replacementNode);
+            return true;
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayType asArrayType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayType(Consumer<ArrayType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayType> toArrayType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java
new file mode 100644
index 0000000..f3b6846
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ClassOrInterfaceType.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.ClassOrInterfaceTypeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.joining;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import java.util.function.Consumer;
+
+/**
+ * A class or an interface type. <br/><code>Object</code> <br/><code>HashMap&lt;String, String></code>
+ * <br/><code>java.util.Punchcard</code>
+ * <p>
+ * <p>Note that the syntax is ambiguous here, and JavaParser does not know what is to the left of the class. It assumes
+ * cases like <code>Map.Entry</code> where Map is the scope of Entry. In <code>java.util.Punchcard</code>, it will not
+ * recognize that java and util are parts of the package name. Instead, it will set util as the scope of Punchcard, as a
+ * ClassOrInterfaceType (which it is not.) In turn, util will have java as its scope, also as a
+ * ClassOrInterfaceType</p>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassOrInterfaceType extends ReferenceType implements NodeWithSimpleName<ClassOrInterfaceType>, NodeWithAnnotations<ClassOrInterfaceType>, NodeWithTypeArguments<ClassOrInterfaceType> {
+
+    @OptionalProperty
+    private ClassOrInterfaceType scope;
+
+    private SimpleName name;
+
+    @OptionalProperty
+    private NodeList<Type> typeArguments;
+
+    public ClassOrInterfaceType() {
+        this(null, null, new SimpleName(), null, new NodeList<>());
+    }
+
+    /**
+     * @deprecated use JavaParser.parseClassOrInterfaceType instead. This constructor does not understand generics.
+     */
+    public ClassOrInterfaceType(final String name) {
+        this(null, null, new SimpleName(name), null, new NodeList<>());
+    }
+
+    public ClassOrInterfaceType(final ClassOrInterfaceType scope, final String name) {
+        this(null, scope, new SimpleName(name), null, new NodeList<>());
+    }
+
+    public ClassOrInterfaceType(final ClassOrInterfaceType scope, final SimpleName name, final NodeList<Type> typeArguments) {
+        this(null, scope, name, typeArguments, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ClassOrInterfaceType(final ClassOrInterfaceType scope, final SimpleName name, final NodeList<Type> typeArguments, final NodeList<AnnotationExpr> annotations) {
+        this(null, scope, name, typeArguments, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ClassOrInterfaceType(TokenRange tokenRange, ClassOrInterfaceType scope, SimpleName name, NodeList<Type> typeArguments, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange, annotations);
+        setScope(scope);
+        setName(name);
+        setTypeArguments(typeArguments);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<ClassOrInterfaceType> getScope() {
+        return Optional.ofNullable(scope);
+    }
+
+    public boolean isBoxedType() {
+        return PrimitiveType.unboxMap.containsKey(name.getIdentifier());
+    }
+
+    public PrimitiveType toUnboxedType() throws UnsupportedOperationException {
+        if (!isBoxedType()) {
+            throw new UnsupportedOperationException(name + " isn't a boxed type.");
+        }
+        return new PrimitiveType(PrimitiveType.unboxMap.get(name.getIdentifier()));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceType setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (ClassOrInterfaceType) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    /**
+     * Sets the scope
+     *
+     * @param scope the scope, can be null
+     * @return this, the ClassOrInterfaceType
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceType setScope(final ClassOrInterfaceType scope) {
+        if (scope == this.scope) {
+            return (ClassOrInterfaceType) this;
+        }
+        notifyPropertyChange(ObservableProperty.SCOPE, this.scope, scope);
+        if (this.scope != null)
+            this.scope.setParentNode(null);
+        this.scope = scope;
+        setAsParentNodeOf(scope);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<NodeList<Type>> getTypeArguments() {
+        return Optional.ofNullable(typeArguments);
+    }
+
+    /**
+     * Sets the typeArguments
+     *
+     * @param typeArguments the typeArguments, can be null
+     * @return this, the ClassOrInterfaceType
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public ClassOrInterfaceType setTypeArguments(final NodeList<Type> typeArguments) {
+        if (typeArguments == this.typeArguments) {
+            return (ClassOrInterfaceType) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_ARGUMENTS, this.typeArguments, typeArguments);
+        if (this.typeArguments != null)
+            this.typeArguments.setParentNode(null);
+        this.typeArguments = typeArguments;
+        setAsParentNodeOf(typeArguments);
+        return this;
+    }
+
+    @Override
+    public ClassOrInterfaceType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (ClassOrInterfaceType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (scope != null) {
+            if (node == scope) {
+                removeScope();
+                return true;
+            }
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.remove(i);
+                    return true;
+                }
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        StringBuilder str = new StringBuilder();
+        getScope().ifPresent(s -> str.append(s.asString()).append("."));
+        str.append(name.asString());
+        getTypeArguments().ifPresent(ta -> str.append(ta.stream().map(Type::asString).collect(joining(",", "<", ">"))));
+        return str.toString();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public ClassOrInterfaceType removeScope() {
+        return setScope((ClassOrInterfaceType) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ClassOrInterfaceType clone() {
+        return (ClassOrInterfaceType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ClassOrInterfaceTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.classOrInterfaceTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        if (scope != null) {
+            if (node == scope) {
+                setScope((ClassOrInterfaceType) replacementNode);
+                return true;
+            }
+        }
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                if (typeArguments.get(i) == node) {
+                    typeArguments.set(i, (Type) replacementNode);
+                    return true;
+                }
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isClassOrInterfaceType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ClassOrInterfaceType asClassOrInterfaceType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifClassOrInterfaceType(Consumer<ClassOrInterfaceType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedReferenceType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedReferenceType.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ClassOrInterfaceType> toClassOrInterfaceType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java
new file mode 100644
index 0000000..6b1056b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/IntersectionType.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.IntersectionTypeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.joining;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedIntersectionType;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Represents a set of types. A given value of this type has to be assignable to at all of the element types.
+ * As of Java 8 it is used in casts or while expressing bounds for generic types.
+ * <p>
+ * For example:
+ * <code>public class A&lt;T extends Serializable &amp; Cloneable&gt; { }</code>
+ * <p>
+ * Or:
+ * <code>void foo((Serializable &amp; Cloneable)myObject);</code>
+ *
+ * @since 3.0.0
+ */
+public final class IntersectionType extends Type implements NodeWithAnnotations<IntersectionType> {
+
+    @NonEmptyProperty
+    private NodeList<ReferenceType> elements;
+
+    @AllFieldsConstructor
+    public IntersectionType(NodeList<ReferenceType> elements) {
+        this(null, elements);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public IntersectionType(TokenRange tokenRange, NodeList<ReferenceType> elements) {
+        super(tokenRange);
+        setElements(elements);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ReferenceType> getElements() {
+        return elements;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public IntersectionType setElements(final NodeList<ReferenceType> elements) {
+        assertNotNull(elements);
+        if (elements == this.elements) {
+            return (IntersectionType) this;
+        }
+        notifyPropertyChange(ObservableProperty.ELEMENTS, this.elements, elements);
+        if (this.elements != null)
+            this.elements.setParentNode(null);
+        this.elements = elements;
+        setAsParentNodeOf(elements);
+        return this;
+    }
+
+    @Override
+    public IntersectionType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (IntersectionType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < elements.size(); i++) {
+            if (elements.get(i) == node) {
+                elements.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        return elements.stream().map(Type::asString).collect(joining("&"));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public IntersectionType clone() {
+        return (IntersectionType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public IntersectionTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.intersectionTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < elements.size(); i++) {
+            if (elements.get(i) == node) {
+                elements.set(i, (ReferenceType) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isIntersectionType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public IntersectionType asIntersectionType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifIntersectionType(Consumer<IntersectionType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedIntersectionType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedIntersectionType.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<IntersectionType> toIntersectionType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java
new file mode 100644
index 0000000..e359b7f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/PrimitiveType.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.PrimitiveTypeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A primitive type.
+ * <br/><code>int</code>
+ * <br/><code>boolean</code>
+ * <br/><code>short</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class PrimitiveType extends Type implements NodeWithAnnotations<PrimitiveType> {
+
+    public static PrimitiveType booleanType() {
+        return new PrimitiveType(Primitive.BOOLEAN);
+    }
+
+    public static PrimitiveType charType() {
+        return new PrimitiveType(Primitive.CHAR);
+    }
+
+    public static PrimitiveType byteType() {
+        return new PrimitiveType(Primitive.BYTE);
+    }
+
+    public static PrimitiveType shortType() {
+        return new PrimitiveType(Primitive.SHORT);
+    }
+
+    public static PrimitiveType intType() {
+        return new PrimitiveType(Primitive.INT);
+    }
+
+    public static PrimitiveType longType() {
+        return new PrimitiveType(Primitive.LONG);
+    }
+
+    public static PrimitiveType floatType() {
+        return new PrimitiveType(Primitive.FLOAT);
+    }
+
+    public static PrimitiveType doubleType() {
+        return new PrimitiveType(Primitive.DOUBLE);
+    }
+
+    public enum Primitive {
+
+        BOOLEAN("Boolean"),
+        CHAR("Character"),
+        BYTE("Byte"),
+        SHORT("Short"),
+        INT("Integer"),
+        LONG("Long"),
+        FLOAT("Float"),
+        DOUBLE("Double");
+
+        final String nameOfBoxedType;
+
+        private String codeRepresentation;
+
+        public ClassOrInterfaceType toBoxedType() {
+            return parseClassOrInterfaceType(nameOfBoxedType);
+        }
+
+        public String asString() {
+            return codeRepresentation;
+        }
+
+        Primitive(String nameOfBoxedType) {
+            this.nameOfBoxedType = nameOfBoxedType;
+            this.codeRepresentation = name().toLowerCase();
+        }
+    }
+
+    static final HashMap<String, Primitive> unboxMap = new HashMap<>();
+
+    static {
+        for (Primitive unboxedType : Primitive.values()) {
+            unboxMap.put(unboxedType.nameOfBoxedType, unboxedType);
+        }
+    }
+
+    private Primitive type;
+
+    public PrimitiveType() {
+        this(null, Primitive.INT, new NodeList<>());
+    }
+
+    public PrimitiveType(final Primitive type) {
+        this(null, type, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public PrimitiveType(final Primitive type, NodeList<AnnotationExpr> annotations) {
+        this(null, type, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public PrimitiveType(TokenRange tokenRange, Primitive type, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange, annotations);
+        setType(type);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Primitive getType() {
+        return type;
+    }
+
+    public ClassOrInterfaceType toBoxedType() {
+        return type.toBoxedType();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public PrimitiveType setType(final Primitive type) {
+        assertNotNull(type);
+        if (type == this.type) {
+            return (PrimitiveType) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE, this.type, type);
+        this.type = type;
+        return this;
+    }
+
+    @Override
+    public String asString() {
+        return type.asString();
+    }
+
+    @Override
+    public PrimitiveType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (PrimitiveType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public PrimitiveType clone() {
+        return (PrimitiveType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public PrimitiveTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.primitiveTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isPrimitiveType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public PrimitiveType asPrimitiveType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifPrimitiveType(Consumer<PrimitiveType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedPrimitiveType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedPrimitiveType.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<PrimitiveType> toPrimitiveType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java
new file mode 100644
index 0000000..f39ee0e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/ReferenceType.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.ReferenceTypeMetaModel;
+import javax.annotation.Generated;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * Base class for reference types.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class ReferenceType extends Type {
+
+    public ReferenceType() {
+        this(null, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public ReferenceType(NodeList<AnnotationExpr> annotations) {
+        this(null, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public ReferenceType(TokenRange tokenRange, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange, annotations);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public ReferenceType clone() {
+        return (ReferenceType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public ReferenceTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.referenceTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isReferenceType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ReferenceType asReferenceType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifReferenceType(Consumer<ReferenceType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ReferenceType> toReferenceType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java
new file mode 100644
index 0000000..acaf5a9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/Type.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.DataKey;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.TypeMetaModel;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.Resolvable;
+import com.github.javaparser.resolution.SymbolResolver;
+import com.github.javaparser.resolution.types.ResolvedType;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import java.util.Optional;
+
+/**
+ * Base class for types.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Type extends Node implements Resolvable<Object> {
+
+    private NodeList<AnnotationExpr> annotations;
+
+    /**
+     * Several sub classes do not support annotations.
+     * This is a support constructor for them.
+     */
+    protected Type(TokenRange range) {
+        this(range, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public Type(NodeList<AnnotationExpr> annotations) {
+        this(null, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public Type(TokenRange tokenRange, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange);
+        setAnnotations(annotations);
+        customInitialization();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    public AnnotationExpr getAnnotation(int i) {
+        return getAnnotations().get(i);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Type setAnnotations(final NodeList<AnnotationExpr> annotations) {
+        assertNotNull(annotations);
+        if (annotations == this.annotations) {
+            return (Type) this;
+        }
+        notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations);
+        if (this.annotations != null)
+            this.annotations.setParentNode(null);
+        this.annotations = annotations;
+        setAsParentNodeOf(annotations);
+        return this;
+    }
+
+    /**
+     * Finds the element type, meaning: the type without ArrayTypes around it.
+     * <p>
+     * In "<code>int[] a[];</code>", the element type is int.
+     */
+    public Type getElementType() {
+        if (this instanceof ArrayType) {
+            return ((ArrayType) this).getComponentType().getElementType();
+        }
+        return this;
+    }
+
+    public int getArrayLevel() {
+        if (this instanceof ArrayType) {
+            return 1 + ((ArrayType) this).getComponentType().getArrayLevel();
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    public abstract String asString();
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public Type clone() {
+        return (Type) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public TypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.typeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < annotations.size(); i++) {
+            if (annotations.get(i) == node) {
+                annotations.set(i, (AnnotationExpr) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isArrayType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ArrayType asArrayType() {
+        throw new IllegalStateException(f("%s is not an ArrayType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isClassOrInterfaceType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ClassOrInterfaceType asClassOrInterfaceType() {
+        throw new IllegalStateException(f("%s is not an ClassOrInterfaceType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isIntersectionType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public IntersectionType asIntersectionType() {
+        throw new IllegalStateException(f("%s is not an IntersectionType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isPrimitiveType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public PrimitiveType asPrimitiveType() {
+        throw new IllegalStateException(f("%s is not an PrimitiveType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isReferenceType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public ReferenceType asReferenceType() {
+        throw new IllegalStateException(f("%s is not an ReferenceType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTypeParameter() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TypeParameter asTypeParameter() {
+        throw new IllegalStateException(f("%s is not an TypeParameter", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnionType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnionType asUnionType() {
+        throw new IllegalStateException(f("%s is not an UnionType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnknownType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnknownType asUnknownType() {
+        throw new IllegalStateException(f("%s is not an UnknownType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isVoidType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public VoidType asVoidType() {
+        throw new IllegalStateException(f("%s is not an VoidType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isWildcardType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public WildcardType asWildcardType() {
+        throw new IllegalStateException(f("%s is not an WildcardType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifArrayType(Consumer<ArrayType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifClassOrInterfaceType(Consumer<ClassOrInterfaceType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifIntersectionType(Consumer<IntersectionType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifPrimitiveType(Consumer<PrimitiveType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifReferenceType(Consumer<ReferenceType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTypeParameter(Consumer<TypeParameter> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnionType(Consumer<UnionType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnknownType(Consumer<UnknownType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifVoidType(Consumer<VoidType> action) {
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifWildcardType(Consumer<WildcardType> action) {
+    }
+
+    @Override
+    public abstract ResolvedType resolve();
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ArrayType> toArrayType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ClassOrInterfaceType> toClassOrInterfaceType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<IntersectionType> toIntersectionType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<PrimitiveType> toPrimitiveType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<ReferenceType> toReferenceType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TypeParameter> toTypeParameter() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnionType> toUnionType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnknownType> toUnknownType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<VoidType> toVoidType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<WildcardType> toWildcardType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isVarType() {
+        return false;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public VarType asVarType() {
+        throw new IllegalStateException(f("%s is not an VarType", this));
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<VarType> toVarType() {
+        return Optional.empty();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifVarType(Consumer<VarType> action) {
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java
new file mode 100644
index 0000000..c3f8ced
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/TypeParameter.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.joining;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.TypeParameterMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * A type parameter.
+ * <br/><code>&lt;<b>U</b>> U getU() { ... }</code>
+ * <br/><code>class D &lt;<b>@Brain T extends B & A & @Tripe C</b>> { ... }</code>
+ * <p>U and T are type parameter names.
+ * <br/>B, A, and C are type parameter bounds.
+ * <br/>Tripe is an annotation on type parameter bound C.
+ * <br/>Brain is an annotation on type parameter T.
+ *
+ * @author Julio Vilmar Gesser
+ * @see com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters
+ */
+public final class TypeParameter extends ReferenceType implements NodeWithSimpleName<TypeParameter>, NodeWithAnnotations<TypeParameter> {
+
+    private SimpleName name;
+
+    private NodeList<ClassOrInterfaceType> typeBound;
+
+    public TypeParameter() {
+        this(null, new SimpleName(), new NodeList<>(), new NodeList<>());
+    }
+
+    public TypeParameter(final String name) {
+        this(null, new SimpleName(name), new NodeList<>(), new NodeList<>());
+    }
+
+    public TypeParameter(final String name, final NodeList<ClassOrInterfaceType> typeBound) {
+        this(null, new SimpleName(name), typeBound, new NodeList<>());
+    }
+
+    /**
+     * @deprecated range shouldn't be in utility constructors.
+     */
+    @Deprecated
+    public TypeParameter(Range range, final SimpleName name, final NodeList<ClassOrInterfaceType> typeBound) {
+        this(null, name, typeBound, new NodeList<>());
+        setRange(range);
+    }
+
+    @AllFieldsConstructor
+    public TypeParameter(SimpleName name, NodeList<ClassOrInterfaceType> typeBound, NodeList<AnnotationExpr> annotations) {
+        this(null, name, typeBound, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public TypeParameter(TokenRange tokenRange, SimpleName name, NodeList<ClassOrInterfaceType> typeBound, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange, annotations);
+        setName(name);
+        setTypeBound(typeBound);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return the name of the paramenter.
+     *
+     * @return the name of the paramenter
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public SimpleName getName() {
+        return name;
+    }
+
+    /**
+     * Return the list of {@link ClassOrInterfaceType} that this parameter
+     * extends. Return <code>null</code> null if there are no type.
+     *
+     * @return list of types that this paramente extends or <code>null</code>
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ClassOrInterfaceType> getTypeBound() {
+        return typeBound;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public TypeParameter setName(final SimpleName name) {
+        assertNotNull(name);
+        if (name == this.name) {
+            return (TypeParameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.NAME, this.name, name);
+        if (this.name != null)
+            this.name.setParentNode(null);
+        this.name = name;
+        setAsParentNodeOf(name);
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public TypeParameter setTypeBound(final NodeList<ClassOrInterfaceType> typeBound) {
+        assertNotNull(typeBound);
+        if (typeBound == this.typeBound) {
+            return (TypeParameter) this;
+        }
+        notifyPropertyChange(ObservableProperty.TYPE_BOUND, this.typeBound, typeBound);
+        if (this.typeBound != null)
+            this.typeBound.setParentNode(null);
+        this.typeBound = typeBound;
+        setAsParentNodeOf(typeBound);
+        return this;
+    }
+
+    @Override
+    public TypeParameter setAnnotations(NodeList<AnnotationExpr> annotations) {
+        super.setAnnotations(annotations);
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < typeBound.size(); i++) {
+            if (typeBound.get(i) == node) {
+                typeBound.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        StringBuilder str = new StringBuilder(getNameAsString());
+        getTypeBound().ifNonEmpty(l -> str.append(l.stream().map(ClassOrInterfaceType::asString).collect(joining("&", " extends ", ""))));
+        return str.toString();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public TypeParameter clone() {
+        return (TypeParameter) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public TypeParameterMetaModel getMetaModel() {
+        return JavaParserMetaModel.typeParameterMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (node == name) {
+            setName((SimpleName) replacementNode);
+            return true;
+        }
+        for (int i = 0; i < typeBound.size(); i++) {
+            if (typeBound.get(i) == node) {
+                typeBound.set(i, (ClassOrInterfaceType) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isTypeParameter() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public TypeParameter asTypeParameter() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifTypeParameter(Consumer<TypeParameter> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedTypeVariable resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedTypeVariable.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<TypeParameter> toTypeParameter() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java
new file mode 100644
index 0000000..5fa78f1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnionType.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.joining;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import com.github.javaparser.metamodel.UnionTypeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * <h1>The union type</h1>
+ * Represents a set of types. A given value of this type has to be assignable to at least one of the element types.
+ * <h2>Java 1-6</h2>
+ * Does not exist.
+ * <h2>Java 7+</h2>
+ * As of Java 7 it is used in catch clauses.
+ * <pre><code>
+ * try {
+ * ...
+ * } catch(<b>IOException | NullPointerException ex</b>) {
+ * ...
+ * }
+ * </pre>
+ *
+ * The types that make up the union type are its "elements"
+ */
+public final class UnionType extends Type implements NodeWithAnnotations<UnionType> {
+
+    @NonEmptyProperty
+    private NodeList<ReferenceType> elements;
+
+    public UnionType() {
+        this(null, new NodeList<>());
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public UnionType(TokenRange tokenRange, NodeList<ReferenceType> elements) {
+        super(tokenRange);
+        setElements(elements);
+        customInitialization();
+    }
+
+    @AllFieldsConstructor
+    public UnionType(NodeList<ReferenceType> elements) {
+        this(null, elements);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public NodeList<ReferenceType> getElements() {
+        return elements;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public UnionType setElements(final NodeList<ReferenceType> elements) {
+        assertNotNull(elements);
+        if (elements == this.elements) {
+            return (UnionType) this;
+        }
+        notifyPropertyChange(ObservableProperty.ELEMENTS, this.elements, elements);
+        if (this.elements != null)
+            this.elements.setParentNode(null);
+        this.elements = elements;
+        setAsParentNodeOf(elements);
+        return this;
+    }
+
+    @Override
+    public UnionType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (UnionType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < elements.size(); i++) {
+            if (elements.get(i) == node) {
+                elements.remove(i);
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        return elements.stream().map(Type::asString).collect(joining("|"));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public UnionType clone() {
+        return (UnionType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public UnionTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.unionTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        for (int i = 0; i < elements.size(); i++) {
+            if (elements.get(i) == node) {
+                elements.set(i, (ReferenceType) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnionType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnionType asUnionType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnionType(Consumer<UnionType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedUnionType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedUnionType.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnionType> toUnionType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java
new file mode 100644
index 0000000..d415214
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/UnknownType.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.UnknownTypeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * An unknown parameter type object. It plays the role of a null object for
+ * lambda parameters that have no explicit type declared. As such, it has no
+ * lexical representation and hence gets no comment attributed.
+ * <p>
+ * <br/>In <code>DoubleToIntFunction d = <b>x</b> -> (int)x + 1;</code> the x parameter in bold has type UnknownType.
+ *
+ * @author Didier Villevalois
+ */
+public final class UnknownType extends Type {
+
+    @AllFieldsConstructor
+    public UnknownType() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public UnknownType(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public UnknownType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        if (annotations.size() > 0) {
+            throw new IllegalStateException("Inferred lambda types cannot be annotated.");
+        }
+        return (UnknownType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        return "";
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public UnknownType clone() {
+        return (UnknownType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public UnknownTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.unknownTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isUnknownType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public UnknownType asUnknownType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifUnknownType(Consumer<UnknownType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedReferenceType.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<UnknownType> toUnknownType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/VarType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/VarType.java
new file mode 100644
index 0000000..3755c2f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/VarType.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.VoidTypeMetaModel;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import javax.annotation.Generated;
+import java.util.Optional;
+import java.util.function.Consumer;
+import com.github.javaparser.metamodel.VarTypeMetaModel;
+
+public final class VarType extends Type {
+
+    @AllFieldsConstructor
+    public VarType() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public VarType(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    public VarType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (VarType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        return "var";
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public VarType clone() {
+        return (VarType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public VarTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.varTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    public ResolvedType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedType.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isVarType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public VarType asVarType() {
+        return this;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<VarType> toVarType() {
+        return Optional.of(this);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifVarType(Consumer<VarType> action) {
+        action.accept(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java
new file mode 100644
index 0000000..860a9d6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/VoidType.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.Arrays;
+import java.util.List;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.metamodel.VoidTypeMetaModel;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import java.util.function.Consumer;
+import java.util.Optional;
+
+/**
+ * The return type of a {@link com.github.javaparser.ast.body.MethodDeclaration}
+ * when it returns void.
+ * <br/><code><b>void</b> helloWorld() { ... }</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class VoidType extends Type implements NodeWithAnnotations<VoidType> {
+
+    @AllFieldsConstructor
+    public VoidType() {
+        this(null);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public VoidType(TokenRange tokenRange) {
+        super(tokenRange);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public VoidType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (VoidType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        return "void";
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public VoidType clone() {
+        return (VoidType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public VoidTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.voidTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        return super.replace(node, replacementNode);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isVoidType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public VoidType asVoidType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifVoidType(Consumer<VoidType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedVoidType resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedVoidType.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<VoidType> toVoidType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java b/javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java
new file mode 100644
index 0000000..e37842e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/type/WildcardType.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.metamodel.OptionalProperty;
+import com.github.javaparser.metamodel.WildcardTypeMetaModel;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import javax.annotation.Generated;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import com.github.javaparser.resolution.types.ResolvedWildcard;
+import java.util.function.Consumer;
+
+/**
+ * A wildcard type argument.
+ * <br/><code>void printCollection(Collection&lt;<b>?</b>> c) { ... }</code>
+ * <br/><code>boolean addAll(Collection&lt;<b>? extends E</b>> c)</code>
+ * <br/><code>Reference(T referent, ReferenceQueue&lt;<b>? super T</b>> queue)</code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class WildcardType extends Type implements NodeWithAnnotations<WildcardType> {
+
+    @OptionalProperty
+    private ReferenceType extendedType;
+
+    @OptionalProperty
+    private ReferenceType superType;
+
+    public WildcardType() {
+        this(null, null, null, new NodeList<>());
+    }
+
+    public WildcardType(final ReferenceType extendedType) {
+        this(null, extendedType, null, new NodeList<>());
+    }
+
+    @AllFieldsConstructor
+    public WildcardType(final ReferenceType extendedType, final ReferenceType superType, final NodeList<AnnotationExpr> annotations) {
+        this(null, extendedType, superType, annotations);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public WildcardType(TokenRange tokenRange, ReferenceType extendedType, ReferenceType superType, NodeList<AnnotationExpr> annotations) {
+        super(tokenRange, annotations);
+        setExtendedType(extendedType);
+        setSuperType(superType);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.AcceptGenerator")
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<ReferenceType> getExtendedType() {
+        return Optional.ofNullable(extendedType);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public Optional<ReferenceType> getSuperType() {
+        return Optional.ofNullable(superType);
+    }
+
+    /**
+     * @deprecated use getExtendedType instead.
+     */
+    @Deprecated
+    public Optional<ReferenceType> getExtendedTypes() {
+        return getExtendedType();
+    }
+
+    /**
+     * @deprecated use getSuperType instead.
+     */
+    @Deprecated
+    public Optional<ReferenceType> getSuperTypes() {
+        return getSuperType();
+    }
+
+    /**
+     * Sets the extended type
+     *
+     * @param extendedType the extends, can be null
+     * @return this, the WildcardType
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public WildcardType setExtendedType(final ReferenceType extendedType) {
+        if (extendedType == this.extendedType) {
+            return (WildcardType) this;
+        }
+        notifyPropertyChange(ObservableProperty.EXTENDED_TYPE, this.extendedType, extendedType);
+        if (this.extendedType != null)
+            this.extendedType.setParentNode(null);
+        this.extendedType = extendedType;
+        setAsParentNodeOf(extendedType);
+        return this;
+    }
+
+    /**
+     * Sets the extended type
+     *
+     * @param extendedType the extends, can be null
+     * @return this, the WildcardType
+     * @deprecated use setExtendedType instead,
+     */
+    @Deprecated
+    public WildcardType setExtendedTypes(final ReferenceType extendedType) {
+        return setExtendedType(extendedType);
+    }
+
+    /**
+     * Sets the supertype
+     *
+     * @param superType the super, can be null
+     * @return this, the WildcardType
+     */
+    @Generated("com.github.javaparser.generator.core.node.PropertyGenerator")
+    public WildcardType setSuperType(final ReferenceType superType) {
+        if (superType == this.superType) {
+            return (WildcardType) this;
+        }
+        notifyPropertyChange(ObservableProperty.SUPER_TYPE, this.superType, superType);
+        if (this.superType != null)
+            this.superType.setParentNode(null);
+        this.superType = superType;
+        setAsParentNodeOf(superType);
+        return this;
+    }
+
+    /**
+     * Sets the supertype
+     *
+     * @param superType the super, can be null
+     * @return this, the WildcardType
+     * @deprecated use setSuperType instead
+     */
+    @Deprecated
+    public WildcardType setSuperTypes(final ReferenceType superType) {
+        return setSuperType(superType);
+    }
+
+    @Override
+    public WildcardType setAnnotations(NodeList<AnnotationExpr> annotations) {
+        return (WildcardType) super.setAnnotations(annotations);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public boolean remove(Node node) {
+        if (node == null)
+            return false;
+        if (extendedType != null) {
+            if (node == extendedType) {
+                removeExtendedType();
+                return true;
+            }
+        }
+        if (superType != null) {
+            if (node == superType) {
+                removeSuperType();
+                return true;
+            }
+        }
+        return super.remove(node);
+    }
+
+    @Override
+    public String asString() {
+        StringBuilder str = new StringBuilder("?");
+        getExtendedType().ifPresent(t -> str.append(" extends ").append(t.asString()));
+        getSuperType().ifPresent(t -> str.append(" super ").append(t.asString()));
+        return str.toString();
+    }
+
+    @Deprecated
+    public WildcardType removeExtendedTypes() {
+        return removeExtendedType();
+    }
+
+    @Deprecated
+    public WildcardType removeSuperTypes() {
+        return removeSuperType();
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public WildcardType removeExtendedType() {
+        return setExtendedType((ReferenceType) null);
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.RemoveMethodGenerator")
+    public WildcardType removeSuperType() {
+        return setSuperType((ReferenceType) null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.CloneGenerator")
+    public WildcardType clone() {
+        return (WildcardType) accept(new CloneVisitor(), null);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.GetMetaModelGenerator")
+    public WildcardTypeMetaModel getMetaModel() {
+        return JavaParserMetaModel.wildcardTypeMetaModel;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.ReplaceMethodGenerator")
+    public boolean replace(Node node, Node replacementNode) {
+        if (node == null)
+            return false;
+        if (extendedType != null) {
+            if (node == extendedType) {
+                setExtendedType((ReferenceType) replacementNode);
+                return true;
+            }
+        }
+        if (superType != null) {
+            if (node == superType) {
+                setSuperType((ReferenceType) replacementNode);
+                return true;
+            }
+        }
+        return super.replace(node, replacementNode);
+    }
+
+    /**
+     * This constructor is used by the parser and is considered private.
+     */
+    @Generated("com.github.javaparser.generator.core.node.MainConstructorGenerator")
+    public WildcardType(TokenRange tokenRange, ReferenceType extendedType, ReferenceType superType) {
+        super(tokenRange);
+        setExtendedType(extendedType);
+        setSuperType(superType);
+        customInitialization();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public boolean isWildcardType() {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public WildcardType asWildcardType() {
+        return this;
+    }
+
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public void ifWildcardType(Consumer<WildcardType> action) {
+        action.accept(this);
+    }
+
+    @Override
+    public ResolvedWildcard resolve() {
+        return getSymbolResolver().toResolvedType(this, ResolvedWildcard.class);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.node.TypeCastingGenerator")
+    public Optional<WildcardType> toWildcardType() {
+        return Optional.of(this);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java10Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java10Validator.java
new file mode 100644
index 0000000..c7fda2f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java10Validator.java
@@ -0,0 +1,19 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.type.VarType;
+import com.github.javaparser.ast.validator.chunks.VarValidator;
+
+/**
+ * This validator validates according to Java 10 syntax rules.
+ */
+public class Java10Validator extends Java9Validator {
+
+    protected final Validator varOnlyOnLocalVariableDefinitionAndFor = new SingleNodeTypeValidator<>(VarType.class, new VarValidator(false));
+
+    public Java10Validator() {
+        super();
+        add(varOnlyOnLocalVariableDefinitionAndFor);
+        /* There is no validator that validates that "var" is not used in Java 9 and lower, since the parser will never create a VarType node,
+           because that is done by the Java10 postprocessor. You can add it by hand, but that is obscure enough to ignore. */
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java11Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java11Validator.java
new file mode 100644
index 0000000..0eb879a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java11Validator.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.type.VarType;
+import com.github.javaparser.ast.validator.chunks.VarValidator;
+
+/**
+ * This validator validates according to Java 11 syntax rules.
+ */
+public class Java11Validator extends Java10Validator {
+    protected final Validator varAlsoInLambdaParameters = new SingleNodeTypeValidator<>(VarType.class, new VarValidator(true));
+
+    public Java11Validator() {
+        super();
+        replace(varOnlyOnLocalVariableDefinitionAndFor, varAlsoInLambdaParameters);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_0Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_0Validator.java
new file mode 100644
index 0000000..0d1051d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_0Validator.java
@@ -0,0 +1,121 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.modules.ModuleDeclaration;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.type.UnionType;
+import com.github.javaparser.ast.validator.chunks.CommonValidators;
+import com.github.javaparser.ast.validator.chunks.ModifierValidator;
+import com.github.javaparser.ast.validator.chunks.NoBinaryIntegerLiteralsValidator;
+import com.github.javaparser.ast.validator.chunks.NoUnderscoresInIntegerLiteralsValidator;
+
+/**
+ * This validator validates according to Java 1.0 syntax rules.
+ */
+public class Java1_0Validator extends Validators {
+    protected final Validator modifiersWithoutStrictfpAndDefaultAndStaticInterfaceMethodsAndPrivateInterfaceMethods
+            = new ModifierValidator(false, false, false);
+    protected final Validator noAssertKeyword = new SimpleValidator<>(AssertStmt.class,
+            n -> true,
+            (n, reporter) -> reporter.report(n, "'assert' keyword is not supported.")
+    );
+    protected final Validator noInnerClasses = new SimpleValidator<>(ClassOrInterfaceDeclaration.class,
+            n -> !n.isTopLevelType(),
+            (n, reporter) -> reporter.report(n, "inner classes or interfaces are not supported.")
+    );
+    protected final Validator noReflection = new SimpleValidator<>(ClassExpr.class,
+            n -> true,
+            (n, reporter) -> reporter.report(n, "Reflection is not supported.")
+    );
+    protected final Validator noGenerics = new TreeVisitorValidator((node, reporter) -> {
+        if (node instanceof NodeWithTypeArguments) {
+            if (((NodeWithTypeArguments<? extends Node>) node).getTypeArguments().isPresent()) {
+                reporter.report(node, "Generics are not supported.");
+            }
+        }
+        if (node instanceof NodeWithTypeParameters) {
+            if (((NodeWithTypeParameters<? extends Node>) node).getTypeParameters().isNonEmpty()) {
+                reporter.report(node, "Generics are not supported.");
+            }
+        }
+    });
+    protected final SingleNodeTypeValidator<TryStmt> tryWithoutResources = new SingleNodeTypeValidator<>(TryStmt.class, (n, reporter) -> {
+        if (n.getCatchClauses().isEmpty() && !n.getFinallyBlock().isPresent()) {
+            reporter.report(n, "Try has no finally and no catch.");
+        }
+        if (n.getResources().isNonEmpty()) {
+            reporter.report(n, "Catch with resource is not supported.");
+        }
+    });
+    protected final Validator noAnnotations = new TreeVisitorValidator((node, reporter) -> {
+        if (node instanceof AnnotationExpr || node instanceof AnnotationDeclaration) {
+            reporter.report(node, "Annotations are not supported.");
+        }
+    });
+    protected final Validator noEnums = new SimpleValidator<>(EnumDeclaration.class,
+            n -> true,
+            (n, reporter) -> reporter.report(n, "Enumerations are not supported.")
+    );
+    protected final Validator noVarargs = new SimpleValidator<>(Parameter.class,
+            Parameter::isVarArgs,
+            (n, reporter) -> reporter.report(n, "Varargs are not supported.")
+    );
+    protected final Validator noForEach = new SimpleValidator<>(ForeachStmt.class,
+            n -> true,
+            (n, reporter) -> reporter.report(n, "For-each loops are not supported.")
+    );
+    protected final Validator noStaticImports = new SimpleValidator<>(ImportDeclaration.class,
+            ImportDeclaration::isStatic,
+            (n, reporter) -> reporter.report(n, "Static imports are not supported.")
+    );
+    protected final Validator noStringsInSwitch = new SimpleValidator<>(SwitchEntryStmt.class,
+            n -> n.getLabel().map(l -> l instanceof StringLiteralExpr).orElse(false),
+            (n, reporter) -> reporter.report(n.getLabel().get(), "Strings in switch statements are not supported.")
+    );
+    protected final Validator noBinaryIntegerLiterals = new NoBinaryIntegerLiteralsValidator();
+    protected final Validator noUnderscoresInIntegerLiterals = new NoUnderscoresInIntegerLiteralsValidator();
+    protected final Validator noMultiCatch = new SimpleValidator<>(UnionType.class,
+            n -> true,
+            (n, reporter) -> reporter.report(n, "Multi-catch is not supported.")
+    );
+    protected final Validator noLambdas = new SimpleValidator<>(LambdaExpr.class,
+            n -> true,
+            (n, reporter) -> reporter.report(n, "Lambdas are not supported.")
+    );
+    protected final Validator noModules = new SimpleValidator<>(ModuleDeclaration.class,
+            n -> true,
+            (n, reporter) -> reporter.report(n, "Modules are not supported.")
+    );
+
+    public Java1_0Validator() {
+        super(new CommonValidators());
+        add(modifiersWithoutStrictfpAndDefaultAndStaticInterfaceMethodsAndPrivateInterfaceMethods);
+        add(noAssertKeyword);
+        add(noInnerClasses);
+        add(noReflection);
+        add(noGenerics);
+        add(tryWithoutResources);
+        add(noAnnotations);
+        add(noEnums);
+        add(noVarargs);
+        add(noForEach);
+        add(noStaticImports);
+        add(noStringsInSwitch);
+        add(noBinaryIntegerLiterals);
+        add(noUnderscoresInIntegerLiterals);
+        add(noMultiCatch);
+        add(noLambdas);
+        add(noModules);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_1Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_1Validator.java
new file mode 100644
index 0000000..5279b7f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_1Validator.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.stmt.LocalClassDeclarationStmt;
+
+/**
+ * This validator validates according to Java 1.1 syntax rules.
+ */
+public class Java1_1Validator extends Java1_0Validator {
+    protected final Validator innerClasses = new SingleNodeTypeValidator<>(ClassOrInterfaceDeclaration.class,
+            (n, reporter) -> n.getParentNode().ifPresent(p -> {
+                if (p instanceof LocalClassDeclarationStmt && n.isInterface())
+                    reporter.report(n, "There is no such thing as a local interface.");
+            })
+    );
+
+    public Java1_1Validator() {
+        super();
+        replace(noInnerClasses, innerClasses);
+        remove(noReflection);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_2Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_2Validator.java
new file mode 100644
index 0000000..4ac7565
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_2Validator.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.validator.chunks.ModifierValidator;
+
+/**
+ * This validator validates according to Java 1.2 syntax rules.
+ */
+public class Java1_2Validator extends Java1_1Validator {
+    protected final Validator modifiersWithoutDefaultAndStaticInterfaceMethodsAndPrivateInterfaceMethods = new ModifierValidator(true, false, false);
+    protected final Validator strictfpNotAllowed = new ReservedKeywordValidator("strictfp");
+    
+    public Java1_2Validator() {
+        super();
+        replace(modifiersWithoutStrictfpAndDefaultAndStaticInterfaceMethodsAndPrivateInterfaceMethods, modifiersWithoutDefaultAndStaticInterfaceMethodsAndPrivateInterfaceMethods);
+        add(strictfpNotAllowed);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_3Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_3Validator.java
new file mode 100644
index 0000000..72830a1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_3Validator.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.ast.validator;
+
+/**
+ * This validator validates according to Java 1.3 syntax rules.
+ */
+public class Java1_3Validator extends Java1_2Validator {
+    public Java1_3Validator() {
+        super();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_4Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_4Validator.java
new file mode 100644
index 0000000..2d4ad5e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java1_4Validator.java
@@ -0,0 +1,11 @@
+package com.github.javaparser.ast.validator;
+
+/**
+ * This validator validates according to Java 1.4 syntax rules.
+ */
+public class Java1_4Validator extends Java1_3Validator {
+    public Java1_4Validator() {
+        super();
+        remove(noAssertKeyword);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java5Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java5Validator.java
new file mode 100644
index 0000000..d8b1aab
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java5Validator.java
@@ -0,0 +1,52 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.ast.type.Type;
+
+import java.util.Optional;
+
+/**
+ * This validator validates according to Java 5 syntax rules.
+ */
+public class Java5Validator extends Java1_4Validator {
+    Validator genericsWithoutDiamondOperator = new TreeVisitorValidator((node, reporter) -> {
+        if (node instanceof NodeWithTypeArguments) {
+            Optional<NodeList<Type>> typeArguments = ((NodeWithTypeArguments<? extends Node>) node).getTypeArguments();
+            if (typeArguments.isPresent() && typeArguments.get().isEmpty()) {
+                reporter.report(node, "The diamond operator is not supported.");
+            }
+        }
+    });
+
+    protected Validator noPrimitiveGenericArguments = new TreeVisitorValidator((node, reporter) -> {
+        if (node instanceof NodeWithTypeArguments) {
+            Optional<NodeList<Type>> typeArguments = ((NodeWithTypeArguments<? extends Node>) node).getTypeArguments();
+            typeArguments.ifPresent(types -> types.forEach(ty -> {
+                if (ty instanceof PrimitiveType) {
+                    reporter.report(node, "Type arguments may not be primitive.");
+                }
+            }));
+        }
+    });
+
+    protected final Validator enumNotAllowed = new ReservedKeywordValidator("enum");
+
+    public Java5Validator() {
+        super();
+        replace(noGenerics, genericsWithoutDiamondOperator);
+        add(noPrimitiveGenericArguments);
+        add(enumNotAllowed);
+        
+        // TODO validate annotations on classes, fields and methods but nowhere else
+        // The following is probably too simple.
+        remove(noAnnotations);
+
+        remove(noEnums);
+        remove(noVarargs);
+        remove(noForEach);
+        remove(noStaticImports);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java6Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java6Validator.java
new file mode 100644
index 0000000..7054003
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java6Validator.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.ast.validator;
+
+/**
+ * This validator validates according to Java 6 syntax rules.
+ */
+public class Java6Validator extends Java5Validator{
+    public Java6Validator() {
+        super();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java7Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java7Validator.java
new file mode 100644
index 0000000..995e836
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java7Validator.java
@@ -0,0 +1,39 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.type.UnionType;
+
+/**
+ * This validator validates according to Java 7 syntax rules.
+ */
+public class Java7Validator extends Java6Validator {
+    protected final SingleNodeTypeValidator<TryStmt> tryWithLimitedResources = new SingleNodeTypeValidator<>(TryStmt.class, (n, reporter) -> {
+        if (n.getCatchClauses().isEmpty()
+                && n.getResources().isEmpty()
+                && !n.getFinallyBlock().isPresent()) {
+            reporter.report(n, "Try has no finally, no catch, and no resources.");
+        }
+        for (Expression resource : n.getResources()) {
+            if (!resource.isVariableDeclarationExpr()) {
+                reporter.report(n, "Try with resources only supports variable declarations.");
+            }
+        }
+    });
+    protected final SingleNodeTypeValidator<UnionType> multiCatch = new SingleNodeTypeValidator<>(UnionType.class, (n, reporter) -> {
+        // Case "0 elements" is caught elsewhere.
+        if (n.getElements().size() == 1) {
+            reporter.report(n, "Union type (multi catch) must have at least two elements.");
+        }
+    });
+
+    public Java7Validator() {
+        super();
+        remove(genericsWithoutDiamondOperator);
+        replace(tryWithoutResources, tryWithLimitedResources);
+        remove(noStringsInSwitch);
+        remove(noBinaryIntegerLiterals);
+        remove(noUnderscoresInIntegerLiterals);
+        replace(noMultiCatch, multiCatch);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java8Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java8Validator.java
new file mode 100644
index 0000000..e6aca92
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java8Validator.java
@@ -0,0 +1,32 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.validator.chunks.ModifierValidator;
+
+/**
+ * This validator validates according to Java 7 syntax rules.
+ */
+public class Java8Validator extends Java7Validator {
+    protected final Validator modifiersWithoutPrivateInterfaceMethods = new ModifierValidator(true, true, false);
+    protected final Validator defaultMethodsInInterface = new SingleNodeTypeValidator<>(ClassOrInterfaceDeclaration.class,
+            (n, reporter) -> {
+                if (n.isInterface()) {
+                    n.getMethods().forEach(m -> {
+                        if (m.isDefault() && !m.getBody().isPresent()) {
+                            reporter.report(m, "'default' methods must have a body.");
+                        }
+                    });
+                }
+            }
+    );
+
+    public Java8Validator() {
+        super();
+        replace(modifiersWithoutDefaultAndStaticInterfaceMethodsAndPrivateInterfaceMethods, modifiersWithoutPrivateInterfaceMethods);
+        add(defaultMethodsInInterface);
+        remove(noLambdas);
+
+        // TODO validate more annotation locations http://openjdk.java.net/jeps/104
+        // TODO validate repeating annotations http://openjdk.java.net/jeps/120
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java9Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java9Validator.java
new file mode 100644
index 0000000..2175c9a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Java9Validator.java
@@ -0,0 +1,30 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.validator.chunks.ModifierValidator;
+import com.github.javaparser.ast.validator.chunks.UnderscoreKeywordValidator;
+
+/**
+ * This validator validates according to Java 9 syntax rules.
+ */
+public class Java9Validator extends Java8Validator {
+    protected final Validator underscoreKeywordValidator = new UnderscoreKeywordValidator();
+    protected final Validator modifiers = new ModifierValidator(true, true, true);
+    protected final SingleNodeTypeValidator<TryStmt> tryWithResources = new SingleNodeTypeValidator<>(TryStmt.class, (n, reporter) -> {
+        if (n.getCatchClauses().isEmpty()
+                && n.getResources().isEmpty()
+                && !n.getFinallyBlock().isPresent()) {
+            reporter.report(n, "Try has no finally, no catch, and no resources.");
+        }
+    });
+
+    public Java9Validator() {
+        super();
+        add(underscoreKeywordValidator);
+        remove(noModules);
+        replace(modifiersWithoutPrivateInterfaceMethods, modifiers);
+        replace(tryWithLimitedResources, tryWithResources);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/NoProblemsValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/NoProblemsValidator.java
new file mode 100644
index 0000000..0026688
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/NoProblemsValidator.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.Node;
+
+/**
+ * Stub validator for when no validation is wanted.
+ *
+ * @deprecated when setting a language validator, try {@link com.github.javaparser.ParserConfiguration#setLanguageLevel(ParserConfiguration.LanguageLevel)} with RAW.
+ */
+@Deprecated
+public final class NoProblemsValidator implements Validator {
+    @Override
+    public void accept(Node node, ProblemReporter problemReporter) {
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/ProblemReporter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/ProblemReporter.java
new file mode 100644
index 0000000..eb54810
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/ProblemReporter.java
@@ -0,0 +1,34 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.Problem;
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.nodeTypes.NodeWithTokenRange;
+
+import java.util.function.Consumer;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * A simple interface where validators can report found problems.
+ */
+public class ProblemReporter {
+    private final Consumer<Problem> problemConsumer;
+
+    public ProblemReporter(Consumer<Problem> problemConsumer) {
+        this.problemConsumer = problemConsumer;
+    }
+
+    /**
+     * Report a problem.
+     *
+     * @param message description of the problem
+     * @param node the node in which the problem occurred, used to find the Range of the problem.
+     */
+    public void report(NodeWithTokenRange<?> node, String message, Object... args) {
+        report(node.getTokenRange().orElse(null), message, args);
+    }
+
+    public void report(TokenRange range, String message, Object... args) {
+        problemConsumer.accept(new Problem(f(message, args), range, null));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/ReservedKeywordValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/ReservedKeywordValidator.java
new file mode 100644
index 0000000..51a08bd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/ReservedKeywordValidator.java
@@ -0,0 +1,36 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.SimpleName;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Validates that identifiers are not keywords - this for the few keywords that the parser
+ * accepts because they were added after Java 1.0.
+ */
+public class ReservedKeywordValidator extends VisitorValidator {
+    private final String keyword;
+    private final String error;
+
+    public ReservedKeywordValidator(String keyword) {
+        this.keyword = keyword;
+        error = f("'%s' cannot be used as an identifier as it is a keyword.", keyword);
+    }
+
+    @Override
+    public void visit(Name n, ProblemReporter arg) {
+        if (n.getIdentifier().equals(keyword)) {
+            arg.report(n, error);
+        }
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(SimpleName n, ProblemReporter arg) {
+        if (n.getIdentifier().equals(keyword)) {
+            arg.report(n, error);
+        }
+        super.visit(n, arg);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/SimpleValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/SimpleValidator.java
new file mode 100644
index 0000000..b705b91
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/SimpleValidator.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.Node;
+
+import java.util.function.BiConsumer;
+import java.util.function.Predicate;
+
+/**
+ * Runs a validator on all nodes of a certain type,
+ * and adds a problem for all nodes that pass a condition.
+ */
+public class SimpleValidator<N extends Node> extends SingleNodeTypeValidator<N> {
+    public SimpleValidator(Class<N> type, Predicate<N> condition, BiConsumer<N, ProblemReporter> problemSupplier) {
+        super(type, (node, problemReporter) -> {
+            if (condition.test(node)) {
+                problemSupplier.accept(node, problemReporter);
+            }
+        });
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/SingleNodeTypeValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/SingleNodeTypeValidator.java
new file mode 100644
index 0000000..1698494
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/SingleNodeTypeValidator.java
@@ -0,0 +1,24 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * Runs a validator on all nodes of a certain type.
+ */
+public class SingleNodeTypeValidator<N extends Node> implements Validator {
+    private final Class<N> type;
+    private final TypedValidator<N> validator;
+
+    public SingleNodeTypeValidator(Class<N> type, TypedValidator<N> validator) {
+        this.type = type;
+        this.validator = validator;
+    }
+
+    @Override
+    public void accept(Node node, ProblemReporter problemReporter) {
+        if (type.isInstance(node)) {
+            validator.accept(type.cast(node), problemReporter);
+        }
+        node.findAll(type).forEach(n -> validator.accept(n, problemReporter));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/TreeVisitorValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/TreeVisitorValidator.java
new file mode 100644
index 0000000..ae8e049
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/TreeVisitorValidator.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * A validator that walks the whole tree, visiting every node.
+ */
+public class TreeVisitorValidator implements Validator {
+    private final Validator validator;
+
+    public TreeVisitorValidator(Validator validator) {
+        this.validator = validator;
+    }
+
+    @Override
+    public final void accept(Node node, ProblemReporter reporter) {
+        validator.accept(node, reporter);
+        for (Node child : node.getChildNodes()) {
+            accept(child, reporter);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/TypedValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/TypedValidator.java
new file mode 100644
index 0000000..588c53f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/TypedValidator.java
@@ -0,0 +1,24 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ast.Node;
+
+import java.util.function.BiConsumer;
+
+/**
+ * A validator that validates a known node type.
+ */
+public interface TypedValidator<N extends Node> extends BiConsumer<N, ProblemReporter> {
+    /**
+     * @param node the node that wants to be validated
+     * @param problemReporter when found, validation errors can be reported here
+     */
+    void accept(N node, ProblemReporter problemReporter);
+
+    @SuppressWarnings("unchecked")
+    default ParseResult.PostProcessor postProcessor() {
+        return (result, configuration) ->
+                result.getResult().ifPresent(node ->
+                        accept((N) node, new ProblemReporter(problem -> result.getProblems().add(problem))));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Validator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Validator.java
new file mode 100644
index 0000000..0d5752a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Validator.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * A validator that can be run on a node to check for semantic errors.
+ * It is fully up to the implementor how to do this.
+ */
+public interface Validator extends TypedValidator<Node> {
+    /**
+     * @param node the node that wants to be validated
+     * @param problemReporter when found, validation errors can be reported here
+     */
+    void accept(Node node, ProblemReporter problemReporter);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Validators.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Validators.java
new file mode 100644
index 0000000..dd6926a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/Validators.java
@@ -0,0 +1,45 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.Node;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A validator that will call a collection of validators.
+ */
+public class Validators implements Validator {
+    private final List<Validator> validators = new ArrayList<>();
+
+    public Validators(Validator... validators) {
+        this.validators.addAll(Arrays.asList(validators));
+    }
+
+    public List<Validator> getValidators() {
+        return validators;
+    }
+
+    public Validators remove(Validator validator) {
+        if (!validators.remove(validator)) {
+            throw new AssertionError("Trying to remove a validator that isn't there.");
+        }
+        return this;
+    }
+
+    public Validators replace(Validator oldValidator, Validator newValidator) {
+        remove(oldValidator);
+        add(newValidator);
+        return this;
+    }
+
+    public Validators add(Validator newValidator) {
+        validators.add(newValidator);
+        return this;
+    }
+
+    @Override
+    public void accept(Node node, ProblemReporter problemReporter) {
+        validators.forEach(v -> v.accept(node, problemReporter));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/VisitorValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/VisitorValidator.java
new file mode 100644
index 0000000..547092d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/VisitorValidator.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+
+/**
+ * A validator that uses a visitor for validation.
+ * This class is the visitor too.
+ * Implement the "visit" methods you want to use for validation.
+ */
+public abstract class VisitorValidator extends VoidVisitorAdapter<ProblemReporter> implements Validator {
+    @Override
+    public void accept(Node node, ProblemReporter problemReporter) {
+        node.accept(this, problemReporter);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/CommonValidators.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/CommonValidators.java
new file mode 100644
index 0000000..5e5b791
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/CommonValidators.java
@@ -0,0 +1,70 @@
+package com.github.javaparser.ast.validator.chunks;
+
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.validator.SimpleValidator;
+import com.github.javaparser.ast.validator.SingleNodeTypeValidator;
+import com.github.javaparser.ast.validator.TreeVisitorValidator;
+import com.github.javaparser.ast.validator.Validators;
+import com.github.javaparser.metamodel.NodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import java.util.Optional;
+
+/**
+ * Contains validations that are valid for every Java version.
+ */
+public class CommonValidators extends Validators {
+    public CommonValidators() {
+        super(
+                new SimpleValidator<>(ClassOrInterfaceDeclaration.class,
+                        n -> !n.isInterface() && n.getExtendedTypes().size() > 1,
+                        (n, reporter) -> reporter.report(n.getExtendedTypes(1), "A class cannot extend more than one other class.")
+                ),
+                new SimpleValidator<>(ClassOrInterfaceDeclaration.class,
+                        n -> n.isInterface() && !n.getImplementedTypes().isEmpty(),
+                        (n, reporter) -> reporter.report(n.getImplementedTypes(0), "An interface cannot implement other interfaces.")
+                ),
+                new SingleNodeTypeValidator<>(ClassOrInterfaceDeclaration.class, (n, reporter) -> {
+                    if (n.isInterface()) {
+                        n.getMembers().forEach(mem -> {
+                            if (mem instanceof InitializerDeclaration) {
+                                reporter.report(mem, "An interface cannot have initializers.");
+                            }
+                        });
+                    }
+                }
+                ),
+                new SingleNodeTypeValidator<>(AssignExpr.class, (n, reporter) -> {
+                    // https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26
+                    Expression target = n.getTarget();
+                    while (target instanceof EnclosedExpr) {
+                        target = ((EnclosedExpr) target).getInner();
+                    }
+                    if (target instanceof NameExpr
+                            || target instanceof ArrayAccessExpr
+                            || target instanceof FieldAccessExpr) {
+                        return;
+                    }
+                    reporter.report(n.getTarget(), "Illegal left hand side of an assignment.");
+                }
+                ),
+                new TreeVisitorValidator((node, problemReporter) -> {
+                    NodeMetaModel mm = node.getMetaModel();
+                    for (PropertyMetaModel ppm : mm.getAllPropertyMetaModels()) {
+                        if (ppm.isNonEmpty()) {
+                            if (ppm.isNodeList()) {
+                                NodeList value = (NodeList) ppm.getValue(node);
+                                if (value.isEmpty()) {
+                                    problemReporter.report(node, "%s.%s can not be empty.", mm.getTypeName(), ppm.getName());
+                                }
+                            }
+                            // No need to check empty strings, it should be impossible to set them to ""
+                        }
+                    }
+                })
+        );
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/ModifierValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/ModifierValidator.java
new file mode 100644
index 0000000..0a01c33
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/ModifierValidator.java
@@ -0,0 +1,211 @@
+package com.github.javaparser.ast.validator.chunks;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.modules.ModuleRequiresStmt;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+import com.github.javaparser.ast.nodeTypes.NodeWithTokenRange;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.validator.ProblemReporter;
+import com.github.javaparser.ast.validator.VisitorValidator;
+import com.github.javaparser.utils.SeparatedItemStringBuilder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.github.javaparser.ast.Modifier.*;
+import static java.util.Arrays.asList;
+
+
+/**
+ * Verifies that only allowed modifiers are used where modifiers are expected.
+ */
+public class ModifierValidator extends VisitorValidator {
+    private final Modifier[] interfaceWithNothingSpecial = new Modifier[]{PUBLIC, PROTECTED, ABSTRACT, FINAL, SYNCHRONIZED, NATIVE, STRICTFP};
+    private final Modifier[] interfaceWithStaticAndDefault = new Modifier[]{PUBLIC, PROTECTED, ABSTRACT, STATIC, FINAL, SYNCHRONIZED, NATIVE, STRICTFP, DEFAULT};
+    private final Modifier[] interfaceWithStaticAndDefaultAndPrivate = new Modifier[]{PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, SYNCHRONIZED, NATIVE, STRICTFP, DEFAULT};
+
+    private final boolean hasStrictfp;
+    private final boolean hasDefaultAndStaticInterfaceMethods;
+    private final boolean hasPrivateInterfaceMethods;
+
+    public ModifierValidator(boolean hasStrictfp, boolean hasDefaultAndStaticInterfaceMethods, boolean hasPrivateInterfaceMethods) {
+        this.hasStrictfp = hasStrictfp;
+        this.hasDefaultAndStaticInterfaceMethods = hasDefaultAndStaticInterfaceMethods;
+        this.hasPrivateInterfaceMethods = hasPrivateInterfaceMethods;
+    }
+
+    @Override
+    public void visit(ClassOrInterfaceDeclaration n, ProblemReporter reporter) {
+        if (n.isInterface()) {
+            validateInterfaceModifiers(n, reporter);
+        } else {
+            validateClassModifiers(n, reporter);
+        }
+        super.visit(n, reporter);
+    }
+
+    private void validateClassModifiers(ClassOrInterfaceDeclaration n, ProblemReporter reporter) {
+        if (n.isTopLevelType()) {
+            validateModifiers(n, reporter, PUBLIC, ABSTRACT, FINAL, STRICTFP);
+        } else if (n.isNestedType()) {
+            validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP);
+        } else if (n.isLocalClassDeclaration()) {
+            validateModifiers(n, reporter, ABSTRACT, FINAL, STRICTFP);
+        }
+    }
+
+    private void validateInterfaceModifiers(TypeDeclaration<?> n, ProblemReporter reporter) {
+        if (n.isTopLevelType()) {
+            validateModifiers(n, reporter, PUBLIC, ABSTRACT, STRICTFP);
+        } else if (n.isNestedType()) {
+            validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, STRICTFP);
+        }
+    }
+
+    @Override
+    public void visit(EnumDeclaration n, ProblemReporter reporter) {
+        if (n.isTopLevelType()) {
+            validateModifiers(n, reporter, PUBLIC, STRICTFP);
+        } else if (n.isNestedType()) {
+            validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, STATIC, STRICTFP);
+        }
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(AnnotationDeclaration n, ProblemReporter reporter) {
+        validateInterfaceModifiers(n, reporter);
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(AnnotationMemberDeclaration n, ProblemReporter reporter) {
+        validateModifiers(n, reporter, PUBLIC, ABSTRACT);
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(ConstructorDeclaration n, ProblemReporter reporter) {
+        validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE);
+        n.getParameters().forEach(p -> validateModifiers(p, reporter, FINAL));
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(FieldDeclaration n, ProblemReporter reporter) {
+        validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, STATIC, FINAL, TRANSIENT, VOLATILE);
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(MethodDeclaration n, ProblemReporter reporter) {
+        if (n.isAbstract()) {
+            final SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder("Cannot be 'abstract' and also '", "', '", "'.");
+            for (Modifier m : asList(PRIVATE, STATIC, FINAL, NATIVE, STRICTFP, SYNCHRONIZED)) {
+                if (n.getModifiers().contains(m)) {
+                    builder.append(m.asString());
+                }
+            }
+            if (builder.hasItems()) {
+                reporter.report(n, builder.toString());
+            }
+        }
+        if (n.getParentNode().isPresent()) {
+            if (n.getParentNode().get() instanceof ClassOrInterfaceDeclaration) {
+                if (((ClassOrInterfaceDeclaration) n.getParentNode().get()).isInterface()) {
+                    if (hasDefaultAndStaticInterfaceMethods) {
+                        if (hasPrivateInterfaceMethods) {
+                            validateModifiers(n, reporter, interfaceWithStaticAndDefaultAndPrivate);
+                        } else {
+                            validateModifiers(n, reporter, interfaceWithStaticAndDefault);
+                        }
+                    } else {
+                        validateModifiers(n, reporter, interfaceWithNothingSpecial);
+                    }
+                } else {
+                    validateModifiers(n, reporter, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, SYNCHRONIZED, NATIVE, STRICTFP);
+                }
+            }
+        }
+        n.getParameters().forEach(p -> validateModifiers(p, reporter, FINAL));
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(LambdaExpr n, ProblemReporter reporter) {
+        n.getParameters().forEach(p -> {
+            // Final is not allowed on inferred parameters, but those get caught by the parser.
+            validateModifiers(p, reporter, FINAL);
+        });
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(CatchClause n, ProblemReporter reporter) {
+        validateModifiers(n.getParameter(), reporter, FINAL);
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(VariableDeclarationExpr n, ProblemReporter reporter) {
+        validateModifiers(n, reporter, FINAL);
+        super.visit(n, reporter);
+    }
+
+    @Override
+    public void visit(ModuleRequiresStmt n, ProblemReporter reporter) {
+        validateModifiers(n, reporter, TRANSITIVE, STATIC);
+        super.visit(n, reporter);
+    }
+
+    private <T extends NodeWithModifiers<?> & NodeWithTokenRange<?>> void validateModifiers(T n, ProblemReporter reporter, Modifier... allowedModifiers) {
+        validateAtMostOneOf(n, reporter, PUBLIC, PROTECTED, PRIVATE);
+        validateAtMostOneOf(n, reporter, FINAL, ABSTRACT);
+        if (hasStrictfp) {
+            validateAtMostOneOf(n, reporter, NATIVE, STRICTFP);
+        } else {
+            allowedModifiers = removeModifierFromArray(STRICTFP, allowedModifiers);
+        }
+        for (Modifier m : n.getModifiers()) {
+            if (!arrayContains(allowedModifiers, m)) {
+                reporter.report(n, "'%s' is not allowed here.", m.asString());
+            }
+        }
+    }
+
+    private Modifier[] removeModifierFromArray(Modifier m, Modifier[] allowedModifiers) {
+        final List<Modifier> newModifiers = new ArrayList<>(asList(allowedModifiers));
+        newModifiers.remove(m);
+        allowedModifiers = newModifiers.toArray(new Modifier[0]);
+        return allowedModifiers;
+    }
+
+    private boolean arrayContains(Object[] items, Object searchItem) {
+        for (Object o : items) {
+            if (o == searchItem) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private <T extends NodeWithModifiers<?> & NodeWithTokenRange<?>> void validateAtMostOneOf(T t, ProblemReporter reporter, Modifier... modifiers) {
+        List<Modifier> foundModifiers = new ArrayList<>();
+        for (Modifier m : modifiers) {
+            if (t.getModifiers().contains(m)) {
+                foundModifiers.add(m);
+            }
+        }
+        if (foundModifiers.size() > 1) {
+            SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder("Can have only one of '", "', '", "'.");
+            for (Modifier m : foundModifiers) {
+                builder.append(m.asString());
+            }
+            reporter.report(t, builder.toString());
+        }
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/NoBinaryIntegerLiteralsValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/NoBinaryIntegerLiteralsValidator.java
new file mode 100644
index 0000000..82e8dd7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/NoBinaryIntegerLiteralsValidator.java
@@ -0,0 +1,27 @@
+package com.github.javaparser.ast.validator.chunks;
+
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.LiteralStringValueExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
+import com.github.javaparser.ast.validator.ProblemReporter;
+import com.github.javaparser.ast.validator.VisitorValidator;
+
+public class NoBinaryIntegerLiteralsValidator extends VisitorValidator {
+    @Override
+    public void visit(IntegerLiteralExpr n, ProblemReporter arg) {
+        validate(n, arg);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(LongLiteralExpr n, ProblemReporter arg) {
+        validate(n, arg);
+        super.visit(n, arg);
+    }
+
+    private static void validate(LiteralStringValueExpr n, ProblemReporter arg) {
+        if (n.getValue().toUpperCase().startsWith("0B")) {
+            arg.report(n, "Binary literal values are not supported.");
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/NoUnderscoresInIntegerLiteralsValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/NoUnderscoresInIntegerLiteralsValidator.java
new file mode 100644
index 0000000..901b734
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/NoUnderscoresInIntegerLiteralsValidator.java
@@ -0,0 +1,27 @@
+package com.github.javaparser.ast.validator.chunks;
+
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.LiteralStringValueExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
+import com.github.javaparser.ast.validator.ProblemReporter;
+import com.github.javaparser.ast.validator.VisitorValidator;
+
+public class NoUnderscoresInIntegerLiteralsValidator extends VisitorValidator {
+    @Override
+    public void visit(IntegerLiteralExpr n, ProblemReporter arg) {
+        validate(n, arg);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(LongLiteralExpr n, ProblemReporter arg) {
+        validate(n, arg);
+        super.visit(n, arg);
+    }
+
+    private static void validate(LiteralStringValueExpr n, ProblemReporter arg) {
+        if (n.getValue().contains("_")) {
+            arg.report(n, "Underscores in literal values are not supported.");
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/UnderscoreKeywordValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/UnderscoreKeywordValidator.java
new file mode 100644
index 0000000..e812597
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/UnderscoreKeywordValidator.java
@@ -0,0 +1,27 @@
+package com.github.javaparser.ast.validator.chunks;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.validator.ProblemReporter;
+import com.github.javaparser.ast.validator.VisitorValidator;
+
+public class UnderscoreKeywordValidator extends VisitorValidator {
+    @Override
+    public void visit(Name n, ProblemReporter arg) {
+        validateIdentifier(n, n.getIdentifier(), arg);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(SimpleName n, ProblemReporter arg) {
+        validateIdentifier(n, n.getIdentifier(), arg);
+        super.visit(n, arg);
+    }
+
+    private static void validateIdentifier(Node n, String id, ProblemReporter arg) {
+        if (id.equals("_")) {
+            arg.report(n, "'_' is a reserved keyword.");
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/VarValidator.java b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/VarValidator.java
new file mode 100644
index 0000000..19357e8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/validator/chunks/VarValidator.java
@@ -0,0 +1,93 @@
+package com.github.javaparser.ast.validator.chunks;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.NullLiteralExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.type.VarType;
+import com.github.javaparser.ast.validator.ProblemReporter;
+import com.github.javaparser.ast.validator.TypedValidator;
+
+import java.util.Optional;
+
+public class VarValidator implements TypedValidator<VarType> {
+    private boolean varAllowedInLambdaParameters;
+
+    public VarValidator(boolean varAllowedInLambdaParameters) {
+        this.varAllowedInLambdaParameters = varAllowedInLambdaParameters;
+    }
+
+    @Override
+    public void accept(VarType node, ProblemReporter reporter) {
+        // All allowed locations are within a VariableDeclaration inside a VariableDeclarationExpr inside something else.
+        Optional<VariableDeclarator> variableDeclarator = node.findParent(VariableDeclarator.class);
+        if (!variableDeclarator.isPresent()) {
+            // Java 11's var in lambda's
+            if (varAllowedInLambdaParameters) {
+                boolean valid = node
+                        .findParent(Parameter.class)
+                        .flatMap(Node::getParentNode)
+                        .map((Node p) -> p instanceof LambdaExpr).orElse(false);
+                if (valid) {
+                    return;
+                }
+            }
+            reportIllegalPosition(node, reporter);
+            return;
+        }
+        variableDeclarator.ifPresent(vd -> {
+            Optional<Node> variableDeclarationExpr = vd.getParentNode();
+            if (!variableDeclarationExpr.isPresent()) {
+                reportIllegalPosition(node, reporter);
+                return;
+            }
+            variableDeclarationExpr.ifPresent(vdeNode -> {
+                if (!(vdeNode instanceof VariableDeclarationExpr)) {
+                    reportIllegalPosition(node, reporter);
+                    return;
+                }
+                VariableDeclarationExpr vde = (VariableDeclarationExpr) vdeNode;
+                if (vde.getVariables().size() > 1) {
+                    reporter.report(vde, "\"var\" only takes a single variable.");
+                }
+                Optional<Node> container = vdeNode.getParentNode();
+                if (!container.isPresent()) {
+                    reportIllegalPosition(node, reporter);
+                    return;
+                }
+                container.ifPresent(c -> {
+                    boolean positionIsFine = c instanceof ForStmt || c instanceof ForeachStmt || c instanceof ExpressionStmt;
+                    if (!positionIsFine) {
+                        reportIllegalPosition(node, reporter);
+                    }
+                    // A local variable declaration ends up inside an ExpressionStmt.
+                    if (c instanceof ExpressionStmt) {
+                        if (!vd.getInitializer().isPresent()) {
+                            reporter.report(node, "\"var\" needs an initializer.");
+                        }
+                        vd.getInitializer().ifPresent(initializer -> {
+                            if (initializer instanceof NullLiteralExpr) {
+                                reporter.report(node, "\"var\" cannot infer type from just null.");
+                            }
+                            if (initializer instanceof ArrayCreationExpr) {
+                                reporter.report(node, "\"var\" cannot infer array types.");
+                            }
+                        });
+
+                    }
+                });
+            });
+        });
+
+    }
+
+    private void reportIllegalPosition(VarType n, ProblemReporter reporter) {
+        reporter.report(n, "\"var\" is not allowed here.");
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
new file mode 100644
index 0000000..4ae343a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/CloneVisitor.java
@@ -0,0 +1,1080 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import java.util.Optional;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that clones (copies) a node and all its children.
+ */
+public class CloneVisitor implements GenericVisitor<Visitable, Object> {
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final CompilationUnit n, final Object arg) {
+        NodeList<ImportDeclaration> imports = cloneList(n.getImports(), arg);
+        ModuleDeclaration module = cloneNode(n.getModule(), arg);
+        PackageDeclaration packageDeclaration = cloneNode(n.getPackageDeclaration(), arg);
+        NodeList<TypeDeclaration<?>> types = cloneList(n.getTypes(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        CompilationUnit r = new CompilationUnit(n.getTokenRange().orElse(null), packageDeclaration, imports, types, module);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final PackageDeclaration n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        PackageDeclaration r = new PackageDeclaration(n.getTokenRange().orElse(null), annotations, name);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final TypeParameter n, final Object arg) {
+        SimpleName name = cloneNode(n.getName(), arg);
+        NodeList<ClassOrInterfaceType> typeBound = cloneList(n.getTypeBound(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        TypeParameter r = new TypeParameter(n.getTokenRange().orElse(null), name, typeBound, annotations);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final LineComment n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        LineComment r = new LineComment(n.getTokenRange().orElse(null), n.getContent());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final BlockComment n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        BlockComment r = new BlockComment(n.getTokenRange().orElse(null), n.getContent());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ClassOrInterfaceDeclaration n, final Object arg) {
+        NodeList<ClassOrInterfaceType> extendedTypes = cloneList(n.getExtendedTypes(), arg);
+        NodeList<ClassOrInterfaceType> implementedTypes = cloneList(n.getImplementedTypes(), arg);
+        NodeList<TypeParameter> typeParameters = cloneList(n.getTypeParameters(), arg);
+        NodeList<BodyDeclaration<?>> members = cloneList(n.getMembers(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ClassOrInterfaceDeclaration r = new ClassOrInterfaceDeclaration(n.getTokenRange().orElse(null), n.getModifiers(), annotations, n.isInterface(), name, typeParameters, extendedTypes, implementedTypes, members);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final EnumDeclaration n, final Object arg) {
+        NodeList<EnumConstantDeclaration> entries = cloneList(n.getEntries(), arg);
+        NodeList<ClassOrInterfaceType> implementedTypes = cloneList(n.getImplementedTypes(), arg);
+        NodeList<BodyDeclaration<?>> members = cloneList(n.getMembers(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        EnumDeclaration r = new EnumDeclaration(n.getTokenRange().orElse(null), n.getModifiers(), annotations, name, implementedTypes, entries, members);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final EnumConstantDeclaration n, final Object arg) {
+        NodeList<Expression> arguments = cloneList(n.getArguments(), arg);
+        NodeList<BodyDeclaration<?>> classBody = cloneList(n.getClassBody(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        EnumConstantDeclaration r = new EnumConstantDeclaration(n.getTokenRange().orElse(null), annotations, name, arguments, classBody);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final AnnotationDeclaration n, final Object arg) {
+        NodeList<BodyDeclaration<?>> members = cloneList(n.getMembers(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        AnnotationDeclaration r = new AnnotationDeclaration(n.getTokenRange().orElse(null), n.getModifiers(), annotations, name, members);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final AnnotationMemberDeclaration n, final Object arg) {
+        Expression defaultValue = cloneNode(n.getDefaultValue(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        Type type = cloneNode(n.getType(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        AnnotationMemberDeclaration r = new AnnotationMemberDeclaration(n.getTokenRange().orElse(null), n.getModifiers(), annotations, type, name, defaultValue);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final FieldDeclaration n, final Object arg) {
+        NodeList<VariableDeclarator> variables = cloneList(n.getVariables(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        FieldDeclaration r = new FieldDeclaration(n.getTokenRange().orElse(null), n.getModifiers(), annotations, variables);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final VariableDeclarator n, final Object arg) {
+        Expression initializer = cloneNode(n.getInitializer(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        Type type = cloneNode(n.getType(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        VariableDeclarator r = new VariableDeclarator(n.getTokenRange().orElse(null), type, name, initializer);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ConstructorDeclaration n, final Object arg) {
+        BlockStmt body = cloneNode(n.getBody(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        NodeList<Parameter> parameters = cloneList(n.getParameters(), arg);
+        ReceiverParameter receiverParameter = cloneNode(n.getReceiverParameter(), arg);
+        NodeList<ReferenceType> thrownExceptions = cloneList(n.getThrownExceptions(), arg);
+        NodeList<TypeParameter> typeParameters = cloneList(n.getTypeParameters(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ConstructorDeclaration r = new ConstructorDeclaration(n.getTokenRange().orElse(null), n.getModifiers(), annotations, typeParameters, name, parameters, thrownExceptions, body, receiverParameter);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final MethodDeclaration n, final Object arg) {
+        BlockStmt body = cloneNode(n.getBody(), arg);
+        Type type = cloneNode(n.getType(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        NodeList<Parameter> parameters = cloneList(n.getParameters(), arg);
+        ReceiverParameter receiverParameter = cloneNode(n.getReceiverParameter(), arg);
+        NodeList<ReferenceType> thrownExceptions = cloneList(n.getThrownExceptions(), arg);
+        NodeList<TypeParameter> typeParameters = cloneList(n.getTypeParameters(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        MethodDeclaration r = new MethodDeclaration(n.getTokenRange().orElse(null), n.getModifiers(), annotations, typeParameters, type, name, parameters, thrownExceptions, body, receiverParameter);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final Parameter n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        Type type = cloneNode(n.getType(), arg);
+        NodeList<AnnotationExpr> varArgsAnnotations = cloneList(n.getVarArgsAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        Parameter r = new Parameter(n.getTokenRange().orElse(null), n.getModifiers(), annotations, type, n.isVarArgs(), varArgsAnnotations, name);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final InitializerDeclaration n, final Object arg) {
+        BlockStmt body = cloneNode(n.getBody(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        InitializerDeclaration r = new InitializerDeclaration(n.getTokenRange().orElse(null), n.isStatic(), body);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final JavadocComment n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        JavadocComment r = new JavadocComment(n.getTokenRange().orElse(null), n.getContent());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ClassOrInterfaceType n, final Object arg) {
+        SimpleName name = cloneNode(n.getName(), arg);
+        ClassOrInterfaceType scope = cloneNode(n.getScope(), arg);
+        NodeList<Type> typeArguments = cloneList(n.getTypeArguments().orElse(null), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ClassOrInterfaceType r = new ClassOrInterfaceType(n.getTokenRange().orElse(null), scope, name, typeArguments, annotations);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final PrimitiveType n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        PrimitiveType r = new PrimitiveType(n.getTokenRange().orElse(null), n.getType(), annotations);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ArrayType n, final Object arg) {
+        Type componentType = cloneNode(n.getComponentType(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ArrayType r = new ArrayType(n.getTokenRange().orElse(null), componentType, n.getOrigin(), annotations);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ArrayCreationLevel n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Expression dimension = cloneNode(n.getDimension(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ArrayCreationLevel r = new ArrayCreationLevel(n.getTokenRange().orElse(null), dimension, annotations);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final IntersectionType n, final Object arg) {
+        NodeList<ReferenceType> elements = cloneList(n.getElements(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        IntersectionType r = new IntersectionType(n.getTokenRange().orElse(null), elements);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final UnionType n, final Object arg) {
+        NodeList<ReferenceType> elements = cloneList(n.getElements(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        UnionType r = new UnionType(n.getTokenRange().orElse(null), elements);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final VoidType n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        VoidType r = new VoidType(n.getTokenRange().orElse(null));
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final WildcardType n, final Object arg) {
+        ReferenceType extendedType = cloneNode(n.getExtendedType(), arg);
+        ReferenceType superType = cloneNode(n.getSuperType(), arg);
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        WildcardType r = new WildcardType(n.getTokenRange().orElse(null), extendedType, superType, annotations);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final UnknownType n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        UnknownType r = new UnknownType(n.getTokenRange().orElse(null));
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ArrayAccessExpr n, final Object arg) {
+        Expression index = cloneNode(n.getIndex(), arg);
+        Expression name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ArrayAccessExpr r = new ArrayAccessExpr(n.getTokenRange().orElse(null), name, index);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ArrayCreationExpr n, final Object arg) {
+        Type elementType = cloneNode(n.getElementType(), arg);
+        ArrayInitializerExpr initializer = cloneNode(n.getInitializer(), arg);
+        NodeList<ArrayCreationLevel> levels = cloneList(n.getLevels(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ArrayCreationExpr r = new ArrayCreationExpr(n.getTokenRange().orElse(null), elementType, levels, initializer);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ArrayInitializerExpr n, final Object arg) {
+        NodeList<Expression> values = cloneList(n.getValues(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ArrayInitializerExpr r = new ArrayInitializerExpr(n.getTokenRange().orElse(null), values);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final AssignExpr n, final Object arg) {
+        Expression target = cloneNode(n.getTarget(), arg);
+        Expression value = cloneNode(n.getValue(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        AssignExpr r = new AssignExpr(n.getTokenRange().orElse(null), target, value, n.getOperator());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final BinaryExpr n, final Object arg) {
+        Expression left = cloneNode(n.getLeft(), arg);
+        Expression right = cloneNode(n.getRight(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        BinaryExpr r = new BinaryExpr(n.getTokenRange().orElse(null), left, right, n.getOperator());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final CastExpr n, final Object arg) {
+        Expression expression = cloneNode(n.getExpression(), arg);
+        Type type = cloneNode(n.getType(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        CastExpr r = new CastExpr(n.getTokenRange().orElse(null), type, expression);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ClassExpr n, final Object arg) {
+        Type type = cloneNode(n.getType(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ClassExpr r = new ClassExpr(n.getTokenRange().orElse(null), type);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ConditionalExpr n, final Object arg) {
+        Expression condition = cloneNode(n.getCondition(), arg);
+        Expression elseExpr = cloneNode(n.getElseExpr(), arg);
+        Expression thenExpr = cloneNode(n.getThenExpr(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ConditionalExpr r = new ConditionalExpr(n.getTokenRange().orElse(null), condition, thenExpr, elseExpr);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final EnclosedExpr n, final Object arg) {
+        Expression inner = cloneNode(n.getInner(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        EnclosedExpr r = new EnclosedExpr(n.getTokenRange().orElse(null), inner);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final FieldAccessExpr n, final Object arg) {
+        SimpleName name = cloneNode(n.getName(), arg);
+        Expression scope = cloneNode(n.getScope(), arg);
+        NodeList<Type> typeArguments = cloneList(n.getTypeArguments().orElse(null), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        FieldAccessExpr r = new FieldAccessExpr(n.getTokenRange().orElse(null), scope, typeArguments, name);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final InstanceOfExpr n, final Object arg) {
+        Expression expression = cloneNode(n.getExpression(), arg);
+        ReferenceType type = cloneNode(n.getType(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        InstanceOfExpr r = new InstanceOfExpr(n.getTokenRange().orElse(null), expression, type);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final StringLiteralExpr n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        StringLiteralExpr r = new StringLiteralExpr(n.getTokenRange().orElse(null), n.getValue());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final IntegerLiteralExpr n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        IntegerLiteralExpr r = new IntegerLiteralExpr(n.getTokenRange().orElse(null), n.getValue());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final LongLiteralExpr n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        LongLiteralExpr r = new LongLiteralExpr(n.getTokenRange().orElse(null), n.getValue());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final CharLiteralExpr n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        CharLiteralExpr r = new CharLiteralExpr(n.getTokenRange().orElse(null), n.getValue());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final DoubleLiteralExpr n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        DoubleLiteralExpr r = new DoubleLiteralExpr(n.getTokenRange().orElse(null), n.getValue());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final BooleanLiteralExpr n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        BooleanLiteralExpr r = new BooleanLiteralExpr(n.getTokenRange().orElse(null), n.getValue());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final NullLiteralExpr n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        NullLiteralExpr r = new NullLiteralExpr(n.getTokenRange().orElse(null));
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final MethodCallExpr n, final Object arg) {
+        NodeList<Expression> arguments = cloneList(n.getArguments(), arg);
+        SimpleName name = cloneNode(n.getName(), arg);
+        Expression scope = cloneNode(n.getScope(), arg);
+        NodeList<Type> typeArguments = cloneList(n.getTypeArguments().orElse(null), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        MethodCallExpr r = new MethodCallExpr(n.getTokenRange().orElse(null), scope, typeArguments, name, arguments);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final NameExpr n, final Object arg) {
+        SimpleName name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        NameExpr r = new NameExpr(n.getTokenRange().orElse(null), name);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ObjectCreationExpr n, final Object arg) {
+        NodeList<BodyDeclaration<?>> anonymousClassBody = cloneList(n.getAnonymousClassBody().orElse(null), arg);
+        NodeList<Expression> arguments = cloneList(n.getArguments(), arg);
+        Expression scope = cloneNode(n.getScope(), arg);
+        ClassOrInterfaceType type = cloneNode(n.getType(), arg);
+        NodeList<Type> typeArguments = cloneList(n.getTypeArguments().orElse(null), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ObjectCreationExpr r = new ObjectCreationExpr(n.getTokenRange().orElse(null), scope, type, typeArguments, arguments, anonymousClassBody);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final Name n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Name qualifier = cloneNode(n.getQualifier(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        Name r = new Name(n.getTokenRange().orElse(null), qualifier, n.getIdentifier(), annotations);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final SimpleName n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        SimpleName r = new SimpleName(n.getTokenRange().orElse(null), n.getIdentifier());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ThisExpr n, final Object arg) {
+        Expression classExpr = cloneNode(n.getClassExpr(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ThisExpr r = new ThisExpr(n.getTokenRange().orElse(null), classExpr);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final SuperExpr n, final Object arg) {
+        Expression classExpr = cloneNode(n.getClassExpr(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        SuperExpr r = new SuperExpr(n.getTokenRange().orElse(null), classExpr);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final UnaryExpr n, final Object arg) {
+        Expression expression = cloneNode(n.getExpression(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        UnaryExpr r = new UnaryExpr(n.getTokenRange().orElse(null), expression, n.getOperator());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final VariableDeclarationExpr n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        NodeList<VariableDeclarator> variables = cloneList(n.getVariables(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        VariableDeclarationExpr r = new VariableDeclarationExpr(n.getTokenRange().orElse(null), n.getModifiers(), annotations, variables);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final MarkerAnnotationExpr n, final Object arg) {
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        MarkerAnnotationExpr r = new MarkerAnnotationExpr(n.getTokenRange().orElse(null), name);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final SingleMemberAnnotationExpr n, final Object arg) {
+        Expression memberValue = cloneNode(n.getMemberValue(), arg);
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        SingleMemberAnnotationExpr r = new SingleMemberAnnotationExpr(n.getTokenRange().orElse(null), name, memberValue);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final NormalAnnotationExpr n, final Object arg) {
+        NodeList<MemberValuePair> pairs = cloneList(n.getPairs(), arg);
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        NormalAnnotationExpr r = new NormalAnnotationExpr(n.getTokenRange().orElse(null), name, pairs);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final MemberValuePair n, final Object arg) {
+        SimpleName name = cloneNode(n.getName(), arg);
+        Expression value = cloneNode(n.getValue(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        MemberValuePair r = new MemberValuePair(n.getTokenRange().orElse(null), name, value);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ExplicitConstructorInvocationStmt n, final Object arg) {
+        NodeList<Expression> arguments = cloneList(n.getArguments(), arg);
+        Expression expression = cloneNode(n.getExpression(), arg);
+        NodeList<Type> typeArguments = cloneList(n.getTypeArguments().orElse(null), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ExplicitConstructorInvocationStmt r = new ExplicitConstructorInvocationStmt(n.getTokenRange().orElse(null), typeArguments, n.isThis(), expression, arguments);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final LocalClassDeclarationStmt n, final Object arg) {
+        ClassOrInterfaceDeclaration classDeclaration = cloneNode(n.getClassDeclaration(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        LocalClassDeclarationStmt r = new LocalClassDeclarationStmt(n.getTokenRange().orElse(null), classDeclaration);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final AssertStmt n, final Object arg) {
+        Expression check = cloneNode(n.getCheck(), arg);
+        Expression message = cloneNode(n.getMessage(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        AssertStmt r = new AssertStmt(n.getTokenRange().orElse(null), check, message);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final BlockStmt n, final Object arg) {
+        NodeList<Statement> statements = cloneList(n.getStatements(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        BlockStmt r = new BlockStmt(n.getTokenRange().orElse(null), statements);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final LabeledStmt n, final Object arg) {
+        SimpleName label = cloneNode(n.getLabel(), arg);
+        Statement statement = cloneNode(n.getStatement(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        LabeledStmt r = new LabeledStmt(n.getTokenRange().orElse(null), label, statement);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final EmptyStmt n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        EmptyStmt r = new EmptyStmt(n.getTokenRange().orElse(null));
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ExpressionStmt n, final Object arg) {
+        Expression expression = cloneNode(n.getExpression(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ExpressionStmt r = new ExpressionStmt(n.getTokenRange().orElse(null), expression);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final SwitchStmt n, final Object arg) {
+        NodeList<SwitchEntryStmt> entries = cloneList(n.getEntries(), arg);
+        Expression selector = cloneNode(n.getSelector(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        SwitchStmt r = new SwitchStmt(n.getTokenRange().orElse(null), selector, entries);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final SwitchEntryStmt n, final Object arg) {
+        Expression label = cloneNode(n.getLabel(), arg);
+        NodeList<Statement> statements = cloneList(n.getStatements(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        SwitchEntryStmt r = new SwitchEntryStmt(n.getTokenRange().orElse(null), label, statements);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final BreakStmt n, final Object arg) {
+        SimpleName label = cloneNode(n.getLabel(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        BreakStmt r = new BreakStmt(n.getTokenRange().orElse(null), label);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ReturnStmt n, final Object arg) {
+        Expression expression = cloneNode(n.getExpression(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ReturnStmt r = new ReturnStmt(n.getTokenRange().orElse(null), expression);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final IfStmt n, final Object arg) {
+        Expression condition = cloneNode(n.getCondition(), arg);
+        Statement elseStmt = cloneNode(n.getElseStmt(), arg);
+        Statement thenStmt = cloneNode(n.getThenStmt(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        IfStmt r = new IfStmt(n.getTokenRange().orElse(null), condition, thenStmt, elseStmt);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final WhileStmt n, final Object arg) {
+        Statement body = cloneNode(n.getBody(), arg);
+        Expression condition = cloneNode(n.getCondition(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        WhileStmt r = new WhileStmt(n.getTokenRange().orElse(null), condition, body);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ContinueStmt n, final Object arg) {
+        SimpleName label = cloneNode(n.getLabel(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ContinueStmt r = new ContinueStmt(n.getTokenRange().orElse(null), label);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final DoStmt n, final Object arg) {
+        Statement body = cloneNode(n.getBody(), arg);
+        Expression condition = cloneNode(n.getCondition(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        DoStmt r = new DoStmt(n.getTokenRange().orElse(null), body, condition);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ForeachStmt n, final Object arg) {
+        Statement body = cloneNode(n.getBody(), arg);
+        Expression iterable = cloneNode(n.getIterable(), arg);
+        VariableDeclarationExpr variable = cloneNode(n.getVariable(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ForeachStmt r = new ForeachStmt(n.getTokenRange().orElse(null), variable, iterable, body);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ForStmt n, final Object arg) {
+        Statement body = cloneNode(n.getBody(), arg);
+        Expression compare = cloneNode(n.getCompare(), arg);
+        NodeList<Expression> initialization = cloneList(n.getInitialization(), arg);
+        NodeList<Expression> update = cloneList(n.getUpdate(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ForStmt r = new ForStmt(n.getTokenRange().orElse(null), initialization, compare, update, body);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ThrowStmt n, final Object arg) {
+        Expression expression = cloneNode(n.getExpression(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ThrowStmt r = new ThrowStmt(n.getTokenRange().orElse(null), expression);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final SynchronizedStmt n, final Object arg) {
+        BlockStmt body = cloneNode(n.getBody(), arg);
+        Expression expression = cloneNode(n.getExpression(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        SynchronizedStmt r = new SynchronizedStmt(n.getTokenRange().orElse(null), expression, body);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final TryStmt n, final Object arg) {
+        NodeList<CatchClause> catchClauses = cloneList(n.getCatchClauses(), arg);
+        BlockStmt finallyBlock = cloneNode(n.getFinallyBlock(), arg);
+        NodeList<Expression> resources = cloneList(n.getResources(), arg);
+        BlockStmt tryBlock = cloneNode(n.getTryBlock(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        TryStmt r = new TryStmt(n.getTokenRange().orElse(null), resources, tryBlock, catchClauses, finallyBlock);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final CatchClause n, final Object arg) {
+        BlockStmt body = cloneNode(n.getBody(), arg);
+        Parameter parameter = cloneNode(n.getParameter(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        CatchClause r = new CatchClause(n.getTokenRange().orElse(null), parameter, body);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final LambdaExpr n, final Object arg) {
+        Statement body = cloneNode(n.getBody(), arg);
+        NodeList<Parameter> parameters = cloneList(n.getParameters(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        LambdaExpr r = new LambdaExpr(n.getTokenRange().orElse(null), parameters, body, n.isEnclosingParameters());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final MethodReferenceExpr n, final Object arg) {
+        Expression scope = cloneNode(n.getScope(), arg);
+        NodeList<Type> typeArguments = cloneList(n.getTypeArguments().orElse(null), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        MethodReferenceExpr r = new MethodReferenceExpr(n.getTokenRange().orElse(null), scope, typeArguments, n.getIdentifier());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final TypeExpr n, final Object arg) {
+        Type type = cloneNode(n.getType(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        TypeExpr r = new TypeExpr(n.getTokenRange().orElse(null), type);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    public Visitable visit(NodeList n, Object arg) {
+        NodeList<Node> newNodes = new NodeList<>();
+        for (Object node : n) {
+            Node resultNode = (Node) ((Node) node).accept(this, arg);
+            if (resultNode != null) {
+                newNodes.add(resultNode);
+            }
+        }
+        return newNodes;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Node visit(final ImportDeclaration n, final Object arg) {
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ImportDeclaration r = new ImportDeclaration(n.getTokenRange().orElse(null), name, n.isStatic(), n.isAsterisk());
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ModuleDeclaration n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        NodeList<ModuleStmt> moduleStmts = cloneList(n.getModuleStmts(), arg);
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ModuleDeclaration r = new ModuleDeclaration(n.getTokenRange().orElse(null), annotations, name, n.isOpen(), moduleStmts);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ModuleRequiresStmt n, final Object arg) {
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ModuleRequiresStmt r = new ModuleRequiresStmt(n.getTokenRange().orElse(null), n.getModifiers(), name);
+        r.setComment(comment);
+        return r;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <T extends Node> T cloneNode(Optional<T> node, Object arg) {
+        if (!node.isPresent()) {
+            return null;
+        }
+        Node r = (Node) node.get().accept(this, arg);
+        if (r == null) {
+            return null;
+        }
+        return (T) r;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <T extends Node> T cloneNode(T node, Object arg) {
+        if (node == null) {
+            return null;
+        }
+        Node r = (Node) node.accept(this, arg);
+        if (r == null) {
+            return null;
+        }
+        return (T) r;
+    }
+
+    private <N extends Node> NodeList<N> cloneList(NodeList<N> list, Object arg) {
+        if (list == null) {
+            return null;
+        }
+        return (NodeList<N>) list.accept(this, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ModuleExportsStmt n, final Object arg) {
+        NodeList<Name> moduleNames = cloneList(n.getModuleNames(), arg);
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ModuleExportsStmt r = new ModuleExportsStmt(n.getTokenRange().orElse(null), name, moduleNames);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ModuleProvidesStmt n, final Object arg) {
+        Type type = cloneNode(n.getType(), arg);
+        NodeList<Type> withTypes = cloneList(n.getWithTypes(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ModuleProvidesStmt r = new ModuleProvidesStmt(n.getTokenRange().orElse(null), type, withTypes);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ModuleUsesStmt n, final Object arg) {
+        Type type = cloneNode(n.getType(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ModuleUsesStmt r = new ModuleUsesStmt(n.getTokenRange().orElse(null), type);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ModuleOpensStmt n, final Object arg) {
+        NodeList<Name> moduleNames = cloneList(n.getModuleNames(), arg);
+        Name name = cloneNode(n.getName(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ModuleOpensStmt r = new ModuleOpensStmt(n.getTokenRange().orElse(null), name, moduleNames);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final UnparsableStmt n, final Object arg) {
+        Comment comment = cloneNode(n.getComment(), arg);
+        UnparsableStmt r = new UnparsableStmt(n.getTokenRange().orElse(null));
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.CloneVisitorGenerator")
+    public Visitable visit(final ReceiverParameter n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Name name = cloneNode(n.getName(), arg);
+        Type type = cloneNode(n.getType(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        ReceiverParameter r = new ReceiverParameter(n.getTokenRange().orElse(null), annotations, type, name);
+        r.setComment(comment);
+        return r;
+    }
+
+    @Override
+    public Visitable visit(final VarType n, final Object arg) {
+        NodeList<AnnotationExpr> annotations = cloneList(n.getAnnotations(), arg);
+        Comment comment = cloneNode(n.getComment(), arg);
+        VarType r = new VarType(n.getTokenRange().orElse(null));
+        r.setComment(comment);
+        return r;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java
new file mode 100644
index 0000000..2062185
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/EqualsVisitor.java
@@ -0,0 +1,1389 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import java.util.List;
+import java.util.Optional;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that calculates deep node equality by comparing all properties and child nodes of the node.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public class EqualsVisitor implements GenericVisitor<Boolean, Visitable> {
+
+    private static final EqualsVisitor SINGLETON = new EqualsVisitor();
+
+    public static boolean equals(final Node n, final Node n2) {
+        return SINGLETON.nodeEquals(n, n2);
+    }
+
+    private EqualsVisitor() {
+    // hide constructor
+    }
+
+    /**
+     * Check for equality that can be applied to each kind of node,
+     * to not repeat it in every method we store that here.
+     */
+    private boolean commonNodeEquality(Node n, Node n2) {
+        if (!nodeEquals(n.getComment(), n2.getComment())) {
+            return false;
+        }
+        return nodesEquals(n.getOrphanComments(), n2.getOrphanComments());
+    }
+
+    private <T extends Node> boolean nodesEquals(final List<T> nodes1, final List<T> nodes2) {
+        if (nodes1 == null) {
+            return nodes2 == null;
+        } else if (nodes2 == null) {
+            return false;
+        }
+        if (nodes1.size() != nodes2.size()) {
+            return false;
+        }
+        for (int i = 0; i < nodes1.size(); i++) {
+            if (!nodeEquals(nodes1.get(i), nodes2.get(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private <N extends Node> boolean nodesEquals(NodeList<N> n, NodeList<N> n2) {
+        if (n == n2) {
+            return true;
+        }
+        if (n == null || n2 == null) {
+            return false;
+        }
+        if (n.size() != n2.size()) {
+            return false;
+        }
+        for (int i = 0; i < n.size(); i++) {
+            if (!nodeEquals(n.get(i), n2.get(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private <T extends Node> boolean nodeEquals(final T n, final T n2) {
+        if (n == n2) {
+            return true;
+        }
+        if (n == null || n2 == null) {
+            return false;
+        }
+        if (n.getClass() != n2.getClass()) {
+            return false;
+        }
+        if (!commonNodeEquality(n, n2)) {
+            return false;
+        }
+        return n.accept(this, n2);
+    }
+
+    private <T extends Node> boolean nodeEquals(final Optional<T> n, final Optional<T> n2) {
+        return nodeEquals(n.orElse(null), n2.orElse(null));
+    }
+
+    private <T extends Node> boolean nodesEquals(final Optional<NodeList<T>> n, final Optional<NodeList<T>> n2) {
+        return nodesEquals(n.orElse(null), n2.orElse(null));
+    }
+
+    private boolean objEquals(final Object n, final Object n2) {
+        if (n == n2) {
+            return true;
+        }
+        if (n == null || n2 == null) {
+            return false;
+        }
+        return n.equals(n2);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final CompilationUnit n, final Visitable arg) {
+        final CompilationUnit n2 = (CompilationUnit) arg;
+        if (!nodesEquals(n.getImports(), n2.getImports()))
+            return false;
+        if (!nodeEquals(n.getModule(), n2.getModule()))
+            return false;
+        if (!nodeEquals(n.getPackageDeclaration(), n2.getPackageDeclaration()))
+            return false;
+        if (!nodesEquals(n.getTypes(), n2.getTypes()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final PackageDeclaration n, final Visitable arg) {
+        final PackageDeclaration n2 = (PackageDeclaration) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final TypeParameter n, final Visitable arg) {
+        final TypeParameter n2 = (TypeParameter) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getTypeBound(), n2.getTypeBound()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final LineComment n, final Visitable arg) {
+        final LineComment n2 = (LineComment) arg;
+        if (!objEquals(n.getContent(), n2.getContent()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final BlockComment n, final Visitable arg) {
+        final BlockComment n2 = (BlockComment) arg;
+        if (!objEquals(n.getContent(), n2.getContent()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ClassOrInterfaceDeclaration n, final Visitable arg) {
+        final ClassOrInterfaceDeclaration n2 = (ClassOrInterfaceDeclaration) arg;
+        if (!nodesEquals(n.getExtendedTypes(), n2.getExtendedTypes()))
+            return false;
+        if (!nodesEquals(n.getImplementedTypes(), n2.getImplementedTypes()))
+            return false;
+        if (!objEquals(n.isInterface(), n2.isInterface()))
+            return false;
+        if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters()))
+            return false;
+        if (!nodesEquals(n.getMembers(), n2.getMembers()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final EnumDeclaration n, final Visitable arg) {
+        final EnumDeclaration n2 = (EnumDeclaration) arg;
+        if (!nodesEquals(n.getEntries(), n2.getEntries()))
+            return false;
+        if (!nodesEquals(n.getImplementedTypes(), n2.getImplementedTypes()))
+            return false;
+        if (!nodesEquals(n.getMembers(), n2.getMembers()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final EnumConstantDeclaration n, final Visitable arg) {
+        final EnumConstantDeclaration n2 = (EnumConstantDeclaration) arg;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodesEquals(n.getClassBody(), n2.getClassBody()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final AnnotationDeclaration n, final Visitable arg) {
+        final AnnotationDeclaration n2 = (AnnotationDeclaration) arg;
+        if (!nodesEquals(n.getMembers(), n2.getMembers()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final AnnotationMemberDeclaration n, final Visitable arg) {
+        final AnnotationMemberDeclaration n2 = (AnnotationMemberDeclaration) arg;
+        if (!nodeEquals(n.getDefaultValue(), n2.getDefaultValue()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final FieldDeclaration n, final Visitable arg) {
+        final FieldDeclaration n2 = (FieldDeclaration) arg;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodesEquals(n.getVariables(), n2.getVariables()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final VariableDeclarator n, final Visitable arg) {
+        final VariableDeclarator n2 = (VariableDeclarator) arg;
+        if (!nodeEquals(n.getInitializer(), n2.getInitializer()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ConstructorDeclaration n, final Visitable arg) {
+        final ConstructorDeclaration n2 = (ConstructorDeclaration) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getParameters(), n2.getParameters()))
+            return false;
+        if (!nodeEquals(n.getReceiverParameter(), n2.getReceiverParameter()))
+            return false;
+        if (!nodesEquals(n.getThrownExceptions(), n2.getThrownExceptions()))
+            return false;
+        if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final MethodDeclaration n, final Visitable arg) {
+        final MethodDeclaration n2 = (MethodDeclaration) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getParameters(), n2.getParameters()))
+            return false;
+        if (!nodeEquals(n.getReceiverParameter(), n2.getReceiverParameter()))
+            return false;
+        if (!nodesEquals(n.getThrownExceptions(), n2.getThrownExceptions()))
+            return false;
+        if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final Parameter n, final Visitable arg) {
+        final Parameter n2 = (Parameter) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.isVarArgs(), n2.isVarArgs()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getVarArgsAnnotations(), n2.getVarArgsAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final InitializerDeclaration n, final Visitable arg) {
+        final InitializerDeclaration n2 = (InitializerDeclaration) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!objEquals(n.isStatic(), n2.isStatic()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final JavadocComment n, final Visitable arg) {
+        final JavadocComment n2 = (JavadocComment) arg;
+        if (!objEquals(n.getContent(), n2.getContent()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ClassOrInterfaceType n, final Visitable arg) {
+        final ClassOrInterfaceType n2 = (ClassOrInterfaceType) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final PrimitiveType n, final Visitable arg) {
+        final PrimitiveType n2 = (PrimitiveType) arg;
+        if (!objEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ArrayType n, final Visitable arg) {
+        final ArrayType n2 = (ArrayType) arg;
+        if (!nodeEquals(n.getComponentType(), n2.getComponentType()))
+            return false;
+        if (!objEquals(n.getOrigin(), n2.getOrigin()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ArrayCreationLevel n, final Visitable arg) {
+        final ArrayCreationLevel n2 = (ArrayCreationLevel) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getDimension(), n2.getDimension()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final IntersectionType n, final Visitable arg) {
+        final IntersectionType n2 = (IntersectionType) arg;
+        if (!nodesEquals(n.getElements(), n2.getElements()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final UnionType n, final Visitable arg) {
+        final UnionType n2 = (UnionType) arg;
+        if (!nodesEquals(n.getElements(), n2.getElements()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final VoidType n, final Visitable arg) {
+        final VoidType n2 = (VoidType) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final WildcardType n, final Visitable arg) {
+        final WildcardType n2 = (WildcardType) arg;
+        if (!nodeEquals(n.getExtendedType(), n2.getExtendedType()))
+            return false;
+        if (!nodeEquals(n.getSuperType(), n2.getSuperType()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final UnknownType n, final Visitable arg) {
+        final UnknownType n2 = (UnknownType) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ArrayAccessExpr n, final Visitable arg) {
+        final ArrayAccessExpr n2 = (ArrayAccessExpr) arg;
+        if (!nodeEquals(n.getIndex(), n2.getIndex()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ArrayCreationExpr n, final Visitable arg) {
+        final ArrayCreationExpr n2 = (ArrayCreationExpr) arg;
+        if (!nodeEquals(n.getElementType(), n2.getElementType()))
+            return false;
+        if (!nodeEquals(n.getInitializer(), n2.getInitializer()))
+            return false;
+        if (!nodesEquals(n.getLevels(), n2.getLevels()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ArrayInitializerExpr n, final Visitable arg) {
+        final ArrayInitializerExpr n2 = (ArrayInitializerExpr) arg;
+        if (!nodesEquals(n.getValues(), n2.getValues()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final AssignExpr n, final Visitable arg) {
+        final AssignExpr n2 = (AssignExpr) arg;
+        if (!objEquals(n.getOperator(), n2.getOperator()))
+            return false;
+        if (!nodeEquals(n.getTarget(), n2.getTarget()))
+            return false;
+        if (!nodeEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final BinaryExpr n, final Visitable arg) {
+        final BinaryExpr n2 = (BinaryExpr) arg;
+        if (!nodeEquals(n.getLeft(), n2.getLeft()))
+            return false;
+        if (!objEquals(n.getOperator(), n2.getOperator()))
+            return false;
+        if (!nodeEquals(n.getRight(), n2.getRight()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final CastExpr n, final Visitable arg) {
+        final CastExpr n2 = (CastExpr) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ClassExpr n, final Visitable arg) {
+        final ClassExpr n2 = (ClassExpr) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ConditionalExpr n, final Visitable arg) {
+        final ConditionalExpr n2 = (ConditionalExpr) arg;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        if (!nodeEquals(n.getElseExpr(), n2.getElseExpr()))
+            return false;
+        if (!nodeEquals(n.getThenExpr(), n2.getThenExpr()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final EnclosedExpr n, final Visitable arg) {
+        final EnclosedExpr n2 = (EnclosedExpr) arg;
+        if (!nodeEquals(n.getInner(), n2.getInner()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final FieldAccessExpr n, final Visitable arg) {
+        final FieldAccessExpr n2 = (FieldAccessExpr) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final InstanceOfExpr n, final Visitable arg) {
+        final InstanceOfExpr n2 = (InstanceOfExpr) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final StringLiteralExpr n, final Visitable arg) {
+        final StringLiteralExpr n2 = (StringLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final IntegerLiteralExpr n, final Visitable arg) {
+        final IntegerLiteralExpr n2 = (IntegerLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final LongLiteralExpr n, final Visitable arg) {
+        final LongLiteralExpr n2 = (LongLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final CharLiteralExpr n, final Visitable arg) {
+        final CharLiteralExpr n2 = (CharLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final DoubleLiteralExpr n, final Visitable arg) {
+        final DoubleLiteralExpr n2 = (DoubleLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final BooleanLiteralExpr n, final Visitable arg) {
+        final BooleanLiteralExpr n2 = (BooleanLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final NullLiteralExpr n, final Visitable arg) {
+        final NullLiteralExpr n2 = (NullLiteralExpr) arg;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final MethodCallExpr n, final Visitable arg) {
+        final MethodCallExpr n2 = (MethodCallExpr) arg;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final NameExpr n, final Visitable arg) {
+        final NameExpr n2 = (NameExpr) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ObjectCreationExpr n, final Visitable arg) {
+        final ObjectCreationExpr n2 = (ObjectCreationExpr) arg;
+        if (!nodesEquals(n.getAnonymousClassBody(), n2.getAnonymousClassBody()))
+            return false;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final Name n, final Visitable arg) {
+        final Name n2 = (Name) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.getIdentifier(), n2.getIdentifier()))
+            return false;
+        if (!nodeEquals(n.getQualifier(), n2.getQualifier()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final SimpleName n, final Visitable arg) {
+        final SimpleName n2 = (SimpleName) arg;
+        if (!objEquals(n.getIdentifier(), n2.getIdentifier()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ThisExpr n, final Visitable arg) {
+        final ThisExpr n2 = (ThisExpr) arg;
+        if (!nodeEquals(n.getClassExpr(), n2.getClassExpr()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final SuperExpr n, final Visitable arg) {
+        final SuperExpr n2 = (SuperExpr) arg;
+        if (!nodeEquals(n.getClassExpr(), n2.getClassExpr()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final UnaryExpr n, final Visitable arg) {
+        final UnaryExpr n2 = (UnaryExpr) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!objEquals(n.getOperator(), n2.getOperator()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final VariableDeclarationExpr n, final Visitable arg) {
+        final VariableDeclarationExpr n2 = (VariableDeclarationExpr) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodesEquals(n.getVariables(), n2.getVariables()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final MarkerAnnotationExpr n, final Visitable arg) {
+        final MarkerAnnotationExpr n2 = (MarkerAnnotationExpr) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final SingleMemberAnnotationExpr n, final Visitable arg) {
+        final SingleMemberAnnotationExpr n2 = (SingleMemberAnnotationExpr) arg;
+        if (!nodeEquals(n.getMemberValue(), n2.getMemberValue()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final NormalAnnotationExpr n, final Visitable arg) {
+        final NormalAnnotationExpr n2 = (NormalAnnotationExpr) arg;
+        if (!nodesEquals(n.getPairs(), n2.getPairs()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final MemberValuePair n, final Visitable arg) {
+        final MemberValuePair n2 = (MemberValuePair) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getValue(), n2.getValue()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ExplicitConstructorInvocationStmt n, final Visitable arg) {
+        final ExplicitConstructorInvocationStmt n2 = (ExplicitConstructorInvocationStmt) arg;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!objEquals(n.isThis(), n2.isThis()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final LocalClassDeclarationStmt n, final Visitable arg) {
+        final LocalClassDeclarationStmt n2 = (LocalClassDeclarationStmt) arg;
+        if (!nodeEquals(n.getClassDeclaration(), n2.getClassDeclaration()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final AssertStmt n, final Visitable arg) {
+        final AssertStmt n2 = (AssertStmt) arg;
+        if (!nodeEquals(n.getCheck(), n2.getCheck()))
+            return false;
+        if (!nodeEquals(n.getMessage(), n2.getMessage()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final BlockStmt n, final Visitable arg) {
+        final BlockStmt n2 = (BlockStmt) arg;
+        if (!nodesEquals(n.getStatements(), n2.getStatements()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final LabeledStmt n, final Visitable arg) {
+        final LabeledStmt n2 = (LabeledStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        if (!nodeEquals(n.getStatement(), n2.getStatement()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final EmptyStmt n, final Visitable arg) {
+        final EmptyStmt n2 = (EmptyStmt) arg;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ExpressionStmt n, final Visitable arg) {
+        final ExpressionStmt n2 = (ExpressionStmt) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final SwitchStmt n, final Visitable arg) {
+        final SwitchStmt n2 = (SwitchStmt) arg;
+        if (!nodesEquals(n.getEntries(), n2.getEntries()))
+            return false;
+        if (!nodeEquals(n.getSelector(), n2.getSelector()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final SwitchEntryStmt n, final Visitable arg) {
+        final SwitchEntryStmt n2 = (SwitchEntryStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        if (!nodesEquals(n.getStatements(), n2.getStatements()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final BreakStmt n, final Visitable arg) {
+        final BreakStmt n2 = (BreakStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ReturnStmt n, final Visitable arg) {
+        final ReturnStmt n2 = (ReturnStmt) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final IfStmt n, final Visitable arg) {
+        final IfStmt n2 = (IfStmt) arg;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        if (!nodeEquals(n.getElseStmt(), n2.getElseStmt()))
+            return false;
+        if (!nodeEquals(n.getThenStmt(), n2.getThenStmt()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final WhileStmt n, final Visitable arg) {
+        final WhileStmt n2 = (WhileStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ContinueStmt n, final Visitable arg) {
+        final ContinueStmt n2 = (ContinueStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final DoStmt n, final Visitable arg) {
+        final DoStmt n2 = (DoStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ForeachStmt n, final Visitable arg) {
+        final ForeachStmt n2 = (ForeachStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getIterable(), n2.getIterable()))
+            return false;
+        if (!nodeEquals(n.getVariable(), n2.getVariable()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ForStmt n, final Visitable arg) {
+        final ForStmt n2 = (ForStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getCompare(), n2.getCompare()))
+            return false;
+        if (!nodesEquals(n.getInitialization(), n2.getInitialization()))
+            return false;
+        if (!nodesEquals(n.getUpdate(), n2.getUpdate()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ThrowStmt n, final Visitable arg) {
+        final ThrowStmt n2 = (ThrowStmt) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final SynchronizedStmt n, final Visitable arg) {
+        final SynchronizedStmt n2 = (SynchronizedStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final TryStmt n, final Visitable arg) {
+        final TryStmt n2 = (TryStmt) arg;
+        if (!nodesEquals(n.getCatchClauses(), n2.getCatchClauses()))
+            return false;
+        if (!nodeEquals(n.getFinallyBlock(), n2.getFinallyBlock()))
+            return false;
+        if (!nodesEquals(n.getResources(), n2.getResources()))
+            return false;
+        if (!nodeEquals(n.getTryBlock(), n2.getTryBlock()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final CatchClause n, final Visitable arg) {
+        final CatchClause n2 = (CatchClause) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getParameter(), n2.getParameter()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final LambdaExpr n, final Visitable arg) {
+        final LambdaExpr n2 = (LambdaExpr) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!objEquals(n.isEnclosingParameters(), n2.isEnclosingParameters()))
+            return false;
+        if (!nodesEquals(n.getParameters(), n2.getParameters()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final MethodReferenceExpr n, final Visitable arg) {
+        final MethodReferenceExpr n2 = (MethodReferenceExpr) arg;
+        if (!objEquals(n.getIdentifier(), n2.getIdentifier()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final TypeExpr n, final Visitable arg) {
+        final TypeExpr n2 = (TypeExpr) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ImportDeclaration n, final Visitable arg) {
+        final ImportDeclaration n2 = (ImportDeclaration) arg;
+        if (!objEquals(n.isAsterisk(), n2.isAsterisk()))
+            return false;
+        if (!objEquals(n.isStatic(), n2.isStatic()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    public Boolean visit(NodeList n, Visitable arg) {
+        return nodesEquals((NodeList<Node>) n, (NodeList<Node>) arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ModuleDeclaration n, final Visitable arg) {
+        final ModuleDeclaration n2 = (ModuleDeclaration) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.isOpen(), n2.isOpen()))
+            return false;
+        if (!nodesEquals(n.getModuleStmts(), n2.getModuleStmts()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ModuleRequiresStmt n, final Visitable arg) {
+        final ModuleRequiresStmt n2 = (ModuleRequiresStmt) arg;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ModuleExportsStmt n, final Visitable arg) {
+        final ModuleExportsStmt n2 = (ModuleExportsStmt) arg;
+        if (!nodesEquals(n.getModuleNames(), n2.getModuleNames()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ModuleProvidesStmt n, final Visitable arg) {
+        final ModuleProvidesStmt n2 = (ModuleProvidesStmt) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getWithTypes(), n2.getWithTypes()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ModuleUsesStmt n, final Visitable arg) {
+        final ModuleUsesStmt n2 = (ModuleUsesStmt) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ModuleOpensStmt n, final Visitable arg) {
+        final ModuleOpensStmt n2 = (ModuleOpensStmt) arg;
+        if (!nodesEquals(n.getModuleNames(), n2.getModuleNames()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final UnparsableStmt n, final Visitable arg) {
+        final UnparsableStmt n2 = (UnparsableStmt) arg;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.EqualsVisitorGenerator")
+    public Boolean visit(final ReceiverParameter n, final Visitable arg) {
+        final ReceiverParameter n2 = (ReceiverParameter) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+
+    @Override
+    public Boolean visit(final VarType n, final Visitable arg) {
+        final VarType n2 = (VarType) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getComment(), n2.getComment()))
+            return false;
+        return true;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericListVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericListVisitorAdapter.java
new file mode 100644
index 0000000..2defdfa
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericListVisitorAdapter.java
@@ -0,0 +1,2061 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * A visitor that has a return value of ({@link List List<R>}), and has a default implementation for all its visit
+ * methods that visits their children in an unspecified order, and all visit methods
+ * that returns a value be added to a flattened {@link List List<R>}.
+ *
+ * @author Enno Boland
+ */
+public abstract class GenericListVisitorAdapter<R, A> implements GenericVisitor<List<R>, A> {
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final AnnotationDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getMembers().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final AnnotationMemberDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getDefaultValue().isPresent()) {
+            tmp = n.getDefaultValue().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ArrayAccessExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getIndex().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ArrayCreationExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getElementType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getInitializer().isPresent()) {
+            tmp = n.getInitializer().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getLevels().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ArrayCreationLevel n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getDimension().isPresent()) {
+            tmp = n.getDimension().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ArrayInitializerExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getValues().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ArrayType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getComponentType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final AssertStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getCheck().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getMessage().isPresent()) {
+            tmp = n.getMessage().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final AssignExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getTarget().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getValue().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final BinaryExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getLeft().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getRight().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final BlockComment n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final BlockStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getStatements().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final BooleanLiteralExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final BreakStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getLabel().isPresent()) {
+            tmp = n.getLabel().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final CastExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getExpression().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final CatchClause n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getParameter().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final CharLiteralExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ClassExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ClassOrInterfaceDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getExtendedTypes().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getImplementedTypes().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getTypeParameters().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getMembers().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ClassOrInterfaceType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getScope().isPresent()) {
+            tmp = n.getScope().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getTypeArguments().isPresent()) {
+            tmp = n.getTypeArguments().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final CompilationUnit n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getImports().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getModule().isPresent()) {
+            tmp = n.getModule().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getPackageDeclaration().isPresent()) {
+            tmp = n.getPackageDeclaration().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getTypes().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ConditionalExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getCondition().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getElseExpr().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getThenExpr().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ConstructorDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getParameters().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getReceiverParameter().isPresent()) {
+            tmp = n.getReceiverParameter().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getThrownExceptions().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getTypeParameters().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ContinueStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getLabel().isPresent()) {
+            tmp = n.getLabel().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final DoStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getCondition().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final DoubleLiteralExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final EmptyStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final EnclosedExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getInner().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final EnumConstantDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getArguments().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getClassBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final EnumDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getEntries().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getImplementedTypes().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getMembers().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getArguments().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getExpression().isPresent()) {
+            tmp = n.getExpression().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getTypeArguments().isPresent()) {
+            tmp = n.getTypeArguments().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ExpressionStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getExpression().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final FieldAccessExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getScope().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getTypeArguments().isPresent()) {
+            tmp = n.getTypeArguments().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final FieldDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getVariables().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ForStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getCompare().isPresent()) {
+            tmp = n.getCompare().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getInitialization().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getUpdate().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ForeachStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getIterable().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getVariable().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final IfStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getCondition().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getElseStmt().isPresent()) {
+            tmp = n.getElseStmt().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getThenStmt().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ImportDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final InitializerDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final InstanceOfExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getExpression().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final IntegerLiteralExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final IntersectionType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getElements().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final JavadocComment n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final LabeledStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getLabel().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getStatement().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final LambdaExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getParameters().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final LineComment n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final LocalClassDeclarationStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getClassDeclaration().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final LongLiteralExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final MarkerAnnotationExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final MemberValuePair n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getValue().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final MethodCallExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getArguments().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getScope().isPresent()) {
+            tmp = n.getScope().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getTypeArguments().isPresent()) {
+            tmp = n.getTypeArguments().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final MethodDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getBody().isPresent()) {
+            tmp = n.getBody().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getParameters().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getReceiverParameter().isPresent()) {
+            tmp = n.getReceiverParameter().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getThrownExceptions().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getTypeParameters().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final MethodReferenceExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getScope().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getTypeArguments().isPresent()) {
+            tmp = n.getTypeArguments().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final NameExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final Name n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getQualifier().isPresent()) {
+            tmp = n.getQualifier().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final NormalAnnotationExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getPairs().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final NullLiteralExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ObjectCreationExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getAnonymousClassBody().isPresent()) {
+            tmp = n.getAnonymousClassBody().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getArguments().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getScope().isPresent()) {
+            tmp = n.getScope().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getTypeArguments().isPresent()) {
+            tmp = n.getTypeArguments().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final PackageDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final Parameter n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getVarArgsAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final PrimitiveType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ReturnStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getExpression().isPresent()) {
+            tmp = n.getExpression().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final SimpleName n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final SingleMemberAnnotationExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getMemberValue().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final StringLiteralExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final SuperExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getClassExpr().isPresent()) {
+            tmp = n.getClassExpr().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final SwitchEntryStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getLabel().isPresent()) {
+            tmp = n.getLabel().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getStatements().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final SwitchStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getEntries().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getSelector().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final SynchronizedStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getExpression().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ThisExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getClassExpr().isPresent()) {
+            tmp = n.getClassExpr().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ThrowStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getExpression().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final TryStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getCatchClauses().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getFinallyBlock().isPresent()) {
+            tmp = n.getFinallyBlock().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getResources().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getTryBlock().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final TypeExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final TypeParameter n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getTypeBound().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final UnaryExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getExpression().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final UnionType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getElements().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final UnknownType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final VariableDeclarationExpr n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getVariables().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final VariableDeclarator n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getInitializer().isPresent()) {
+            tmp = n.getInitializer().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final VoidType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final WhileStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getBody().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getCondition().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final WildcardType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getExtendedType().isPresent()) {
+            tmp = n.getExtendedType().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getSuperType().isPresent()) {
+            tmp = n.getSuperType().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    public List<R> visit(NodeList n, A arg) {
+        return ((NodeList<? extends Node>) n).stream().filter(Objects::nonNull).flatMap(v -> v.accept(this, arg).stream()).collect(Collectors.toList());
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ModuleDeclaration n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getModuleStmts().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ModuleExportsStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getModuleNames().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ModuleOpensStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getModuleNames().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ModuleProvidesStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getWithTypes().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ModuleRequiresStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ModuleUsesStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final UnparsableStmt n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericListVisitorAdapterGenerator")
+    public List<R> visit(final ReceiverParameter n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getName().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        {
+            tmp = n.getType().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+
+    @Override
+    public List<R> visit(final VarType n, final A arg) {
+        List<R> result = new ArrayList<>();
+        List<R> tmp;
+        {
+            tmp = n.getAnnotations().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        if (n.getComment().isPresent()) {
+            tmp = n.getComment().get().accept(this, arg);
+            if (tmp != null)
+                result.addAll(tmp);
+        }
+        return result;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitor.java
new file mode 100644
index 0000000..494013c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitor.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that has a return value.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public interface GenericVisitor<R, A> {
+
+    // - Compilation Unit ----------------------------------
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(CompilationUnit n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(PackageDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(TypeParameter n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(LineComment n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(BlockComment n, A arg);
+
+    // - Body ----------------------------------------------
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ClassOrInterfaceDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(EnumDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(EnumConstantDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(AnnotationDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(AnnotationMemberDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(FieldDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(VariableDeclarator n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ConstructorDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(MethodDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(Parameter n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(InitializerDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(JavadocComment n, A arg);
+
+    // - Type ----------------------------------------------
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ClassOrInterfaceType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(PrimitiveType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ArrayType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ArrayCreationLevel n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(IntersectionType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(UnionType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(VoidType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(WildcardType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(UnknownType n, A arg);
+
+    // - Expression ----------------------------------------
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ArrayAccessExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ArrayCreationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ArrayInitializerExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(AssignExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(BinaryExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(CastExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ClassExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ConditionalExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(EnclosedExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(FieldAccessExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(InstanceOfExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(StringLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(IntegerLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(LongLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(CharLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(DoubleLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(BooleanLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(NullLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(MethodCallExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(NameExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ObjectCreationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ThisExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(SuperExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(UnaryExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(VariableDeclarationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(MarkerAnnotationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(SingleMemberAnnotationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(NormalAnnotationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(MemberValuePair n, A arg);
+
+    // - Statements ----------------------------------------
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ExplicitConstructorInvocationStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(LocalClassDeclarationStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(AssertStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(BlockStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(LabeledStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(EmptyStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ExpressionStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(SwitchStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(SwitchEntryStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(BreakStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ReturnStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(IfStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(WhileStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ContinueStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(DoStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ForeachStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ForStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ThrowStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(SynchronizedStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(TryStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(CatchClause n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(LambdaExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(MethodReferenceExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(TypeExpr n, A arg);
+
+    R visit(NodeList n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(Name n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(SimpleName n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ImportDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ModuleDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ModuleRequiresStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ModuleExportsStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ModuleProvidesStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ModuleUsesStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ModuleOpensStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(UnparsableStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorGenerator")
+    R visit(ReceiverParameter n, A arg);
+
+    R visit(VarType n, A arg);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
new file mode 100644
index 0000000..3d5de4f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
@@ -0,0 +1,2054 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that has a return value (R), and has a default implementation for all its visit
+ * methods that visits their children in an unspecified order, and the first visit method
+ * that returns a value will stop the visitation and be the end result.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class GenericVisitorAdapter<R, A> implements GenericVisitor<R, A> {
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final AnnotationDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getMembers().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final AnnotationMemberDeclaration n, final A arg) {
+        R result;
+        if (n.getDefaultValue().isPresent()) {
+            result = n.getDefaultValue().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ArrayAccessExpr n, final A arg) {
+        R result;
+        {
+            result = n.getIndex().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ArrayCreationExpr n, final A arg) {
+        R result;
+        {
+            result = n.getElementType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getInitializer().isPresent()) {
+            result = n.getInitializer().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getLevels().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ArrayInitializerExpr n, final A arg) {
+        R result;
+        {
+            result = n.getValues().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final AssertStmt n, final A arg) {
+        R result;
+        {
+            result = n.getCheck().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getMessage().isPresent()) {
+            result = n.getMessage().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final AssignExpr n, final A arg) {
+        R result;
+        {
+            result = n.getTarget().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getValue().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final BinaryExpr n, final A arg) {
+        R result;
+        {
+            result = n.getLeft().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getRight().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final BlockStmt n, final A arg) {
+        R result;
+        {
+            result = n.getStatements().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final BooleanLiteralExpr n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final BreakStmt n, final A arg) {
+        R result;
+        if (n.getLabel().isPresent()) {
+            result = n.getLabel().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final CastExpr n, final A arg) {
+        R result;
+        {
+            result = n.getExpression().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final CatchClause n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getParameter().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final CharLiteralExpr n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ClassExpr n, final A arg) {
+        R result;
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ClassOrInterfaceDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getExtendedTypes().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getImplementedTypes().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getTypeParameters().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getMembers().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ClassOrInterfaceType n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getScope().isPresent()) {
+            result = n.getScope().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getTypeArguments().isPresent()) {
+            result = n.getTypeArguments().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final CompilationUnit n, final A arg) {
+        R result;
+        {
+            result = n.getImports().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getModule().isPresent()) {
+            result = n.getModule().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getPackageDeclaration().isPresent()) {
+            result = n.getPackageDeclaration().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getTypes().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ConditionalExpr n, final A arg) {
+        R result;
+        {
+            result = n.getCondition().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getElseExpr().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getThenExpr().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ConstructorDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getParameters().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getReceiverParameter().isPresent()) {
+            result = n.getReceiverParameter().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getThrownExceptions().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getTypeParameters().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ContinueStmt n, final A arg) {
+        R result;
+        if (n.getLabel().isPresent()) {
+            result = n.getLabel().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final DoStmt n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getCondition().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final DoubleLiteralExpr n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final EmptyStmt n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final EnclosedExpr n, final A arg) {
+        R result;
+        {
+            result = n.getInner().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final EnumConstantDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getArguments().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getClassBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final EnumDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getEntries().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getImplementedTypes().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getMembers().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+        R result;
+        {
+            result = n.getArguments().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getExpression().isPresent()) {
+            result = n.getExpression().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getTypeArguments().isPresent()) {
+            result = n.getTypeArguments().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ExpressionStmt n, final A arg) {
+        R result;
+        {
+            result = n.getExpression().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final FieldAccessExpr n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getScope().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getTypeArguments().isPresent()) {
+            result = n.getTypeArguments().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final FieldDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getVariables().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ForeachStmt n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getIterable().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getVariable().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ForStmt n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getCompare().isPresent()) {
+            result = n.getCompare().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getInitialization().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getUpdate().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final IfStmt n, final A arg) {
+        R result;
+        {
+            result = n.getCondition().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getElseStmt().isPresent()) {
+            result = n.getElseStmt().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getThenStmt().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final InitializerDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final InstanceOfExpr n, final A arg) {
+        R result;
+        {
+            result = n.getExpression().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final IntegerLiteralExpr n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final JavadocComment n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final LabeledStmt n, final A arg) {
+        R result;
+        {
+            result = n.getLabel().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getStatement().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final LongLiteralExpr n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final MarkerAnnotationExpr n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final MemberValuePair n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getValue().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final MethodCallExpr n, final A arg) {
+        R result;
+        {
+            result = n.getArguments().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getScope().isPresent()) {
+            result = n.getScope().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getTypeArguments().isPresent()) {
+            result = n.getTypeArguments().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final MethodDeclaration n, final A arg) {
+        R result;
+        if (n.getBody().isPresent()) {
+            result = n.getBody().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getParameters().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getReceiverParameter().isPresent()) {
+            result = n.getReceiverParameter().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getThrownExceptions().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getTypeParameters().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final NameExpr n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final NormalAnnotationExpr n, final A arg) {
+        R result;
+        {
+            result = n.getPairs().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final NullLiteralExpr n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ObjectCreationExpr n, final A arg) {
+        R result;
+        if (n.getAnonymousClassBody().isPresent()) {
+            result = n.getAnonymousClassBody().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getArguments().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getScope().isPresent()) {
+            result = n.getScope().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getTypeArguments().isPresent()) {
+            result = n.getTypeArguments().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final PackageDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final Parameter n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getVarArgsAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final PrimitiveType n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final Name n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getQualifier().isPresent()) {
+            result = n.getQualifier().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final SimpleName n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ArrayType n, final A arg) {
+        R result;
+        {
+            result = n.getComponentType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ArrayCreationLevel n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getDimension().isPresent()) {
+            result = n.getDimension().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final IntersectionType n, final A arg) {
+        R result;
+        {
+            result = n.getElements().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final UnionType n, final A arg) {
+        R result;
+        {
+            result = n.getElements().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ReturnStmt n, final A arg) {
+        R result;
+        if (n.getExpression().isPresent()) {
+            result = n.getExpression().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final SingleMemberAnnotationExpr n, final A arg) {
+        R result;
+        {
+            result = n.getMemberValue().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final StringLiteralExpr n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final SuperExpr n, final A arg) {
+        R result;
+        if (n.getClassExpr().isPresent()) {
+            result = n.getClassExpr().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final SwitchEntryStmt n, final A arg) {
+        R result;
+        if (n.getLabel().isPresent()) {
+            result = n.getLabel().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getStatements().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final SwitchStmt n, final A arg) {
+        R result;
+        {
+            result = n.getEntries().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getSelector().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final SynchronizedStmt n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getExpression().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ThisExpr n, final A arg) {
+        R result;
+        if (n.getClassExpr().isPresent()) {
+            result = n.getClassExpr().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ThrowStmt n, final A arg) {
+        R result;
+        {
+            result = n.getExpression().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final TryStmt n, final A arg) {
+        R result;
+        {
+            result = n.getCatchClauses().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getFinallyBlock().isPresent()) {
+            result = n.getFinallyBlock().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getResources().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getTryBlock().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final LocalClassDeclarationStmt n, final A arg) {
+        R result;
+        {
+            result = n.getClassDeclaration().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final TypeParameter n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getTypeBound().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final UnaryExpr n, final A arg) {
+        R result;
+        {
+            result = n.getExpression().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final UnknownType n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final VariableDeclarationExpr n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getVariables().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final VariableDeclarator n, final A arg) {
+        R result;
+        if (n.getInitializer().isPresent()) {
+            result = n.getInitializer().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final VoidType n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final WhileStmt n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getCondition().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final WildcardType n, final A arg) {
+        R result;
+        if (n.getExtendedType().isPresent()) {
+            result = n.getExtendedType().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getSuperType().isPresent()) {
+            result = n.getSuperType().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final LambdaExpr n, final A arg) {
+        R result;
+        {
+            result = n.getBody().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getParameters().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final MethodReferenceExpr n, final A arg) {
+        R result;
+        {
+            result = n.getScope().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getTypeArguments().isPresent()) {
+            result = n.getTypeArguments().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final TypeExpr n, final A arg) {
+        R result;
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ImportDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final BlockComment n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final LineComment n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    public R visit(NodeList n, A arg) {
+        for (final Object v : n) {
+            R result = ((Node) v).accept(this, arg);
+            if (result != null) {
+                return result;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ModuleDeclaration n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getModuleStmts().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ModuleRequiresStmt n, final A arg) {
+        R result;
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ModuleExportsStmt n, final A arg) {
+        R result;
+        {
+            result = n.getModuleNames().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ModuleProvidesStmt n, final A arg) {
+        R result;
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getWithTypes().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ModuleUsesStmt n, final A arg) {
+        R result;
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ModuleOpensStmt n, final A arg) {
+        R result;
+        {
+            result = n.getModuleNames().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final UnparsableStmt n, final A arg) {
+        R result;
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorAdapterGenerator")
+    public R visit(final ReceiverParameter n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getName().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        {
+            result = n.getType().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+
+    @Override
+    public R visit(final VarType n, final A arg) {
+        R result;
+        {
+            result = n.getAnnotations().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        if (n.getComment().isPresent()) {
+            result = n.getComment().get().accept(this, arg);
+            if (result != null)
+                return result;
+        }
+        return null;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorWithDefaults.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorWithDefaults.java
new file mode 100644
index 0000000..2cd9a0f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/GenericVisitorWithDefaults.java
@@ -0,0 +1,603 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that has a return value (R), and has default methods that are used when a specific visit method is not
+ * overridden.
+ */
+public abstract class GenericVisitorWithDefaults<R, A> implements GenericVisitor<R, A> {
+
+    /**
+     * This will be called by every node visit method that is not overridden.
+     */
+    public R defaultAction(Node n, A arg) {
+        return null;
+    }
+
+    /**
+     * This will be called by the NodeList visit method when it is not overridden.
+     */
+    public R defaultAction(NodeList n, A arg) {
+        return null;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final AnnotationDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final AnnotationMemberDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ArrayAccessExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ArrayCreationExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ArrayInitializerExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final AssertStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final AssignExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final BinaryExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final BlockStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final BooleanLiteralExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final BreakStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final CastExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final CatchClause n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final CharLiteralExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ClassExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ClassOrInterfaceDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ClassOrInterfaceType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final CompilationUnit n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ConditionalExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ConstructorDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ContinueStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final DoStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final DoubleLiteralExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final EmptyStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final EnclosedExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final EnumConstantDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final EnumDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ExpressionStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final FieldAccessExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final FieldDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ForeachStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ForStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final IfStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final InitializerDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final InstanceOfExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final IntegerLiteralExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final JavadocComment n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final LabeledStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final LongLiteralExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final MarkerAnnotationExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final MemberValuePair n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final MethodCallExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final MethodDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final NameExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final NormalAnnotationExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final NullLiteralExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ObjectCreationExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final PackageDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final Parameter n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final PrimitiveType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final Name n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final SimpleName n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ArrayType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ArrayCreationLevel n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final IntersectionType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final UnionType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ReturnStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final SingleMemberAnnotationExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final StringLiteralExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final SuperExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final SwitchEntryStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final SwitchStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final SynchronizedStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ThisExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ThrowStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final TryStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final LocalClassDeclarationStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final TypeParameter n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final UnaryExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final UnknownType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final VariableDeclarationExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final VariableDeclarator n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final VoidType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final WhileStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final WildcardType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final LambdaExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final MethodReferenceExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final TypeExpr n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ImportDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final BlockComment n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final LineComment n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    public R visit(NodeList n, A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ModuleDeclaration n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ModuleRequiresStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ModuleExportsStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ModuleProvidesStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ModuleUsesStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ModuleOpensStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final UnparsableStmt n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.GenericVisitorWithDefaultsGenerator")
+    public R visit(final ReceiverParameter n, final A arg) {
+        return defaultAction(n, arg);
+    }
+
+    @Override
+    public R visit(final VarType n, final A arg) {
+        return defaultAction(n, arg);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/HashCodeVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/HashCodeVisitor.java
new file mode 100644
index 0000000..92da13e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/HashCodeVisitor.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that calculates a deep hash code for a node by using the hash codes of all its properties,
+ * and the hash codes of all its child nodes (by visiting those too.)
+ */
+public class HashCodeVisitor implements GenericVisitor<Integer, Void> {
+
+    private static final HashCodeVisitor SINGLETON = new HashCodeVisitor();
+
+    private HashCodeVisitor() {
+    // hide constructor
+    }
+
+    public static int hashCode(final Node node) {
+        return node.accept(SINGLETON, null);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final AnnotationDeclaration n, final Void arg) {
+        return (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final AnnotationMemberDeclaration n, final Void arg) {
+        return (n.getDefaultValue().isPresent() ? n.getDefaultValue().get().accept(this, arg) : 0) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ArrayAccessExpr n, final Void arg) {
+        return (n.getIndex().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ArrayCreationExpr n, final Void arg) {
+        return (n.getElementType().accept(this, arg)) * 31 + (n.getInitializer().isPresent() ? n.getInitializer().get().accept(this, arg) : 0) * 31 + (n.getLevels().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ArrayCreationLevel n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getDimension().isPresent() ? n.getDimension().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ArrayInitializerExpr n, final Void arg) {
+        return (n.getValues().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ArrayType n, final Void arg) {
+        return (n.getComponentType().accept(this, arg)) * 31 + (n.getOrigin().hashCode()) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final AssertStmt n, final Void arg) {
+        return (n.getCheck().accept(this, arg)) * 31 + (n.getMessage().isPresent() ? n.getMessage().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final AssignExpr n, final Void arg) {
+        return (n.getOperator().hashCode()) * 31 + (n.getTarget().accept(this, arg)) * 31 + (n.getValue().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final BinaryExpr n, final Void arg) {
+        return (n.getLeft().accept(this, arg)) * 31 + (n.getOperator().hashCode()) * 31 + (n.getRight().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final BlockComment n, final Void arg) {
+        return (n.getContent().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final BlockStmt n, final Void arg) {
+        return (n.getStatements().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final BooleanLiteralExpr n, final Void arg) {
+        return (n.getValue() ? 1 : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final BreakStmt n, final Void arg) {
+        return (n.getLabel().isPresent() ? n.getLabel().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final CastExpr n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final CatchClause n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getParameter().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final CharLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ClassExpr n, final Void arg) {
+        return (n.getType().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ClassOrInterfaceDeclaration n, final Void arg) {
+        return (n.getExtendedTypes().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.isInterface() ? 1 : 0) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ClassOrInterfaceType n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getScope().isPresent() ? n.getScope().get().accept(this, arg) : 0) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final CompilationUnit n, final Void arg) {
+        return (n.getImports().accept(this, arg)) * 31 + (n.getModule().isPresent() ? n.getModule().get().accept(this, arg) : 0) * 31 + (n.getPackageDeclaration().isPresent() ? n.getPackageDeclaration().get().accept(this, arg) : 0) * 31 + (n.getTypes().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ConditionalExpr n, final Void arg) {
+        return (n.getCondition().accept(this, arg)) * 31 + (n.getElseExpr().accept(this, arg)) * 31 + (n.getThenExpr().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ConstructorDeclaration n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getParameters().accept(this, arg)) * 31 + (n.getReceiverParameter().isPresent() ? n.getReceiverParameter().get().accept(this, arg) : 0) * 31 + (n.getThrownExceptions().accept(this, arg)) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ContinueStmt n, final Void arg) {
+        return (n.getLabel().isPresent() ? n.getLabel().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final DoStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getCondition().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final DoubleLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final EmptyStmt n, final Void arg) {
+        return (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final EnclosedExpr n, final Void arg) {
+        return (n.getInner().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final EnumConstantDeclaration n, final Void arg) {
+        return (n.getArguments().accept(this, arg)) * 31 + (n.getClassBody().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final EnumDeclaration n, final Void arg) {
+        return (n.getEntries().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ExplicitConstructorInvocationStmt n, final Void arg) {
+        return (n.getArguments().accept(this, arg)) * 31 + (n.getExpression().isPresent() ? n.getExpression().get().accept(this, arg) : 0) * 31 + (n.isThis() ? 1 : 0) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ExpressionStmt n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final FieldAccessExpr n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getScope().accept(this, arg)) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final FieldDeclaration n, final Void arg) {
+        return (n.getModifiers().hashCode()) * 31 + (n.getVariables().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ForStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getCompare().isPresent() ? n.getCompare().get().accept(this, arg) : 0) * 31 + (n.getInitialization().accept(this, arg)) * 31 + (n.getUpdate().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ForeachStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getIterable().accept(this, arg)) * 31 + (n.getVariable().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final IfStmt n, final Void arg) {
+        return (n.getCondition().accept(this, arg)) * 31 + (n.getElseStmt().isPresent() ? n.getElseStmt().get().accept(this, arg) : 0) * 31 + (n.getThenStmt().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ImportDeclaration n, final Void arg) {
+        return (n.isAsterisk() ? 1 : 0) * 31 + (n.isStatic() ? 1 : 0) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final InitializerDeclaration n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.isStatic() ? 1 : 0) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final InstanceOfExpr n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final IntegerLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final IntersectionType n, final Void arg) {
+        return (n.getElements().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final JavadocComment n, final Void arg) {
+        return (n.getContent().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final LabeledStmt n, final Void arg) {
+        return (n.getLabel().accept(this, arg)) * 31 + (n.getStatement().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final LambdaExpr n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.isEnclosingParameters() ? 1 : 0) * 31 + (n.getParameters().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final LineComment n, final Void arg) {
+        return (n.getContent().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final LocalClassDeclarationStmt n, final Void arg) {
+        return (n.getClassDeclaration().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final LongLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final MarkerAnnotationExpr n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final MemberValuePair n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getValue().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final MethodCallExpr n, final Void arg) {
+        return (n.getArguments().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getScope().isPresent() ? n.getScope().get().accept(this, arg) : 0) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final MethodDeclaration n, final Void arg) {
+        return (n.getBody().isPresent() ? n.getBody().get().accept(this, arg) : 0) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getParameters().accept(this, arg)) * 31 + (n.getReceiverParameter().isPresent() ? n.getReceiverParameter().get().accept(this, arg) : 0) * 31 + (n.getThrownExceptions().accept(this, arg)) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final MethodReferenceExpr n, final Void arg) {
+        return (n.getIdentifier().hashCode()) * 31 + (n.getScope().accept(this, arg)) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final NameExpr n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final Name n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getIdentifier().hashCode()) * 31 + (n.getQualifier().isPresent() ? n.getQualifier().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    public Integer visit(NodeList n, Void arg) {
+        int result = 0;
+        for (Object node : n) {
+            result += 31 * ((Visitable) node).accept(this, arg);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final NormalAnnotationExpr n, final Void arg) {
+        return (n.getPairs().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final NullLiteralExpr n, final Void arg) {
+        return (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ObjectCreationExpr n, final Void arg) {
+        return (n.getAnonymousClassBody().isPresent() ? n.getAnonymousClassBody().get().accept(this, arg) : 0) * 31 + (n.getArguments().accept(this, arg)) * 31 + (n.getScope().isPresent() ? n.getScope().get().accept(this, arg) : 0) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final PackageDeclaration n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final Parameter n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.isVarArgs() ? 1 : 0) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getVarArgsAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final PrimitiveType n, final Void arg) {
+        return (n.getType().hashCode()) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ReturnStmt n, final Void arg) {
+        return (n.getExpression().isPresent() ? n.getExpression().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final SimpleName n, final Void arg) {
+        return (n.getIdentifier().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final SingleMemberAnnotationExpr n, final Void arg) {
+        return (n.getMemberValue().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final StringLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final SuperExpr n, final Void arg) {
+        return (n.getClassExpr().isPresent() ? n.getClassExpr().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final SwitchEntryStmt n, final Void arg) {
+        return (n.getLabel().isPresent() ? n.getLabel().get().accept(this, arg) : 0) * 31 + (n.getStatements().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final SwitchStmt n, final Void arg) {
+        return (n.getEntries().accept(this, arg)) * 31 + (n.getSelector().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final SynchronizedStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getExpression().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ThisExpr n, final Void arg) {
+        return (n.getClassExpr().isPresent() ? n.getClassExpr().get().accept(this, arg) : 0) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ThrowStmt n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final TryStmt n, final Void arg) {
+        return (n.getCatchClauses().accept(this, arg)) * 31 + (n.getFinallyBlock().isPresent() ? n.getFinallyBlock().get().accept(this, arg) : 0) * 31 + (n.getResources().accept(this, arg)) * 31 + (n.getTryBlock().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final TypeExpr n, final Void arg) {
+        return (n.getType().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final TypeParameter n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getTypeBound().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final UnaryExpr n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getOperator().hashCode()) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final UnionType n, final Void arg) {
+        return (n.getElements().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final UnknownType n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final VariableDeclarationExpr n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getVariables().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final VariableDeclarator n, final Void arg) {
+        return (n.getInitializer().isPresent() ? n.getInitializer().get().accept(this, arg) : 0) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final VoidType n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final WhileStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getCondition().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final WildcardType n, final Void arg) {
+        return (n.getExtendedType().isPresent() ? n.getExtendedType().get().accept(this, arg) : 0) * 31 + (n.getSuperType().isPresent() ? n.getSuperType().get().accept(this, arg) : 0) * 31 + (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ModuleDeclaration n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.isOpen() ? 1 : 0) * 31 + (n.getModuleStmts().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ModuleRequiresStmt n, final Void arg) {
+        return (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ModuleExportsStmt n, final Void arg) {
+        return (n.getModuleNames().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ModuleProvidesStmt n, final Void arg) {
+        return (n.getType().accept(this, arg)) * 31 + (n.getWithTypes().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ModuleUsesStmt n, final Void arg) {
+        return (n.getType().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ModuleOpensStmt n, final Void arg) {
+        return (n.getModuleNames().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final UnparsableStmt n, final Void arg) {
+        return (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.HashCodeVisitorGenerator")
+    public Integer visit(final ReceiverParameter n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+
+    @Override
+    public Integer visit(final VarType n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getComment().isPresent() ? n.getComment().get().accept(this, arg) : 0);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java
new file mode 100644
index 0000000..c780864
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java
@@ -0,0 +1,1297 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.utils.Pair;
+import javax.annotation.Generated;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * This visitor can be used to save time when some specific nodes needs
+ * to be changed. To do that just extend this class and override the methods
+ * from the nodes who needs to be changed, returning the changed node.
+ * Returning null will remove the node.
+ *
+ * If a node is removed that was required in its parent node,
+ * the parent node will be removed too.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public class ModifierVisitor<A> implements GenericVisitor<Visitable, A> {
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final AnnotationDeclaration n, final A arg) {
+        NodeList<BodyDeclaration<?>> members = modifyList(n.getMembers(), arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setMembers(members);
+        n.setName(name);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final AnnotationMemberDeclaration n, final A arg) {
+        Expression defaultValue = n.getDefaultValue().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        Type type = (Type) n.getType().accept(this, arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null || type == null)
+            return null;
+        n.setDefaultValue(defaultValue);
+        n.setName(name);
+        n.setType(type);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ArrayAccessExpr n, final A arg) {
+        Expression index = (Expression) n.getIndex().accept(this, arg);
+        Expression name = (Expression) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (index == null || name == null)
+            return null;
+        n.setIndex(index);
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ArrayCreationExpr n, final A arg) {
+        Type elementType = (Type) n.getElementType().accept(this, arg);
+        ArrayInitializerExpr initializer = n.getInitializer().map(s -> (ArrayInitializerExpr) s.accept(this, arg)).orElse(null);
+        NodeList<ArrayCreationLevel> levels = modifyList(n.getLevels(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (elementType == null || levels.isEmpty())
+            return null;
+        n.setElementType(elementType);
+        n.setInitializer(initializer);
+        n.setLevels(levels);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ArrayInitializerExpr n, final A arg) {
+        NodeList<Expression> values = modifyList(n.getValues(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setValues(values);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final AssertStmt n, final A arg) {
+        Expression check = (Expression) n.getCheck().accept(this, arg);
+        Expression message = n.getMessage().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (check == null)
+            return null;
+        n.setCheck(check);
+        n.setMessage(message);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final AssignExpr n, final A arg) {
+        Expression target = (Expression) n.getTarget().accept(this, arg);
+        Expression value = (Expression) n.getValue().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (target == null || value == null)
+            return null;
+        n.setTarget(target);
+        n.setValue(value);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final BinaryExpr n, final A arg) {
+        Expression left = (Expression) n.getLeft().accept(this, arg);
+        Expression right = (Expression) n.getRight().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (left == null)
+            return right;
+        if (right == null)
+            return left;
+        n.setLeft(left);
+        n.setRight(right);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final BlockStmt n, final A arg) {
+        NodeList<Statement> statements = modifyList(n.getStatements(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setStatements(statements);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final BooleanLiteralExpr n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final BreakStmt n, final A arg) {
+        SimpleName label = n.getLabel().map(s -> (SimpleName) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setLabel(label);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final CastExpr n, final A arg) {
+        Expression expression = (Expression) n.getExpression().accept(this, arg);
+        Type type = (Type) n.getType().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (expression == null || type == null)
+            return null;
+        n.setExpression(expression);
+        n.setType(type);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final CatchClause n, final A arg) {
+        BlockStmt body = (BlockStmt) n.getBody().accept(this, arg);
+        Parameter parameter = (Parameter) n.getParameter().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null || parameter == null)
+            return null;
+        n.setBody(body);
+        n.setParameter(parameter);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final CharLiteralExpr n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ClassExpr n, final A arg) {
+        Type type = (Type) n.getType().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (type == null)
+            return null;
+        n.setType(type);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ClassOrInterfaceDeclaration n, final A arg) {
+        NodeList<ClassOrInterfaceType> extendedTypes = modifyList(n.getExtendedTypes(), arg);
+        NodeList<ClassOrInterfaceType> implementedTypes = modifyList(n.getImplementedTypes(), arg);
+        NodeList<TypeParameter> typeParameters = modifyList(n.getTypeParameters(), arg);
+        NodeList<BodyDeclaration<?>> members = modifyList(n.getMembers(), arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setExtendedTypes(extendedTypes);
+        n.setImplementedTypes(implementedTypes);
+        n.setTypeParameters(typeParameters);
+        n.setMembers(members);
+        n.setName(name);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ClassOrInterfaceType n, final A arg) {
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        ClassOrInterfaceType scope = n.getScope().map(s -> (ClassOrInterfaceType) s.accept(this, arg)).orElse(null);
+        NodeList<Type> typeArguments = modifyList(n.getTypeArguments(), arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setName(name);
+        n.setScope(scope);
+        n.setTypeArguments(typeArguments);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final CompilationUnit n, final A arg) {
+        NodeList<ImportDeclaration> imports = modifyList(n.getImports(), arg);
+        ModuleDeclaration module = n.getModule().map(s -> (ModuleDeclaration) s.accept(this, arg)).orElse(null);
+        PackageDeclaration packageDeclaration = n.getPackageDeclaration().map(s -> (PackageDeclaration) s.accept(this, arg)).orElse(null);
+        NodeList<TypeDeclaration<?>> types = modifyList(n.getTypes(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setImports(imports);
+        n.setModule(module);
+        n.setPackageDeclaration(packageDeclaration);
+        n.setTypes(types);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ConditionalExpr n, final A arg) {
+        Expression condition = (Expression) n.getCondition().accept(this, arg);
+        Expression elseExpr = (Expression) n.getElseExpr().accept(this, arg);
+        Expression thenExpr = (Expression) n.getThenExpr().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (condition == null || elseExpr == null || thenExpr == null)
+            return null;
+        n.setCondition(condition);
+        n.setElseExpr(elseExpr);
+        n.setThenExpr(thenExpr);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ConstructorDeclaration n, final A arg) {
+        BlockStmt body = (BlockStmt) n.getBody().accept(this, arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        NodeList<Parameter> parameters = modifyList(n.getParameters(), arg);
+        ReceiverParameter receiverParameter = n.getReceiverParameter().map(s -> (ReceiverParameter) s.accept(this, arg)).orElse(null);
+        NodeList<ReferenceType> thrownExceptions = modifyList(n.getThrownExceptions(), arg);
+        NodeList<TypeParameter> typeParameters = modifyList(n.getTypeParameters(), arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null || name == null)
+            return null;
+        n.setBody(body);
+        n.setName(name);
+        n.setParameters(parameters);
+        n.setReceiverParameter(receiverParameter);
+        n.setThrownExceptions(thrownExceptions);
+        n.setTypeParameters(typeParameters);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ContinueStmt n, final A arg) {
+        SimpleName label = n.getLabel().map(s -> (SimpleName) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setLabel(label);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final DoStmt n, final A arg) {
+        Statement body = (Statement) n.getBody().accept(this, arg);
+        Expression condition = (Expression) n.getCondition().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null || condition == null)
+            return null;
+        n.setBody(body);
+        n.setCondition(condition);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final DoubleLiteralExpr n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final EmptyStmt n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final EnclosedExpr n, final A arg) {
+        Expression inner = (Expression) n.getInner().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (inner == null)
+            return null;
+        n.setInner(inner);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final EnumConstantDeclaration n, final A arg) {
+        NodeList<Expression> arguments = modifyList(n.getArguments(), arg);
+        NodeList<BodyDeclaration<?>> classBody = modifyList(n.getClassBody(), arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setArguments(arguments);
+        n.setClassBody(classBody);
+        n.setName(name);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final EnumDeclaration n, final A arg) {
+        NodeList<EnumConstantDeclaration> entries = modifyList(n.getEntries(), arg);
+        NodeList<ClassOrInterfaceType> implementedTypes = modifyList(n.getImplementedTypes(), arg);
+        NodeList<BodyDeclaration<?>> members = modifyList(n.getMembers(), arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setEntries(entries);
+        n.setImplementedTypes(implementedTypes);
+        n.setMembers(members);
+        n.setName(name);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+        NodeList<Expression> arguments = modifyList(n.getArguments(), arg);
+        Expression expression = n.getExpression().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        NodeList<Type> typeArguments = modifyList(n.getTypeArguments(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setArguments(arguments);
+        n.setExpression(expression);
+        n.setTypeArguments(typeArguments);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ExpressionStmt n, final A arg) {
+        Expression expression = (Expression) n.getExpression().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (expression == null)
+            return null;
+        n.setExpression(expression);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final FieldAccessExpr n, final A arg) {
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        Expression scope = (Expression) n.getScope().accept(this, arg);
+        NodeList<Type> typeArguments = modifyList(n.getTypeArguments(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null || scope == null)
+            return null;
+        n.setName(name);
+        n.setScope(scope);
+        n.setTypeArguments(typeArguments);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final FieldDeclaration n, final A arg) {
+        NodeList<VariableDeclarator> variables = modifyList(n.getVariables(), arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (variables.isEmpty())
+            return null;
+        n.setVariables(variables);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ForeachStmt n, final A arg) {
+        Statement body = (Statement) n.getBody().accept(this, arg);
+        Expression iterable = (Expression) n.getIterable().accept(this, arg);
+        VariableDeclarationExpr variable = (VariableDeclarationExpr) n.getVariable().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null || iterable == null || variable == null)
+            return null;
+        n.setBody(body);
+        n.setIterable(iterable);
+        n.setVariable(variable);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ForStmt n, final A arg) {
+        Statement body = (Statement) n.getBody().accept(this, arg);
+        Expression compare = n.getCompare().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        NodeList<Expression> initialization = modifyList(n.getInitialization(), arg);
+        NodeList<Expression> update = modifyList(n.getUpdate(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null)
+            return null;
+        n.setBody(body);
+        n.setCompare(compare);
+        n.setInitialization(initialization);
+        n.setUpdate(update);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final IfStmt n, final A arg) {
+        Expression condition = (Expression) n.getCondition().accept(this, arg);
+        Statement elseStmt = n.getElseStmt().map(s -> (Statement) s.accept(this, arg)).orElse(null);
+        Statement thenStmt = (Statement) n.getThenStmt().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (condition == null || thenStmt == null)
+            return null;
+        n.setCondition(condition);
+        n.setElseStmt(elseStmt);
+        n.setThenStmt(thenStmt);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final InitializerDeclaration n, final A arg) {
+        BlockStmt body = (BlockStmt) n.getBody().accept(this, arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null)
+            return null;
+        n.setBody(body);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final InstanceOfExpr n, final A arg) {
+        Expression expression = (Expression) n.getExpression().accept(this, arg);
+        ReferenceType type = (ReferenceType) n.getType().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (expression == null || type == null)
+            return null;
+        n.setExpression(expression);
+        n.setType(type);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final IntegerLiteralExpr n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final JavadocComment n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final LabeledStmt n, final A arg) {
+        SimpleName label = (SimpleName) n.getLabel().accept(this, arg);
+        Statement statement = (Statement) n.getStatement().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (label == null || statement == null)
+            return null;
+        n.setLabel(label);
+        n.setStatement(statement);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final LongLiteralExpr n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final MarkerAnnotationExpr n, final A arg) {
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final MemberValuePair n, final A arg) {
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        Expression value = (Expression) n.getValue().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null || value == null)
+            return null;
+        n.setName(name);
+        n.setValue(value);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final MethodCallExpr n, final A arg) {
+        NodeList<Expression> arguments = modifyList(n.getArguments(), arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        Expression scope = n.getScope().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        NodeList<Type> typeArguments = modifyList(n.getTypeArguments(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setArguments(arguments);
+        n.setName(name);
+        n.setScope(scope);
+        n.setTypeArguments(typeArguments);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final MethodDeclaration n, final A arg) {
+        BlockStmt body = n.getBody().map(s -> (BlockStmt) s.accept(this, arg)).orElse(null);
+        Type type = (Type) n.getType().accept(this, arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        NodeList<Parameter> parameters = modifyList(n.getParameters(), arg);
+        ReceiverParameter receiverParameter = n.getReceiverParameter().map(s -> (ReceiverParameter) s.accept(this, arg)).orElse(null);
+        NodeList<ReferenceType> thrownExceptions = modifyList(n.getThrownExceptions(), arg);
+        NodeList<TypeParameter> typeParameters = modifyList(n.getTypeParameters(), arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (type == null || name == null)
+            return null;
+        n.setBody(body);
+        n.setType(type);
+        n.setName(name);
+        n.setParameters(parameters);
+        n.setReceiverParameter(receiverParameter);
+        n.setThrownExceptions(thrownExceptions);
+        n.setTypeParameters(typeParameters);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final NameExpr n, final A arg) {
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final NormalAnnotationExpr n, final A arg) {
+        NodeList<MemberValuePair> pairs = modifyList(n.getPairs(), arg);
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setPairs(pairs);
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final NullLiteralExpr n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ObjectCreationExpr n, final A arg) {
+        NodeList<BodyDeclaration<?>> anonymousClassBody = modifyList(n.getAnonymousClassBody(), arg);
+        NodeList<Expression> arguments = modifyList(n.getArguments(), arg);
+        Expression scope = n.getScope().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        ClassOrInterfaceType type = (ClassOrInterfaceType) n.getType().accept(this, arg);
+        NodeList<Type> typeArguments = modifyList(n.getTypeArguments(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (type == null)
+            return null;
+        n.setAnonymousClassBody(anonymousClassBody);
+        n.setArguments(arguments);
+        n.setScope(scope);
+        n.setType(type);
+        n.setTypeArguments(typeArguments);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final PackageDeclaration n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setAnnotations(annotations);
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final Parameter n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        Type type = (Type) n.getType().accept(this, arg);
+        NodeList<AnnotationExpr> varArgsAnnotations = modifyList(n.getVarArgsAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null || type == null)
+            return null;
+        n.setAnnotations(annotations);
+        n.setName(name);
+        n.setType(type);
+        n.setVarArgsAnnotations(varArgsAnnotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final Name n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Name qualifier = n.getQualifier().map(s -> (Name) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setAnnotations(annotations);
+        n.setQualifier(qualifier);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final PrimitiveType n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final SimpleName n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ArrayType n, final A arg) {
+        Type componentType = (Type) n.getComponentType().accept(this, arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (componentType == null)
+            return null;
+        n.setComponentType(componentType);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ArrayCreationLevel n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Expression dimension = n.getDimension().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setAnnotations(annotations);
+        n.setDimension(dimension);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final IntersectionType n, final A arg) {
+        NodeList<ReferenceType> elements = modifyList(n.getElements(), arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (elements.isEmpty())
+            return null;
+        n.setElements(elements);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final UnionType n, final A arg) {
+        NodeList<ReferenceType> elements = modifyList(n.getElements(), arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (elements.isEmpty())
+            return null;
+        n.setElements(elements);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ReturnStmt n, final A arg) {
+        Expression expression = n.getExpression().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setExpression(expression);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final SingleMemberAnnotationExpr n, final A arg) {
+        Expression memberValue = (Expression) n.getMemberValue().accept(this, arg);
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (memberValue == null || name == null)
+            return null;
+        n.setMemberValue(memberValue);
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final StringLiteralExpr n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final SuperExpr n, final A arg) {
+        Expression classExpr = n.getClassExpr().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setClassExpr(classExpr);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final SwitchEntryStmt n, final A arg) {
+        Expression label = n.getLabel().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        NodeList<Statement> statements = modifyList(n.getStatements(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setLabel(label);
+        n.setStatements(statements);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final SwitchStmt n, final A arg) {
+        NodeList<SwitchEntryStmt> entries = modifyList(n.getEntries(), arg);
+        Expression selector = (Expression) n.getSelector().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (selector == null)
+            return null;
+        n.setEntries(entries);
+        n.setSelector(selector);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final SynchronizedStmt n, final A arg) {
+        BlockStmt body = (BlockStmt) n.getBody().accept(this, arg);
+        Expression expression = (Expression) n.getExpression().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null || expression == null)
+            return null;
+        n.setBody(body);
+        n.setExpression(expression);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ThisExpr n, final A arg) {
+        Expression classExpr = n.getClassExpr().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setClassExpr(classExpr);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ThrowStmt n, final A arg) {
+        Expression expression = (Expression) n.getExpression().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (expression == null)
+            return null;
+        n.setExpression(expression);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final TryStmt n, final A arg) {
+        NodeList<CatchClause> catchClauses = modifyList(n.getCatchClauses(), arg);
+        BlockStmt finallyBlock = n.getFinallyBlock().map(s -> (BlockStmt) s.accept(this, arg)).orElse(null);
+        NodeList<Expression> resources = modifyList(n.getResources(), arg);
+        BlockStmt tryBlock = (BlockStmt) n.getTryBlock().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (tryBlock == null)
+            return null;
+        n.setCatchClauses(catchClauses);
+        n.setFinallyBlock(finallyBlock);
+        n.setResources(resources);
+        n.setTryBlock(tryBlock);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final LocalClassDeclarationStmt n, final A arg) {
+        ClassOrInterfaceDeclaration classDeclaration = (ClassOrInterfaceDeclaration) n.getClassDeclaration().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (classDeclaration == null)
+            return null;
+        n.setClassDeclaration(classDeclaration);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final TypeParameter n, final A arg) {
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        NodeList<ClassOrInterfaceType> typeBound = modifyList(n.getTypeBound(), arg);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setName(name);
+        n.setTypeBound(typeBound);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final UnaryExpr n, final A arg) {
+        Expression expression = (Expression) n.getExpression().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (expression == null)
+            return null;
+        n.setExpression(expression);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final UnknownType n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final VariableDeclarationExpr n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        NodeList<VariableDeclarator> variables = modifyList(n.getVariables(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (variables.isEmpty())
+            return null;
+        n.setAnnotations(annotations);
+        n.setVariables(variables);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final VariableDeclarator n, final A arg) {
+        Expression initializer = n.getInitializer().map(s -> (Expression) s.accept(this, arg)).orElse(null);
+        SimpleName name = (SimpleName) n.getName().accept(this, arg);
+        Type type = (Type) n.getType().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null || type == null)
+            return null;
+        n.setInitializer(initializer);
+        n.setName(name);
+        n.setType(type);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final VoidType n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final WhileStmt n, final A arg) {
+        Statement body = (Statement) n.getBody().accept(this, arg);
+        Expression condition = (Expression) n.getCondition().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null || condition == null)
+            return null;
+        n.setBody(body);
+        n.setCondition(condition);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final WildcardType n, final A arg) {
+        ReferenceType extendedType = n.getExtendedType().map(s -> (ReferenceType) s.accept(this, arg)).orElse(null);
+        ReferenceType superType = n.getSuperType().map(s -> (ReferenceType) s.accept(this, arg)).orElse(null);
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setExtendedType(extendedType);
+        n.setSuperType(superType);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final LambdaExpr n, final A arg) {
+        Statement body = (Statement) n.getBody().accept(this, arg);
+        NodeList<Parameter> parameters = modifyList(n.getParameters(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (body == null)
+            return null;
+        n.setBody(body);
+        n.setParameters(parameters);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final MethodReferenceExpr n, final A arg) {
+        Expression scope = (Expression) n.getScope().accept(this, arg);
+        NodeList<Type> typeArguments = modifyList(n.getTypeArguments(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (scope == null)
+            return null;
+        n.setScope(scope);
+        n.setTypeArguments(typeArguments);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final TypeExpr n, final A arg) {
+        Type type = (Type) n.getType().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (type == null)
+            return null;
+        n.setType(type);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    public Visitable visit(NodeList n, A arg) {
+        if (n.isEmpty()) {
+            return n;
+        }
+        final List<Pair<Node, Node>> changeList = new ArrayList<>();
+        final List<Node> listCopy = new ArrayList<>(n);
+        for (Node node : listCopy) {
+            final Node newNode = (Node) node.accept(this, arg);
+            changeList.add(new Pair<>(node, newNode));
+        }
+        for (Pair<Node, Node> change : changeList) {
+            if (change.b == null) {
+                n.remove(change.a);
+            } else {
+                final int i = n.indexOf(change.a);
+                // If the user removed this item by hand, ignore the change.
+                if (i != -1) {
+                    n.set(i, change.b);
+                }
+            }
+        }
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Node visit(final ImportDeclaration n, final A arg) {
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final BlockComment n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final LineComment n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    private <N extends Node> NodeList<N> modifyList(NodeList<N> list, A arg) {
+        return (NodeList<N>) list.accept(this, arg);
+    }
+
+    private <N extends Node> NodeList<N> modifyList(Optional<NodeList<N>> list, A arg) {
+        return list.map(ns -> modifyList(ns, arg)).orElse(null);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ModuleDeclaration n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        NodeList<ModuleStmt> moduleStmts = modifyList(n.getModuleStmts(), arg);
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setAnnotations(annotations);
+        n.setModuleStmts(moduleStmts);
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ModuleRequiresStmt n, final A arg) {
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ModuleExportsStmt n, final A arg) {
+        NodeList<Name> moduleNames = modifyList(n.getModuleNames(), arg);
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setModuleNames(moduleNames);
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ModuleProvidesStmt n, final A arg) {
+        Type type = (Type) n.getType().accept(this, arg);
+        NodeList<Type> withTypes = modifyList(n.getWithTypes(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (type == null)
+            return null;
+        n.setType(type);
+        n.setWithTypes(withTypes);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ModuleUsesStmt n, final A arg) {
+        Type type = (Type) n.getType().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (type == null)
+            return null;
+        n.setType(type);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ModuleOpensStmt n, final A arg) {
+        NodeList<Name> moduleNames = modifyList(n.getModuleNames(), arg);
+        Name name = (Name) n.getName().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null)
+            return null;
+        n.setModuleNames(moduleNames);
+        n.setName(name);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final UnparsableStmt n, final A arg) {
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ModifierVisitorGenerator")
+    public Visitable visit(final ReceiverParameter n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Name name = (Name) n.getName().accept(this, arg);
+        Type type = (Type) n.getType().accept(this, arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        if (name == null || type == null)
+            return null;
+        n.setAnnotations(annotations);
+        n.setName(name);
+        n.setType(type);
+        n.setComment(comment);
+        return n;
+    }
+
+    @Override
+    public Visitable visit(final VarType n, final A arg) {
+        NodeList<AnnotationExpr> annotations = modifyList(n.getAnnotations(), arg);
+        Comment comment = n.getComment().map(s -> (Comment) s.accept(this, arg)).orElse(null);
+        n.setAnnotations(annotations);
+        n.setComment(comment);
+        return n;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitor.java
new file mode 100644
index 0000000..b3c1dce
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitor.java
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+import java.util.Optional;
+
+public class NoCommentEqualsVisitor implements GenericVisitor<Boolean, Visitable> {
+
+    private static final NoCommentEqualsVisitor SINGLETON = new NoCommentEqualsVisitor();
+
+    public static boolean equals(final Node n, final Node n2) {
+        return SINGLETON.nodeEquals(n, n2);
+    }
+
+    private <N extends Node> boolean nodesEquals(NodeList<N> n, NodeList<N> n2) {
+        if (n == n2) {
+            return true;
+        }
+        if (n == null || n2 == null) {
+            return false;
+        }
+        if (n.size() != n2.size()) {
+            return false;
+        }
+        for (int i = 0; i < n.size(); i++) {
+            if (!nodeEquals(n.get(i), n2.get(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private <T extends Node> boolean nodeEquals(final T n, final T n2) {
+        if (n == n2) {
+            return true;
+        }
+        if (n == null || n2 == null) {
+            return false;
+        }
+        if (n.getClass() != n2.getClass()) {
+            return false;
+        }
+        return n.accept(this, n2);
+    }
+
+    private <T extends Node> boolean nodeEquals(final Optional<T> n, final Optional<T> n2) {
+        return nodeEquals(n.orElse(null), n2.orElse(null));
+    }
+
+    private <T extends Node> boolean nodesEquals(final Optional<NodeList<T>> n, final Optional<NodeList<T>> n2) {
+        return nodesEquals(n.orElse(null), n2.orElse(null));
+    }
+
+    private boolean objEquals(final Object n, final Object n2) {
+        if (n == n2) {
+            return true;
+        }
+        if (n == null || n2 == null) {
+            return false;
+        }
+        return n.equals(n2);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final CompilationUnit n, final Visitable arg) {
+        final CompilationUnit n2 = (CompilationUnit) arg;
+        if (!nodesEquals(n.getImports(), n2.getImports()))
+            return false;
+        if (!nodeEquals(n.getModule(), n2.getModule()))
+            return false;
+        if (!nodeEquals(n.getPackageDeclaration(), n2.getPackageDeclaration()))
+            return false;
+        if (!nodesEquals(n.getTypes(), n2.getTypes()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final PackageDeclaration n, final Visitable arg) {
+        final PackageDeclaration n2 = (PackageDeclaration) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final TypeParameter n, final Visitable arg) {
+        final TypeParameter n2 = (TypeParameter) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getTypeBound(), n2.getTypeBound()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final LineComment n, final Visitable arg) {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final BlockComment n, final Visitable arg) {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ClassOrInterfaceDeclaration n, final Visitable arg) {
+        final ClassOrInterfaceDeclaration n2 = (ClassOrInterfaceDeclaration) arg;
+        if (!nodesEquals(n.getExtendedTypes(), n2.getExtendedTypes()))
+            return false;
+        if (!nodesEquals(n.getImplementedTypes(), n2.getImplementedTypes()))
+            return false;
+        if (!objEquals(n.isInterface(), n2.isInterface()))
+            return false;
+        if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters()))
+            return false;
+        if (!nodesEquals(n.getMembers(), n2.getMembers()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final EnumDeclaration n, final Visitable arg) {
+        final EnumDeclaration n2 = (EnumDeclaration) arg;
+        if (!nodesEquals(n.getEntries(), n2.getEntries()))
+            return false;
+        if (!nodesEquals(n.getImplementedTypes(), n2.getImplementedTypes()))
+            return false;
+        if (!nodesEquals(n.getMembers(), n2.getMembers()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final EnumConstantDeclaration n, final Visitable arg) {
+        final EnumConstantDeclaration n2 = (EnumConstantDeclaration) arg;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodesEquals(n.getClassBody(), n2.getClassBody()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final AnnotationDeclaration n, final Visitable arg) {
+        final AnnotationDeclaration n2 = (AnnotationDeclaration) arg;
+        if (!nodesEquals(n.getMembers(), n2.getMembers()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final AnnotationMemberDeclaration n, final Visitable arg) {
+        final AnnotationMemberDeclaration n2 = (AnnotationMemberDeclaration) arg;
+        if (!nodeEquals(n.getDefaultValue(), n2.getDefaultValue()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final FieldDeclaration n, final Visitable arg) {
+        final FieldDeclaration n2 = (FieldDeclaration) arg;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodesEquals(n.getVariables(), n2.getVariables()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final VariableDeclarator n, final Visitable arg) {
+        final VariableDeclarator n2 = (VariableDeclarator) arg;
+        if (!nodeEquals(n.getInitializer(), n2.getInitializer()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ConstructorDeclaration n, final Visitable arg) {
+        final ConstructorDeclaration n2 = (ConstructorDeclaration) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getParameters(), n2.getParameters()))
+            return false;
+        if (!nodeEquals(n.getReceiverParameter(), n2.getReceiverParameter()))
+            return false;
+        if (!nodesEquals(n.getThrownExceptions(), n2.getThrownExceptions()))
+            return false;
+        if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final MethodDeclaration n, final Visitable arg) {
+        final MethodDeclaration n2 = (MethodDeclaration) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodesEquals(n.getParameters(), n2.getParameters()))
+            return false;
+        if (!nodeEquals(n.getReceiverParameter(), n2.getReceiverParameter()))
+            return false;
+        if (!nodesEquals(n.getThrownExceptions(), n2.getThrownExceptions()))
+            return false;
+        if (!nodesEquals(n.getTypeParameters(), n2.getTypeParameters()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final Parameter n, final Visitable arg) {
+        final Parameter n2 = (Parameter) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.isVarArgs(), n2.isVarArgs()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getVarArgsAnnotations(), n2.getVarArgsAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final InitializerDeclaration n, final Visitable arg) {
+        final InitializerDeclaration n2 = (InitializerDeclaration) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!objEquals(n.isStatic(), n2.isStatic()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final JavadocComment n, final Visitable arg) {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ClassOrInterfaceType n, final Visitable arg) {
+        final ClassOrInterfaceType n2 = (ClassOrInterfaceType) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final PrimitiveType n, final Visitable arg) {
+        final PrimitiveType n2 = (PrimitiveType) arg;
+        if (!objEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ArrayType n, final Visitable arg) {
+        final ArrayType n2 = (ArrayType) arg;
+        if (!nodeEquals(n.getComponentType(), n2.getComponentType()))
+            return false;
+        if (!objEquals(n.getOrigin(), n2.getOrigin()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ArrayCreationLevel n, final Visitable arg) {
+        final ArrayCreationLevel n2 = (ArrayCreationLevel) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getDimension(), n2.getDimension()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final IntersectionType n, final Visitable arg) {
+        final IntersectionType n2 = (IntersectionType) arg;
+        if (!nodesEquals(n.getElements(), n2.getElements()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final UnionType n, final Visitable arg) {
+        final UnionType n2 = (UnionType) arg;
+        if (!nodesEquals(n.getElements(), n2.getElements()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final VoidType n, final Visitable arg) {
+        final VoidType n2 = (VoidType) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final WildcardType n, final Visitable arg) {
+        final WildcardType n2 = (WildcardType) arg;
+        if (!nodeEquals(n.getExtendedType(), n2.getExtendedType()))
+            return false;
+        if (!nodeEquals(n.getSuperType(), n2.getSuperType()))
+            return false;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final UnknownType n, final Visitable arg) {
+        final UnknownType n2 = (UnknownType) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ArrayAccessExpr n, final Visitable arg) {
+        final ArrayAccessExpr n2 = (ArrayAccessExpr) arg;
+        if (!nodeEquals(n.getIndex(), n2.getIndex()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ArrayCreationExpr n, final Visitable arg) {
+        final ArrayCreationExpr n2 = (ArrayCreationExpr) arg;
+        if (!nodeEquals(n.getElementType(), n2.getElementType()))
+            return false;
+        if (!nodeEquals(n.getInitializer(), n2.getInitializer()))
+            return false;
+        if (!nodesEquals(n.getLevels(), n2.getLevels()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ArrayInitializerExpr n, final Visitable arg) {
+        final ArrayInitializerExpr n2 = (ArrayInitializerExpr) arg;
+        if (!nodesEquals(n.getValues(), n2.getValues()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final AssignExpr n, final Visitable arg) {
+        final AssignExpr n2 = (AssignExpr) arg;
+        if (!objEquals(n.getOperator(), n2.getOperator()))
+            return false;
+        if (!nodeEquals(n.getTarget(), n2.getTarget()))
+            return false;
+        if (!nodeEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final BinaryExpr n, final Visitable arg) {
+        final BinaryExpr n2 = (BinaryExpr) arg;
+        if (!nodeEquals(n.getLeft(), n2.getLeft()))
+            return false;
+        if (!objEquals(n.getOperator(), n2.getOperator()))
+            return false;
+        if (!nodeEquals(n.getRight(), n2.getRight()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final CastExpr n, final Visitable arg) {
+        final CastExpr n2 = (CastExpr) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ClassExpr n, final Visitable arg) {
+        final ClassExpr n2 = (ClassExpr) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ConditionalExpr n, final Visitable arg) {
+        final ConditionalExpr n2 = (ConditionalExpr) arg;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        if (!nodeEquals(n.getElseExpr(), n2.getElseExpr()))
+            return false;
+        if (!nodeEquals(n.getThenExpr(), n2.getThenExpr()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final EnclosedExpr n, final Visitable arg) {
+        final EnclosedExpr n2 = (EnclosedExpr) arg;
+        if (!nodeEquals(n.getInner(), n2.getInner()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final FieldAccessExpr n, final Visitable arg) {
+        final FieldAccessExpr n2 = (FieldAccessExpr) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final InstanceOfExpr n, final Visitable arg) {
+        final InstanceOfExpr n2 = (InstanceOfExpr) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final StringLiteralExpr n, final Visitable arg) {
+        final StringLiteralExpr n2 = (StringLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final IntegerLiteralExpr n, final Visitable arg) {
+        final IntegerLiteralExpr n2 = (IntegerLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final LongLiteralExpr n, final Visitable arg) {
+        final LongLiteralExpr n2 = (LongLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final CharLiteralExpr n, final Visitable arg) {
+        final CharLiteralExpr n2 = (CharLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final DoubleLiteralExpr n, final Visitable arg) {
+        final DoubleLiteralExpr n2 = (DoubleLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final BooleanLiteralExpr n, final Visitable arg) {
+        final BooleanLiteralExpr n2 = (BooleanLiteralExpr) arg;
+        if (!objEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final NullLiteralExpr n, final Visitable arg) {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final MethodCallExpr n, final Visitable arg) {
+        final MethodCallExpr n2 = (MethodCallExpr) arg;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final NameExpr n, final Visitable arg) {
+        final NameExpr n2 = (NameExpr) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ObjectCreationExpr n, final Visitable arg) {
+        final ObjectCreationExpr n2 = (ObjectCreationExpr) arg;
+        if (!nodesEquals(n.getAnonymousClassBody(), n2.getAnonymousClassBody()))
+            return false;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final Name n, final Visitable arg) {
+        final Name n2 = (Name) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.getIdentifier(), n2.getIdentifier()))
+            return false;
+        if (!nodeEquals(n.getQualifier(), n2.getQualifier()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final SimpleName n, final Visitable arg) {
+        final SimpleName n2 = (SimpleName) arg;
+        if (!objEquals(n.getIdentifier(), n2.getIdentifier()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ThisExpr n, final Visitable arg) {
+        final ThisExpr n2 = (ThisExpr) arg;
+        if (!nodeEquals(n.getClassExpr(), n2.getClassExpr()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final SuperExpr n, final Visitable arg) {
+        final SuperExpr n2 = (SuperExpr) arg;
+        if (!nodeEquals(n.getClassExpr(), n2.getClassExpr()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final UnaryExpr n, final Visitable arg) {
+        final UnaryExpr n2 = (UnaryExpr) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!objEquals(n.getOperator(), n2.getOperator()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final VariableDeclarationExpr n, final Visitable arg) {
+        final VariableDeclarationExpr n2 = (VariableDeclarationExpr) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodesEquals(n.getVariables(), n2.getVariables()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final MarkerAnnotationExpr n, final Visitable arg) {
+        final MarkerAnnotationExpr n2 = (MarkerAnnotationExpr) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final SingleMemberAnnotationExpr n, final Visitable arg) {
+        final SingleMemberAnnotationExpr n2 = (SingleMemberAnnotationExpr) arg;
+        if (!nodeEquals(n.getMemberValue(), n2.getMemberValue()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final NormalAnnotationExpr n, final Visitable arg) {
+        final NormalAnnotationExpr n2 = (NormalAnnotationExpr) arg;
+        if (!nodesEquals(n.getPairs(), n2.getPairs()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final MemberValuePair n, final Visitable arg) {
+        final MemberValuePair n2 = (MemberValuePair) arg;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getValue(), n2.getValue()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ExplicitConstructorInvocationStmt n, final Visitable arg) {
+        final ExplicitConstructorInvocationStmt n2 = (ExplicitConstructorInvocationStmt) arg;
+        if (!nodesEquals(n.getArguments(), n2.getArguments()))
+            return false;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        if (!objEquals(n.isThis(), n2.isThis()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final LocalClassDeclarationStmt n, final Visitable arg) {
+        final LocalClassDeclarationStmt n2 = (LocalClassDeclarationStmt) arg;
+        if (!nodeEquals(n.getClassDeclaration(), n2.getClassDeclaration()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final AssertStmt n, final Visitable arg) {
+        final AssertStmt n2 = (AssertStmt) arg;
+        if (!nodeEquals(n.getCheck(), n2.getCheck()))
+            return false;
+        if (!nodeEquals(n.getMessage(), n2.getMessage()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final BlockStmt n, final Visitable arg) {
+        final BlockStmt n2 = (BlockStmt) arg;
+        if (!nodesEquals(n.getStatements(), n2.getStatements()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final LabeledStmt n, final Visitable arg) {
+        final LabeledStmt n2 = (LabeledStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        if (!nodeEquals(n.getStatement(), n2.getStatement()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final EmptyStmt n, final Visitable arg) {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ExpressionStmt n, final Visitable arg) {
+        final ExpressionStmt n2 = (ExpressionStmt) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final SwitchStmt n, final Visitable arg) {
+        final SwitchStmt n2 = (SwitchStmt) arg;
+        if (!nodesEquals(n.getEntries(), n2.getEntries()))
+            return false;
+        if (!nodeEquals(n.getSelector(), n2.getSelector()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final SwitchEntryStmt n, final Visitable arg) {
+        final SwitchEntryStmt n2 = (SwitchEntryStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        if (!nodesEquals(n.getStatements(), n2.getStatements()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final BreakStmt n, final Visitable arg) {
+        final BreakStmt n2 = (BreakStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ReturnStmt n, final Visitable arg) {
+        final ReturnStmt n2 = (ReturnStmt) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final IfStmt n, final Visitable arg) {
+        final IfStmt n2 = (IfStmt) arg;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        if (!nodeEquals(n.getElseStmt(), n2.getElseStmt()))
+            return false;
+        if (!nodeEquals(n.getThenStmt(), n2.getThenStmt()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final WhileStmt n, final Visitable arg) {
+        final WhileStmt n2 = (WhileStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ContinueStmt n, final Visitable arg) {
+        final ContinueStmt n2 = (ContinueStmt) arg;
+        if (!nodeEquals(n.getLabel(), n2.getLabel()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final DoStmt n, final Visitable arg) {
+        final DoStmt n2 = (DoStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getCondition(), n2.getCondition()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ForeachStmt n, final Visitable arg) {
+        final ForeachStmt n2 = (ForeachStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getIterable(), n2.getIterable()))
+            return false;
+        if (!nodeEquals(n.getVariable(), n2.getVariable()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ForStmt n, final Visitable arg) {
+        final ForStmt n2 = (ForStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getCompare(), n2.getCompare()))
+            return false;
+        if (!nodesEquals(n.getInitialization(), n2.getInitialization()))
+            return false;
+        if (!nodesEquals(n.getUpdate(), n2.getUpdate()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ThrowStmt n, final Visitable arg) {
+        final ThrowStmt n2 = (ThrowStmt) arg;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final SynchronizedStmt n, final Visitable arg) {
+        final SynchronizedStmt n2 = (SynchronizedStmt) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getExpression(), n2.getExpression()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final TryStmt n, final Visitable arg) {
+        final TryStmt n2 = (TryStmt) arg;
+        if (!nodesEquals(n.getCatchClauses(), n2.getCatchClauses()))
+            return false;
+        if (!nodeEquals(n.getFinallyBlock(), n2.getFinallyBlock()))
+            return false;
+        if (!nodesEquals(n.getResources(), n2.getResources()))
+            return false;
+        if (!nodeEquals(n.getTryBlock(), n2.getTryBlock()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final CatchClause n, final Visitable arg) {
+        final CatchClause n2 = (CatchClause) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!nodeEquals(n.getParameter(), n2.getParameter()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final LambdaExpr n, final Visitable arg) {
+        final LambdaExpr n2 = (LambdaExpr) arg;
+        if (!nodeEquals(n.getBody(), n2.getBody()))
+            return false;
+        if (!objEquals(n.isEnclosingParameters(), n2.isEnclosingParameters()))
+            return false;
+        if (!nodesEquals(n.getParameters(), n2.getParameters()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final MethodReferenceExpr n, final Visitable arg) {
+        final MethodReferenceExpr n2 = (MethodReferenceExpr) arg;
+        if (!objEquals(n.getIdentifier(), n2.getIdentifier()))
+            return false;
+        if (!nodeEquals(n.getScope(), n2.getScope()))
+            return false;
+        if (!nodesEquals(n.getTypeArguments(), n2.getTypeArguments()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final TypeExpr n, final Visitable arg) {
+        final TypeExpr n2 = (TypeExpr) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ImportDeclaration n, final Visitable arg) {
+        final ImportDeclaration n2 = (ImportDeclaration) arg;
+        if (!objEquals(n.isAsterisk(), n2.isAsterisk()))
+            return false;
+        if (!objEquals(n.isStatic(), n2.isStatic()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    public Boolean visit(NodeList n, Visitable arg) {
+        return nodesEquals((NodeList<Node>) n, (NodeList<Node>) arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ModuleDeclaration n, final Visitable arg) {
+        final ModuleDeclaration n2 = (ModuleDeclaration) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!objEquals(n.isOpen(), n2.isOpen()))
+            return false;
+        if (!nodesEquals(n.getModuleStmts(), n2.getModuleStmts()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ModuleRequiresStmt n, final Visitable arg) {
+        final ModuleRequiresStmt n2 = (ModuleRequiresStmt) arg;
+        if (!objEquals(n.getModifiers(), n2.getModifiers()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ModuleExportsStmt n, final Visitable arg) {
+        final ModuleExportsStmt n2 = (ModuleExportsStmt) arg;
+        if (!nodesEquals(n.getModuleNames(), n2.getModuleNames()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ModuleProvidesStmt n, final Visitable arg) {
+        final ModuleProvidesStmt n2 = (ModuleProvidesStmt) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        if (!nodesEquals(n.getWithTypes(), n2.getWithTypes()))
+            return false;
+        return true;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ModuleUsesStmt n, final Visitable arg) {
+        final ModuleUsesStmt n2 = (ModuleUsesStmt) arg;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ModuleOpensStmt n, final Visitable arg) {
+        final ModuleOpensStmt n2 = (ModuleOpensStmt) arg;
+        if (!nodesEquals(n.getModuleNames(), n2.getModuleNames()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final UnparsableStmt n, final Visitable arg) {
+        return true;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentEqualsVisitorGenerator")
+    public Boolean visit(final ReceiverParameter n, final Visitable arg) {
+        final ReceiverParameter n2 = (ReceiverParameter) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        if (!nodeEquals(n.getName(), n2.getName()))
+            return false;
+        if (!nodeEquals(n.getType(), n2.getType()))
+            return false;
+        return true;
+    }
+
+    @Override
+    public Boolean visit(final VarType n, final Visitable arg) {
+        final VarType n2 = (VarType) arg;
+        if (!nodesEquals(n.getAnnotations(), n2.getAnnotations()))
+            return false;
+        return true;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitor.java
new file mode 100644
index 0000000..774e5d9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitor.java
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+public class NoCommentHashCodeVisitor implements GenericVisitor<Integer, Void> {
+
+    private static final NoCommentHashCodeVisitor SINGLETON = new NoCommentHashCodeVisitor();
+
+    public static int hashCode(final Node node) {
+        return node.accept(SINGLETON, null);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final AnnotationDeclaration n, final Void arg) {
+        return (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final AnnotationMemberDeclaration n, final Void arg) {
+        return (n.getDefaultValue().isPresent() ? n.getDefaultValue().get().accept(this, arg) : 0) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ArrayAccessExpr n, final Void arg) {
+        return (n.getIndex().accept(this, arg)) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ArrayCreationExpr n, final Void arg) {
+        return (n.getElementType().accept(this, arg)) * 31 + (n.getInitializer().isPresent() ? n.getInitializer().get().accept(this, arg) : 0) * 31 + (n.getLevels().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ArrayCreationLevel n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getDimension().isPresent() ? n.getDimension().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ArrayInitializerExpr n, final Void arg) {
+        return (n.getValues().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ArrayType n, final Void arg) {
+        return (n.getComponentType().accept(this, arg)) * 31 + (n.getOrigin().hashCode()) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final AssertStmt n, final Void arg) {
+        return (n.getCheck().accept(this, arg)) * 31 + (n.getMessage().isPresent() ? n.getMessage().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final AssignExpr n, final Void arg) {
+        return (n.getOperator().hashCode()) * 31 + (n.getTarget().accept(this, arg)) * 31 + (n.getValue().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final BinaryExpr n, final Void arg) {
+        return (n.getLeft().accept(this, arg)) * 31 + (n.getOperator().hashCode()) * 31 + (n.getRight().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final BlockComment n, final Void arg) {
+        return 0;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final BlockStmt n, final Void arg) {
+        return (n.getStatements().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final BooleanLiteralExpr n, final Void arg) {
+        return (n.getValue() ? 1 : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final BreakStmt n, final Void arg) {
+        return (n.getLabel().isPresent() ? n.getLabel().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final CastExpr n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getType().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final CatchClause n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getParameter().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final CharLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode());
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ClassExpr n, final Void arg) {
+        return (n.getType().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ClassOrInterfaceDeclaration n, final Void arg) {
+        return (n.getExtendedTypes().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.isInterface() ? 1 : 0) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ClassOrInterfaceType n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getScope().isPresent() ? n.getScope().get().accept(this, arg) : 0) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final CompilationUnit n, final Void arg) {
+        return (n.getImports().accept(this, arg)) * 31 + (n.getModule().isPresent() ? n.getModule().get().accept(this, arg) : 0) * 31 + (n.getPackageDeclaration().isPresent() ? n.getPackageDeclaration().get().accept(this, arg) : 0) * 31 + (n.getTypes().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ConditionalExpr n, final Void arg) {
+        return (n.getCondition().accept(this, arg)) * 31 + (n.getElseExpr().accept(this, arg)) * 31 + (n.getThenExpr().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ConstructorDeclaration n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getParameters().accept(this, arg)) * 31 + (n.getReceiverParameter().isPresent() ? n.getReceiverParameter().get().accept(this, arg) : 0) * 31 + (n.getThrownExceptions().accept(this, arg)) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ContinueStmt n, final Void arg) {
+        return (n.getLabel().isPresent() ? n.getLabel().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final DoStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getCondition().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final DoubleLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode());
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final EmptyStmt n, final Void arg) {
+        return 0;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final EnclosedExpr n, final Void arg) {
+        return (n.getInner().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final EnumConstantDeclaration n, final Void arg) {
+        return (n.getArguments().accept(this, arg)) * 31 + (n.getClassBody().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final EnumDeclaration n, final Void arg) {
+        return (n.getEntries().accept(this, arg)) * 31 + (n.getImplementedTypes().accept(this, arg)) * 31 + (n.getMembers().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ExplicitConstructorInvocationStmt n, final Void arg) {
+        return (n.getArguments().accept(this, arg)) * 31 + (n.getExpression().isPresent() ? n.getExpression().get().accept(this, arg) : 0) * 31 + (n.isThis() ? 1 : 0) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ExpressionStmt n, final Void arg) {
+        return (n.getExpression().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final FieldAccessExpr n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getScope().accept(this, arg)) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final FieldDeclaration n, final Void arg) {
+        return (n.getModifiers().hashCode()) * 31 + (n.getVariables().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ForStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getCompare().isPresent() ? n.getCompare().get().accept(this, arg) : 0) * 31 + (n.getInitialization().accept(this, arg)) * 31 + (n.getUpdate().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ForeachStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getIterable().accept(this, arg)) * 31 + (n.getVariable().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final IfStmt n, final Void arg) {
+        return (n.getCondition().accept(this, arg)) * 31 + (n.getElseStmt().isPresent() ? n.getElseStmt().get().accept(this, arg) : 0) * 31 + (n.getThenStmt().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ImportDeclaration n, final Void arg) {
+        return (n.isAsterisk() ? 1 : 0) * 31 + (n.isStatic() ? 1 : 0) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final InitializerDeclaration n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.isStatic() ? 1 : 0) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final InstanceOfExpr n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getType().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final IntegerLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode());
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final IntersectionType n, final Void arg) {
+        return (n.getElements().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final JavadocComment n, final Void arg) {
+        return 0;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final LabeledStmt n, final Void arg) {
+        return (n.getLabel().accept(this, arg)) * 31 + (n.getStatement().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final LambdaExpr n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.isEnclosingParameters() ? 1 : 0) * 31 + (n.getParameters().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final LineComment n, final Void arg) {
+        return 0;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final LocalClassDeclarationStmt n, final Void arg) {
+        return (n.getClassDeclaration().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final LongLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode());
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final MarkerAnnotationExpr n, final Void arg) {
+        return (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final MemberValuePair n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getValue().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final MethodCallExpr n, final Void arg) {
+        return (n.getArguments().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getScope().isPresent() ? n.getScope().get().accept(this, arg) : 0) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final MethodDeclaration n, final Void arg) {
+        return (n.getBody().isPresent() ? n.getBody().get().accept(this, arg) : 0) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getParameters().accept(this, arg)) * 31 + (n.getReceiverParameter().isPresent() ? n.getReceiverParameter().get().accept(this, arg) : 0) * 31 + (n.getThrownExceptions().accept(this, arg)) * 31 + (n.getTypeParameters().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final MethodReferenceExpr n, final Void arg) {
+        return (n.getIdentifier().hashCode()) * 31 + (n.getScope().accept(this, arg)) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final NameExpr n, final Void arg) {
+        return (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final Name n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getIdentifier().hashCode()) * 31 + (n.getQualifier().isPresent() ? n.getQualifier().get().accept(this, arg) : 0);
+    }
+
+    public Integer visit(NodeList n, Void arg) {
+        int result = 0;
+        for (Object node : n) {
+            result += 31 * ((Visitable) node).accept(this, arg);
+        }
+        return result;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final NormalAnnotationExpr n, final Void arg) {
+        return (n.getPairs().accept(this, arg)) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final NullLiteralExpr n, final Void arg) {
+        return 0;
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ObjectCreationExpr n, final Void arg) {
+        return (n.getAnonymousClassBody().isPresent() ? n.getAnonymousClassBody().get().accept(this, arg) : 0) * 31 + (n.getArguments().accept(this, arg)) * 31 + (n.getScope().isPresent() ? n.getScope().get().accept(this, arg) : 0) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getTypeArguments().isPresent() ? n.getTypeArguments().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final PackageDeclaration n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final Parameter n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.isVarArgs() ? 1 : 0) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg)) * 31 + (n.getVarArgsAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final PrimitiveType n, final Void arg) {
+        return (n.getType().hashCode()) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ReturnStmt n, final Void arg) {
+        return (n.getExpression().isPresent() ? n.getExpression().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final SimpleName n, final Void arg) {
+        return (n.getIdentifier().hashCode());
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final SingleMemberAnnotationExpr n, final Void arg) {
+        return (n.getMemberValue().accept(this, arg)) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final StringLiteralExpr n, final Void arg) {
+        return (n.getValue().hashCode());
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final SuperExpr n, final Void arg) {
+        return (n.getClassExpr().isPresent() ? n.getClassExpr().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final SwitchEntryStmt n, final Void arg) {
+        return (n.getLabel().isPresent() ? n.getLabel().get().accept(this, arg) : 0) * 31 + (n.getStatements().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final SwitchStmt n, final Void arg) {
+        return (n.getEntries().accept(this, arg)) * 31 + (n.getSelector().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final SynchronizedStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getExpression().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ThisExpr n, final Void arg) {
+        return (n.getClassExpr().isPresent() ? n.getClassExpr().get().accept(this, arg) : 0);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ThrowStmt n, final Void arg) {
+        return (n.getExpression().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final TryStmt n, final Void arg) {
+        return (n.getCatchClauses().accept(this, arg)) * 31 + (n.getFinallyBlock().isPresent() ? n.getFinallyBlock().get().accept(this, arg) : 0) * 31 + (n.getResources().accept(this, arg)) * 31 + (n.getTryBlock().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final TypeExpr n, final Void arg) {
+        return (n.getType().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final TypeParameter n, final Void arg) {
+        return (n.getName().accept(this, arg)) * 31 + (n.getTypeBound().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final UnaryExpr n, final Void arg) {
+        return (n.getExpression().accept(this, arg)) * 31 + (n.getOperator().hashCode());
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final UnionType n, final Void arg) {
+        return (n.getElements().accept(this, arg)) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final UnknownType n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final VariableDeclarationExpr n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getModifiers().hashCode()) * 31 + (n.getVariables().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final VariableDeclarator n, final Void arg) {
+        return (n.getInitializer().isPresent() ? n.getInitializer().get().accept(this, arg) : 0) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final VoidType n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final WhileStmt n, final Void arg) {
+        return (n.getBody().accept(this, arg)) * 31 + (n.getCondition().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final WildcardType n, final Void arg) {
+        return (n.getExtendedType().isPresent() ? n.getExtendedType().get().accept(this, arg) : 0) * 31 + (n.getSuperType().isPresent() ? n.getSuperType().get().accept(this, arg) : 0) * 31 + (n.getAnnotations().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ModuleDeclaration n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.isOpen() ? 1 : 0) * 31 + (n.getModuleStmts().accept(this, arg)) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ModuleRequiresStmt n, final Void arg) {
+        return (n.getModifiers().hashCode()) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ModuleExportsStmt n, final Void arg) {
+        return (n.getModuleNames().accept(this, arg)) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ModuleProvidesStmt n, final Void arg) {
+        return (n.getType().accept(this, arg)) * 31 + (n.getWithTypes().accept(this, arg));
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ModuleUsesStmt n, final Void arg) {
+        return (n.getType().accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ModuleOpensStmt n, final Void arg) {
+        return (n.getModuleNames().accept(this, arg)) * 31 + (n.getName().accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final UnparsableStmt n, final Void arg) {
+        return 0;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.NoCommentHashCodeVisitorGenerator")
+    public Integer visit(final ReceiverParameter n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg)) * 31 + (n.getName().accept(this, arg)) * 31 + (n.getType().accept(this, arg));
+    }
+
+    @Override
+    public Integer visit(final VarType n, final Void arg) {
+        return (n.getAnnotations().accept(this, arg));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ObjectIdentityEqualsVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ObjectIdentityEqualsVisitor.java
new file mode 100644
index 0000000..7c642bb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ObjectIdentityEqualsVisitor.java
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that calculates deep node equality by comparing all properties and child nodes of the node.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public class ObjectIdentityEqualsVisitor implements GenericVisitor<Boolean, Visitable> {
+
+    private static final ObjectIdentityEqualsVisitor SINGLETON = new ObjectIdentityEqualsVisitor();
+
+    public static boolean equals(final Node n, final Node n2) {
+        return n.accept(SINGLETON, n2);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final CompilationUnit n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final PackageDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final TypeParameter n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final LineComment n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final BlockComment n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ClassOrInterfaceDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final EnumDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final EnumConstantDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final AnnotationDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final AnnotationMemberDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final FieldDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final VariableDeclarator n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ConstructorDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final MethodDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final Parameter n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final InitializerDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final JavadocComment n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ClassOrInterfaceType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final PrimitiveType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ArrayType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ArrayCreationLevel n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final IntersectionType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final UnionType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final VoidType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final WildcardType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final UnknownType n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ArrayAccessExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ArrayCreationExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ArrayInitializerExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final AssignExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final BinaryExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final CastExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ClassExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ConditionalExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final EnclosedExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final FieldAccessExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final InstanceOfExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final StringLiteralExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final IntegerLiteralExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final LongLiteralExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final CharLiteralExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final DoubleLiteralExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final BooleanLiteralExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final NullLiteralExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final MethodCallExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final NameExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ObjectCreationExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final Name n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final SimpleName n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ThisExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final SuperExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final UnaryExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final VariableDeclarationExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final MarkerAnnotationExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final SingleMemberAnnotationExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final NormalAnnotationExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final MemberValuePair n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ExplicitConstructorInvocationStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final LocalClassDeclarationStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final AssertStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final BlockStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final LabeledStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final EmptyStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ExpressionStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final SwitchStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final SwitchEntryStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final BreakStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ReturnStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final IfStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final WhileStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ContinueStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final DoStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ForeachStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ForStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ThrowStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final SynchronizedStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final TryStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final CatchClause n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final LambdaExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final MethodReferenceExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final TypeExpr n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ImportDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    public Boolean visit(NodeList n, Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ModuleDeclaration n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ModuleRequiresStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ModuleExportsStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ModuleProvidesStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ModuleUsesStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ModuleOpensStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final UnparsableStmt n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityEqualsVisitorGenerator")
+    public Boolean visit(final ReceiverParameter n, final Visitable arg) {
+        return n == arg;
+    }
+
+    @Override
+    public Boolean visit(final VarType n, final Visitable arg) {
+        return n == arg;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ObjectIdentityHashCodeVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ObjectIdentityHashCodeVisitor.java
new file mode 100644
index 0000000..c53cf79
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ObjectIdentityHashCodeVisitor.java
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that calculates a deep hash code for a node by using the hash codes of all its properties,
+ * and the hash codes of all its child nodes (by visiting those too.)
+ */
+public class ObjectIdentityHashCodeVisitor implements GenericVisitor<Integer, Void> {
+
+    private static final ObjectIdentityHashCodeVisitor SINGLETON = new ObjectIdentityHashCodeVisitor();
+
+    public static int hashCode(final Node node) {
+        return node.accept(SINGLETON, null);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final AnnotationDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final AnnotationMemberDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ArrayAccessExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ArrayCreationExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ArrayCreationLevel n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ArrayInitializerExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ArrayType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final AssertStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final AssignExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final BinaryExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final BlockComment n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final BlockStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final BooleanLiteralExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final BreakStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final CastExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final CatchClause n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final CharLiteralExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ClassExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ClassOrInterfaceDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ClassOrInterfaceType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final CompilationUnit n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ConditionalExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ConstructorDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ContinueStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final DoStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final DoubleLiteralExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final EmptyStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final EnclosedExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final EnumConstantDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final EnumDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ExplicitConstructorInvocationStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ExpressionStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final FieldAccessExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final FieldDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ForStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ForeachStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final IfStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ImportDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final InitializerDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final InstanceOfExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final IntegerLiteralExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final IntersectionType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final JavadocComment n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final LabeledStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final LambdaExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final LineComment n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final LocalClassDeclarationStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final LongLiteralExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final MarkerAnnotationExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final MemberValuePair n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final MethodCallExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final MethodDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final MethodReferenceExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final NameExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final Name n, final Void arg) {
+        return n.hashCode();
+    }
+
+    public Integer visit(NodeList n, Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final NormalAnnotationExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final NullLiteralExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ObjectCreationExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final PackageDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final Parameter n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final PrimitiveType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ReturnStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final SimpleName n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final SingleMemberAnnotationExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final StringLiteralExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final SuperExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final SwitchEntryStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final SwitchStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final SynchronizedStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ThisExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ThrowStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final TryStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final TypeExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final TypeParameter n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final UnaryExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final UnionType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final UnknownType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final VariableDeclarationExpr n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final VariableDeclarator n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final VoidType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final WhileStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final WildcardType n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ModuleDeclaration n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ModuleRequiresStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ModuleExportsStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ModuleProvidesStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Override()
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ModuleUsesStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ModuleOpensStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final UnparsableStmt n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.ObjectIdentityHashCodeVisitorGenerator")
+    public Integer visit(final ReceiverParameter n, final Void arg) {
+        return n.hashCode();
+    }
+
+    @Override
+    public Integer visit(final VarType n, final Void arg) {
+        return n.hashCode();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/TreeVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/TreeVisitor.java
new file mode 100644
index 0000000..3c4aecd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/TreeVisitor.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.Node;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Queue;
+
+/**
+ * Iterate over all the nodes in (a part of) the AST. In contrast to the visit methods in Node, these methods are
+ * implemented in a simple recursive way which should be more efficient. A disadvantage is that they cannot be quit in
+ * the middle of their traversal.
+ */
+public abstract class TreeVisitor {
+
+    public void visitLeavesFirst(Node node) {
+        for (Node child : node.getChildNodes()) {
+            visitLeavesFirst(child);
+        }
+        process(node);
+    }
+
+    /**
+     * Performs a pre-order node traversal starting with a given node. When each node is visited, {@link #process(Node)}
+     * is called for further processing.
+     *
+     * @param node The node at which the traversal begins.
+     * @see <a href="https://en.wikipedia.org/wiki/Pre-order">Pre-order traversal</a>
+     */
+    public void visitPreOrder(Node node) {
+        process(node);
+        new ArrayList<>(node.getChildNodes()).forEach(this::visitPreOrder);
+    }
+
+    /**
+     * Performs a post-order node traversal starting with a given node. When each node is visited, {@link
+     * #process(Node)} is called for further processing.
+     *
+     * @param node The node at which the traversal begins.
+     * @see <a href="https://en.wikipedia.org/wiki/Post-order">Post-order traversal</a>
+     */
+    public void visitPostOrder(Node node) {
+        new ArrayList<>(node.getChildNodes()).forEach(this::visitPostOrder);
+        process(node);
+    }
+
+    /**
+     * Performs a pre-order node traversal starting with a given node. When each node is visited, {@link #process(Node)}
+     * is called for further processing.
+     *
+     * @param node The node at which the traversal begins.
+     * @see <a href="https://en.wikipedia.org/wiki/Pre-order">Pre-order traversal</a>
+     * @deprecated As of release 3.1.0, replaced by {@link #visitPreOrder(Node)}
+     */
+    @Deprecated
+    public void visitDepthFirst(Node node) {
+        visitPreOrder(node);
+    }
+
+    /**
+     * https://en.wikipedia.org/wiki/Breadth-first_search
+     *
+     * @param node the start node, and the first one that is passed to process(node).
+     */
+    public void visitBreadthFirst(Node node) {
+        final Queue<Node> queue = new LinkedList<>();
+        queue.offer(node);
+        while (queue.size() > 0) {
+            final Node head = queue.peek();
+            for (Node child : head.getChildNodes()) {
+                queue.offer(child);
+            }
+            process(queue.poll());
+        }
+    }
+
+    /**
+     * Process the given node.
+     *
+     * @param node The current node to process.
+     */
+    public abstract void process(Node node);
+
+    /**
+     * Performs a simple traversal over all nodes that have the passed node as their parent.
+     */
+    public void visitDirectChildren(Node node) {
+        new ArrayList<>(node.getChildNodes()).forEach(this::process);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/Visitable.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/Visitable.java
new file mode 100644
index 0000000..32c01a1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/Visitable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.visitor;
+
+public interface Visitable {
+    /**
+     * Accept method for visitor support.
+     *
+     * @param <R> the type of the return value of the visitor
+     * @param <A> the type the user argument passed to the visitor
+     * @param v the visitor implementation
+     * @param arg the argument passed to the visitor (of type A)
+     * @return the result of the visit (of type R)
+     */
+    <R, A> R accept(GenericVisitor<R, A> v, A arg);
+
+    /**
+     * Accept method for visitor support.
+     *
+     * @param <A> the type the argument passed for the visitor
+     * @param v the visitor implementation
+     * @param arg any value relevant for the visitor (of type A)
+     */
+    <A> void accept(VoidVisitor<A> v, A arg);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitor.java
new file mode 100644
index 0000000..37c9c1c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitor.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that does not return anything.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public interface VoidVisitor<A> {
+
+    void visit(NodeList n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(AnnotationDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(AnnotationMemberDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ArrayAccessExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ArrayCreationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ArrayCreationLevel n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ArrayInitializerExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ArrayType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(AssertStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(AssignExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(BinaryExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(BlockComment n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(BlockStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(BooleanLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(BreakStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(CastExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(CatchClause n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(CharLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ClassExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ClassOrInterfaceDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ClassOrInterfaceType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(CompilationUnit n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ConditionalExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ConstructorDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ContinueStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(DoStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(DoubleLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(EmptyStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(EnclosedExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(EnumConstantDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(EnumDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ExplicitConstructorInvocationStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ExpressionStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(FieldAccessExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(FieldDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ForStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ForeachStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(IfStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ImportDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(InitializerDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(InstanceOfExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(IntegerLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(IntersectionType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(JavadocComment n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(LabeledStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(LambdaExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(LineComment n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(LocalClassDeclarationStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(LongLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(MarkerAnnotationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(MemberValuePair n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(MethodCallExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(MethodDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(MethodReferenceExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(NameExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(Name n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(NormalAnnotationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(NullLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ObjectCreationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(PackageDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(Parameter n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(PrimitiveType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ReturnStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(SimpleName n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(SingleMemberAnnotationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(StringLiteralExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(SuperExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(SwitchEntryStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(SwitchStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(SynchronizedStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ThisExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ThrowStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(TryStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(TypeExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(TypeParameter n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(UnaryExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(UnionType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(UnknownType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(VariableDeclarationExpr n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(VariableDeclarator n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(VoidType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(WhileStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(WildcardType n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ModuleDeclaration n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ModuleRequiresStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ModuleExportsStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ModuleProvidesStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ModuleUsesStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ModuleOpensStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(UnparsableStmt n, A arg);
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorGenerator")
+    void visit(ReceiverParameter n, A arg);
+
+    void visit(VarType n, A arg);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
new file mode 100644
index 0000000..1ee8266
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
@@ -0,0 +1,773 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that returns nothing, and has a default implementation for all its visit
+ * methods that simply visit their children in an unspecified order.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public abstract class VoidVisitorAdapter<A> implements VoidVisitor<A> {
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final AnnotationDeclaration n, final A arg) {
+        n.getMembers().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final AnnotationMemberDeclaration n, final A arg) {
+        n.getDefaultValue().ifPresent(l -> l.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getType().accept(this, arg);
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ArrayAccessExpr n, final A arg) {
+        n.getIndex().accept(this, arg);
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ArrayCreationExpr n, final A arg) {
+        n.getElementType().accept(this, arg);
+        n.getInitializer().ifPresent(l -> l.accept(this, arg));
+        n.getLevels().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ArrayInitializerExpr n, final A arg) {
+        n.getValues().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final AssertStmt n, final A arg) {
+        n.getCheck().accept(this, arg);
+        n.getMessage().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final AssignExpr n, final A arg) {
+        n.getTarget().accept(this, arg);
+        n.getValue().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final BinaryExpr n, final A arg) {
+        n.getLeft().accept(this, arg);
+        n.getRight().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final BlockComment n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final BlockStmt n, final A arg) {
+        n.getStatements().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final BooleanLiteralExpr n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final BreakStmt n, final A arg) {
+        n.getLabel().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final CastExpr n, final A arg) {
+        n.getExpression().accept(this, arg);
+        n.getType().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final CatchClause n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getParameter().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final CharLiteralExpr n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ClassExpr n, final A arg) {
+        n.getType().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ClassOrInterfaceDeclaration n, final A arg) {
+        n.getExtendedTypes().forEach(p -> p.accept(this, arg));
+        n.getImplementedTypes().forEach(p -> p.accept(this, arg));
+        n.getTypeParameters().forEach(p -> p.accept(this, arg));
+        n.getMembers().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ClassOrInterfaceType n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getScope().ifPresent(l -> l.accept(this, arg));
+        n.getTypeArguments().ifPresent(l -> l.forEach(v -> v.accept(this, arg)));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final CompilationUnit n, final A arg) {
+        n.getImports().forEach(p -> p.accept(this, arg));
+        n.getModule().ifPresent(l -> l.accept(this, arg));
+        n.getPackageDeclaration().ifPresent(l -> l.accept(this, arg));
+        n.getTypes().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ConditionalExpr n, final A arg) {
+        n.getCondition().accept(this, arg);
+        n.getElseExpr().accept(this, arg);
+        n.getThenExpr().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ConstructorDeclaration n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getName().accept(this, arg);
+        n.getParameters().forEach(p -> p.accept(this, arg));
+        n.getReceiverParameter().ifPresent(l -> l.accept(this, arg));
+        n.getThrownExceptions().forEach(p -> p.accept(this, arg));
+        n.getTypeParameters().forEach(p -> p.accept(this, arg));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ContinueStmt n, final A arg) {
+        n.getLabel().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final DoStmt n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getCondition().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final DoubleLiteralExpr n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final EmptyStmt n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final EnclosedExpr n, final A arg) {
+        n.getInner().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final EnumConstantDeclaration n, final A arg) {
+        n.getArguments().forEach(p -> p.accept(this, arg));
+        n.getClassBody().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final EnumDeclaration n, final A arg) {
+        n.getEntries().forEach(p -> p.accept(this, arg));
+        n.getImplementedTypes().forEach(p -> p.accept(this, arg));
+        n.getMembers().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+        n.getArguments().forEach(p -> p.accept(this, arg));
+        n.getExpression().ifPresent(l -> l.accept(this, arg));
+        n.getTypeArguments().ifPresent(l -> l.forEach(v -> v.accept(this, arg)));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ExpressionStmt n, final A arg) {
+        n.getExpression().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final FieldAccessExpr n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getScope().accept(this, arg);
+        n.getTypeArguments().ifPresent(l -> l.forEach(v -> v.accept(this, arg)));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final FieldDeclaration n, final A arg) {
+        n.getVariables().forEach(p -> p.accept(this, arg));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ForeachStmt n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getIterable().accept(this, arg);
+        n.getVariable().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ForStmt n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getCompare().ifPresent(l -> l.accept(this, arg));
+        n.getInitialization().forEach(p -> p.accept(this, arg));
+        n.getUpdate().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final IfStmt n, final A arg) {
+        n.getCondition().accept(this, arg);
+        n.getElseStmt().ifPresent(l -> l.accept(this, arg));
+        n.getThenStmt().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final InitializerDeclaration n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final InstanceOfExpr n, final A arg) {
+        n.getExpression().accept(this, arg);
+        n.getType().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final IntegerLiteralExpr n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final JavadocComment n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final LabeledStmt n, final A arg) {
+        n.getLabel().accept(this, arg);
+        n.getStatement().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final LineComment n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final LongLiteralExpr n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final MarkerAnnotationExpr n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final MemberValuePair n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getValue().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final MethodCallExpr n, final A arg) {
+        n.getArguments().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getScope().ifPresent(l -> l.accept(this, arg));
+        n.getTypeArguments().ifPresent(l -> l.forEach(v -> v.accept(this, arg)));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final MethodDeclaration n, final A arg) {
+        n.getBody().ifPresent(l -> l.accept(this, arg));
+        n.getType().accept(this, arg);
+        n.getName().accept(this, arg);
+        n.getParameters().forEach(p -> p.accept(this, arg));
+        n.getReceiverParameter().ifPresent(l -> l.accept(this, arg));
+        n.getThrownExceptions().forEach(p -> p.accept(this, arg));
+        n.getTypeParameters().forEach(p -> p.accept(this, arg));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final NameExpr n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final NormalAnnotationExpr n, final A arg) {
+        n.getPairs().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final NullLiteralExpr n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ObjectCreationExpr n, final A arg) {
+        n.getAnonymousClassBody().ifPresent(l -> l.forEach(v -> v.accept(this, arg)));
+        n.getArguments().forEach(p -> p.accept(this, arg));
+        n.getScope().ifPresent(l -> l.accept(this, arg));
+        n.getType().accept(this, arg);
+        n.getTypeArguments().ifPresent(l -> l.forEach(v -> v.accept(this, arg)));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final PackageDeclaration n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final Parameter n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getType().accept(this, arg);
+        n.getVarArgsAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final PrimitiveType n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final Name n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getQualifier().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final SimpleName n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ArrayType n, final A arg) {
+        n.getComponentType().accept(this, arg);
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ArrayCreationLevel n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getDimension().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final IntersectionType n, final A arg) {
+        n.getElements().forEach(p -> p.accept(this, arg));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final UnionType n, final A arg) {
+        n.getElements().forEach(p -> p.accept(this, arg));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ReturnStmt n, final A arg) {
+        n.getExpression().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final SingleMemberAnnotationExpr n, final A arg) {
+        n.getMemberValue().accept(this, arg);
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final StringLiteralExpr n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final SuperExpr n, final A arg) {
+        n.getClassExpr().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final SwitchEntryStmt n, final A arg) {
+        n.getLabel().ifPresent(l -> l.accept(this, arg));
+        n.getStatements().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final SwitchStmt n, final A arg) {
+        n.getEntries().forEach(p -> p.accept(this, arg));
+        n.getSelector().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final SynchronizedStmt n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getExpression().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ThisExpr n, final A arg) {
+        n.getClassExpr().ifPresent(l -> l.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ThrowStmt n, final A arg) {
+        n.getExpression().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final TryStmt n, final A arg) {
+        n.getCatchClauses().forEach(p -> p.accept(this, arg));
+        n.getFinallyBlock().ifPresent(l -> l.accept(this, arg));
+        n.getResources().forEach(p -> p.accept(this, arg));
+        n.getTryBlock().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final LocalClassDeclarationStmt n, final A arg) {
+        n.getClassDeclaration().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final TypeParameter n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getTypeBound().forEach(p -> p.accept(this, arg));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final UnaryExpr n, final A arg) {
+        n.getExpression().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final UnknownType n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final VariableDeclarationExpr n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getVariables().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final VariableDeclarator n, final A arg) {
+        n.getInitializer().ifPresent(l -> l.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getType().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final VoidType n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final WhileStmt n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getCondition().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final WildcardType n, final A arg) {
+        n.getExtendedType().ifPresent(l -> l.accept(this, arg));
+        n.getSuperType().ifPresent(l -> l.accept(this, arg));
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final LambdaExpr n, final A arg) {
+        n.getBody().accept(this, arg);
+        n.getParameters().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final MethodReferenceExpr n, final A arg) {
+        n.getScope().accept(this, arg);
+        n.getTypeArguments().ifPresent(l -> l.forEach(v -> v.accept(this, arg)));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final TypeExpr n, final A arg) {
+        n.getType().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    public void visit(NodeList n, A arg) {
+        for (Object node : n) {
+            ((Node) node).accept(this, arg);
+        }
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ImportDeclaration n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ModuleDeclaration n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getModuleStmts().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ModuleRequiresStmt n, final A arg) {
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ModuleExportsStmt n, final A arg) {
+        n.getModuleNames().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ModuleProvidesStmt n, final A arg) {
+        n.getType().accept(this, arg);
+        n.getWithTypes().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ModuleUsesStmt n, final A arg) {
+        n.getType().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ModuleOpensStmt n, final A arg) {
+        n.getModuleNames().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final UnparsableStmt n, final A arg) {
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorAdapterGenerator")
+    public void visit(final ReceiverParameter n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getName().accept(this, arg);
+        n.getType().accept(this, arg);
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+
+    @Override
+    public void visit(final VarType n, final A arg) {
+        n.getAnnotations().forEach(p -> p.accept(this, arg));
+        n.getComment().ifPresent(l -> l.accept(this, arg));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorWithDefaults.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorWithDefaults.java
new file mode 100644
index 0000000..6622567
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/VoidVisitorWithDefaults.java
@@ -0,0 +1,599 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import javax.annotation.Generated;
+
+/**
+ * A visitor that returns nothing, and has default methods that are used when a specific visit method is not
+ * overridden.
+ */
+public abstract class VoidVisitorWithDefaults<A> implements VoidVisitor<A> {
+
+    /**
+     * This will be called by every node visit method that is not overridden.
+     */
+    public void defaultAction(Node n, A arg) {
+    }
+
+    /**
+     * This will be called by the NodeList visit method when it is not overridden.
+     */
+    public void defaultAction(NodeList n, A arg) {
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final AnnotationDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final AnnotationMemberDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ArrayAccessExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ArrayCreationExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ArrayInitializerExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final AssertStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final AssignExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final BinaryExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final BlockComment n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final BlockStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final BooleanLiteralExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final BreakStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final CastExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final CatchClause n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final CharLiteralExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ClassExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ClassOrInterfaceDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ClassOrInterfaceType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final CompilationUnit n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ConditionalExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ConstructorDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ContinueStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final DoStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final DoubleLiteralExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final EmptyStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final EnclosedExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final EnumConstantDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final EnumDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ExpressionStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final FieldAccessExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final FieldDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ForeachStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ForStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final IfStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final InitializerDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final InstanceOfExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final IntegerLiteralExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final JavadocComment n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final LabeledStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final LineComment n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final LongLiteralExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final MarkerAnnotationExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final MemberValuePair n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final MethodCallExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final MethodDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final NameExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final NormalAnnotationExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final NullLiteralExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ObjectCreationExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final PackageDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final Parameter n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final PrimitiveType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final Name n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final SimpleName n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ArrayType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ArrayCreationLevel n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final IntersectionType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final UnionType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ReturnStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final SingleMemberAnnotationExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final StringLiteralExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final SuperExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final SwitchEntryStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final SwitchStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final SynchronizedStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ThisExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ThrowStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final TryStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final LocalClassDeclarationStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final TypeParameter n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final UnaryExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final UnknownType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final VariableDeclarationExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final VariableDeclarator n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final VoidType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final WhileStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final WildcardType n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final LambdaExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final MethodReferenceExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final TypeExpr n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    public void visit(NodeList n, A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ImportDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ModuleDeclaration n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ModuleRequiresStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ModuleExportsStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ModuleProvidesStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ModuleUsesStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ModuleOpensStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final UnparsableStmt n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    @Generated("com.github.javaparser.generator.core.visitor.VoidVisitorWithDefaultsGenerator")
+    public void visit(final ReceiverParameter n, final A arg) {
+        defaultAction(n, arg);
+    }
+
+    @Override
+    public void visit(final VarType n, final A arg) {
+        defaultAction(n, arg);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/javadoc/Javadoc.java b/javaparser-core/src/main/java/com/github/javaparser/javadoc/Javadoc.java
new file mode 100644
index 0000000..ba606c2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/javadoc/Javadoc.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc;
+
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.javadoc.description.JavadocDescription;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.*;
+
+/**
+ * The structured content of a single Javadoc comment.
+ * <p>
+ * It is composed by a description and a list of block tags.
+ * <p>
+ * An example would be the text contained in this very Javadoc comment. At the moment
+ * of this writing this comment does not contain any block tags (such as <code>@see AnotherClass</code>)
+ */
+public class Javadoc {
+
+    private JavadocDescription description;
+    private List<JavadocBlockTag> blockTags;
+
+    public Javadoc(JavadocDescription description) {
+        this.description = description;
+        this.blockTags = new LinkedList<>();
+    }
+
+    public Javadoc addBlockTag(JavadocBlockTag blockTag) {
+        this.blockTags.add(blockTag);
+        return this;
+    }
+
+    /**
+     * For tags like "@return good things" where
+     * tagName is "return",
+     * and the rest is content.
+     */
+    public Javadoc addBlockTag(String tagName, String content) {
+        return addBlockTag(new JavadocBlockTag(tagName, content));
+    }
+
+    /**
+     * For tags like "@param abc this is a parameter" where
+     * tagName is "param",
+     * parameter is "abc"
+     * and the rest is content.
+     */
+    public Javadoc addBlockTag(String tagName, String parameter, String content) {
+        return addBlockTag(tagName, parameter + " " + content);
+    }
+
+    public Javadoc addBlockTag(String tagName) {
+        return addBlockTag(tagName, "");
+    }
+
+    /**
+     * Return the text content of the document. It does not containing trailing spaces and asterisks
+     * at the start of the line.
+     */
+    public String toText() {
+        StringBuilder sb = new StringBuilder();
+        if (!description.isEmpty()) {
+            sb.append(description.toText());
+            sb.append(EOL);
+        }
+        if (!blockTags.isEmpty()) {
+            sb.append(EOL);
+        }
+        blockTags.forEach(bt -> {
+            sb.append(bt.toText());
+            sb.append(EOL);
+        });
+        return sb.toString();
+    }
+
+    /**
+     * Create a JavadocComment, by formatting the text of the Javadoc using no indentation (expecting the pretty printer to do the formatting.)
+     */
+    public JavadocComment toComment() {
+        return toComment("");
+    }
+
+    /**
+     * Create a JavadocComment, by formatting the text of the Javadoc using the given indentation.
+     */
+    public JavadocComment toComment(String indentation) {
+        for (char c : indentation.toCharArray()) {
+            if (!Character.isWhitespace(c)) {
+                throw new IllegalArgumentException("The indentation string should be composed only by whitespace characters");
+            }
+        }
+        StringBuilder sb = new StringBuilder();
+        sb.append(EOL);
+        final String text = toText();
+        if (!text.isEmpty()) {
+            for (String line : text.split(EOL)) {
+                sb.append(indentation);
+                sb.append(" * ");
+                sb.append(line);
+                sb.append(EOL);
+            }
+        }
+        sb.append(indentation);
+        sb.append(" ");
+        return new JavadocComment(sb.toString());
+    }
+
+    public JavadocDescription getDescription() {
+        return description;
+    }
+
+    /**
+     * @return the current List of associated JavadocBlockTags
+     */
+    public List<JavadocBlockTag> getBlockTags() {
+        return this.blockTags;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Javadoc document = (Javadoc) o;
+
+        return description.equals(document.description) && blockTags.equals(document.blockTags);
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = description.hashCode();
+        result = 31 * result + blockTags.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Javadoc{" +
+                "description=" + description +
+                ", blockTags=" + blockTags +
+                '}';
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/javadoc/JavadocBlockTag.java b/javaparser-core/src/main/java/com/github/javaparser/javadoc/JavadocBlockTag.java
new file mode 100644
index 0000000..f339931
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/javadoc/JavadocBlockTag.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc;
+
+import com.github.javaparser.javadoc.description.JavadocDescription;
+
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.nextWord;
+import static com.github.javaparser.utils.Utils.screamingToCamelCase;
+
+/**
+ * A block tag.
+ * <p>
+ * Typically they are found at the end of Javadoc comments.
+ * <p>
+ * Examples:
+ * <code>@see AnotherClass</code>
+ * <code>@since v0.0.1</code>
+ * <code>@author Jim O'Java</code>
+ */
+public class JavadocBlockTag {
+
+    /**
+     * The type of tag: it could either correspond to a known tag (param, return, etc.) or represent
+     * an unknown tag.
+     */
+    public enum Type {
+        AUTHOR,
+        DEPRECATED,
+        EXCEPTION,
+        PARAM,
+        RETURN,
+        SEE,
+        SERIAL,
+        SERIAL_DATA,
+        SERIAL_FIELD,
+        SINCE,
+        THROWS,
+        VERSION,
+        UNKNOWN;
+
+        Type() {
+            this.keyword = screamingToCamelCase(name());
+        }
+
+        private String keyword;
+
+        boolean hasName() {
+            return this == PARAM;
+        }
+
+        static Type fromName(String tagName) {
+            for (Type t : Type.values()) {
+                if (t.keyword.equals(tagName)) {
+                    return t;
+                }
+            }
+            return UNKNOWN;
+        }
+
+    }
+
+    private Type type;
+    private JavadocDescription content;
+    private Optional<String> name = Optional.empty();
+    private String tagName;
+
+    public JavadocBlockTag(Type type, String content) {
+        this.type = type;
+        this.tagName = type.keyword;
+        if (type.hasName()) {
+            this.name = Optional.of(nextWord(content));
+            content = content.substring(this.name.get().length()).trim();
+        }
+        this.content = JavadocDescription.parseText(content);
+    }
+
+    public JavadocBlockTag(String tagName, String content) {
+        this(Type.fromName(tagName), content);
+        this.tagName = tagName;
+    }
+
+    public static JavadocBlockTag createParamBlockTag(String paramName, String content) {
+        return new JavadocBlockTag(Type.PARAM, paramName + " " + content);
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public JavadocDescription getContent() {
+        return content;
+    }
+
+    public Optional<String> getName() {
+        return name;
+    }
+
+    public String getTagName() {
+        return tagName;
+    }
+
+    public String toText() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("@");
+        sb.append(tagName);
+        name.ifPresent(s -> sb.append(" ").append(s));
+        if (!content.isEmpty()) {
+            sb.append(" ");
+            sb.append(content.toText());
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavadocBlockTag that = (JavadocBlockTag) o;
+
+        if (type != that.type) return false;
+        if (!content.equals(that.content)) return false;
+        return name.equals(that.name);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = type.hashCode();
+        result = 31 * result + content.hashCode();
+        result = 31 * result + name.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "JavadocBlockTag{" +
+                "type=" + type +
+                ", content='" + content + '\'' +
+                ", name=" + name +
+                '}';
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocDescription.java b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocDescription.java
new file mode 100644
index 0000000..82f818a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocDescription.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc.description;
+
+import com.github.javaparser.utils.Pair;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * A javadoc text, potentially containing inline tags.
+ *
+ * For example <code>This class is totally unrelated to {@link com.github.javaparser.Range}</code>
+ */
+public class JavadocDescription {
+
+    private List<JavadocDescriptionElement> elements;
+
+    public static JavadocDescription parseText(String text) {
+        JavadocDescription instance = new JavadocDescription();
+        int index = 0;
+        Pair<Integer, Integer> nextInlineTagPos;
+        while ((nextInlineTagPos = indexOfNextInlineTag(text, index)) != null) {
+            if (nextInlineTagPos.a != index) {
+                instance.addElement(new JavadocSnippet(text.substring(index, nextInlineTagPos.a + 1)));
+            }
+            instance.addElement(JavadocInlineTag.fromText(text.substring(nextInlineTagPos.a, nextInlineTagPos.b + 1)));
+            index = nextInlineTagPos.b;
+        }
+        if (index < text.length()) {
+            instance.addElement(new JavadocSnippet(text.substring(index)));
+        }
+        return instance;
+    }
+
+    private static Pair<Integer, Integer> indexOfNextInlineTag(String text, int start) {
+        int index = text.indexOf("{@", start);
+        if (index == -1) {
+            return null;
+        }
+        // we are interested only in complete inline tags
+        int closeIndex = text.indexOf("}", index);
+        if (closeIndex == -1) {
+            return null;
+        }
+        return new Pair<>(index, closeIndex);
+    }
+
+    public JavadocDescription() {
+        elements = new LinkedList<>();
+    }
+
+    public JavadocDescription(List<JavadocDescriptionElement> elements) {
+        this();
+
+        this.elements.addAll(elements);
+    }
+
+    public boolean addElement(JavadocDescriptionElement element) {
+        return this.elements.add(element);
+    }
+
+    public List<JavadocDescriptionElement> getElements() {
+        return this.elements;
+    }
+
+    public String toText() {
+        StringBuilder sb = new StringBuilder();
+        elements.forEach(e -> sb.append(e.toText()));
+        return sb.toString();
+    }
+
+    public boolean isEmpty() {
+        return toText().isEmpty();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavadocDescription that = (JavadocDescription) o;
+
+        return elements.equals(that.elements);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return elements.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "JavadocDescription{" +
+                "elements=" + elements +
+                '}';
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocDescriptionElement.java b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocDescriptionElement.java
new file mode 100644
index 0000000..3d75b6c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocDescriptionElement.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc.description;
+
+/**
+ * An element of a description: either an inline tag or a piece of text.
+ * <p>
+ * So for example <code>a text</code> or <code>{@link String}</code> could be valid description elements.
+ */
+public interface JavadocDescriptionElement {
+    String toText();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocInlineTag.java b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocInlineTag.java
new file mode 100644
index 0000000..8125bd5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocInlineTag.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc.description;
+
+import static com.github.javaparser.utils.Utils.nextWord;
+import static com.github.javaparser.utils.Utils.screamingToCamelCase;
+
+/**
+ * An inline tag contained in a Javadoc description.
+ * <p>
+ * For example <code>{@link String}</code>
+ */
+public class JavadocInlineTag implements JavadocDescriptionElement {
+
+    public static JavadocDescriptionElement fromText(String text) {
+        if (!text.startsWith("{@")) {
+            throw new IllegalArgumentException(String.format("Expected to start with '{@'. Text '%s'", text));
+        }
+        if (!text.endsWith("}")) {
+            throw new IllegalArgumentException(String.format("Expected to end with '}'. Text '%s'", text));
+        }
+        text = text.substring(2, text.length() - 1);
+        String tagName = nextWord(text);
+        Type type = Type.fromName(tagName);
+        String content = text.substring(tagName.length());
+        return new JavadocInlineTag(tagName, type, content);
+    }
+
+    /**
+     * The type of tag: it could either correspond to a known tag (code, docRoot, etc.) or represent
+     * an unknown tag.
+     */
+    public enum Type {
+        CODE,
+        DOC_ROOT,
+        INHERIT_DOC,
+        LINK,
+        LINKPLAIN,
+        LITERAL,
+        VALUE,
+        UNKNOWN;
+
+        Type() {
+            this.keyword = screamingToCamelCase(name());
+        }
+
+        private String keyword;
+
+        static JavadocInlineTag.Type fromName(String tagName) {
+            for (JavadocInlineTag.Type t : JavadocInlineTag.Type.values()) {
+                if (t.keyword.equals(tagName)) {
+                    return t;
+                }
+            }
+            return UNKNOWN;
+        }
+
+    }
+
+    private String tagName;
+    private Type type;
+    private String content;
+
+    public JavadocInlineTag(String tagName, Type type, String content) {
+        this.tagName = tagName;
+        this.type = type;
+        this.content = content;
+    }
+
+    @Override
+    public String toText() {
+        return "@" + tagName + this.content;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavadocInlineTag that = (JavadocInlineTag) o;
+
+        if (tagName != null ? !tagName.equals(that.tagName) : that.tagName != null) return false;
+        if (type != that.type) return false;
+        return content != null ? content.equals(that.content) : that.content == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = tagName != null ? tagName.hashCode() : 0;
+        result = 31 * result + (type != null ? type.hashCode() : 0);
+        result = 31 * result + (content != null ? content.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "JavadocInlineTag{" +
+                "tagName='" + tagName + '\'' +
+                ", type=" + type +
+                ", content='" + content + '\'' +
+                '}';
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocSnippet.java b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocSnippet.java
new file mode 100644
index 0000000..50b32cb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/javadoc/description/JavadocSnippet.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc.description;
+
+/**
+ * A piece of text inside a Javadoc description.
+ * <p>
+ * For example in <code>A class totally unrelated to {@link String}, I swear!</code> we would have two snippets: one
+ * before and one after the inline tag (<code>{@link String}</code>).
+ */
+public class JavadocSnippet implements JavadocDescriptionElement {
+    private String text;
+
+    public JavadocSnippet(String text) {
+        if (text == null) {
+            throw new NullPointerException();
+        }
+        this.text = text;
+    }
+
+    @Override
+    public String toText() {
+        return this.text;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavadocSnippet that = (JavadocSnippet) o;
+
+        return text.equals(that.text);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return text.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "JavadocSnippet{" +
+                "text='" + text + '\'' +
+                '}';
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationDeclarationMetaModel.java
new file mode 100644
index 0000000..e4a7fdc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationDeclarationMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class AnnotationDeclarationMetaModel extends TypeDeclarationMetaModel {
+
+    AnnotationDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.AnnotationDeclaration.class, "AnnotationDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationExprMetaModel.java
new file mode 100644
index 0000000..f4e892a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationExprMetaModel.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class AnnotationExprMetaModel extends ExpressionMetaModel {
+
+    AnnotationExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.AnnotationExpr.class, "AnnotationExpr", "com.github.javaparser.ast.expr", true, false);
+    }
+
+    protected AnnotationExprMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationMemberDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationMemberDeclarationMetaModel.java
new file mode 100644
index 0000000..d15b967
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AnnotationMemberDeclarationMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class AnnotationMemberDeclarationMetaModel extends BodyDeclarationMetaModel {
+
+    AnnotationMemberDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.AnnotationMemberDeclaration.class, "AnnotationMemberDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel defaultValuePropertyMetaModel;
+
+    public PropertyMetaModel modifiersPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayAccessExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayAccessExprMetaModel.java
new file mode 100644
index 0000000..b6dd157
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayAccessExprMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ArrayAccessExprMetaModel extends ExpressionMetaModel {
+
+    ArrayAccessExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.ArrayAccessExpr.class, "ArrayAccessExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel indexPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayCreationExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayCreationExprMetaModel.java
new file mode 100644
index 0000000..a120f34
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayCreationExprMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ArrayCreationExprMetaModel extends ExpressionMetaModel {
+
+    ArrayCreationExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.ArrayCreationExpr.class, "ArrayCreationExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel elementTypePropertyMetaModel;
+
+    public PropertyMetaModel initializerPropertyMetaModel;
+
+    public PropertyMetaModel levelsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayCreationLevelMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayCreationLevelMetaModel.java
new file mode 100644
index 0000000..b99f92e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayCreationLevelMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ArrayCreationLevelMetaModel extends NodeMetaModel {
+
+    ArrayCreationLevelMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.ArrayCreationLevel.class, "ArrayCreationLevel", "com.github.javaparser.ast", false, false);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+
+    public PropertyMetaModel dimensionPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayInitializerExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayInitializerExprMetaModel.java
new file mode 100644
index 0000000..685910f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayInitializerExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ArrayInitializerExprMetaModel extends ExpressionMetaModel {
+
+    ArrayInitializerExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.ArrayInitializerExpr.class, "ArrayInitializerExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel valuesPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayTypeMetaModel.java
new file mode 100644
index 0000000..58f3f62
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ArrayTypeMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ArrayTypeMetaModel extends ReferenceTypeMetaModel {
+
+    ArrayTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.ArrayType.class, "ArrayType", "com.github.javaparser.ast.type", false, false);
+    }
+
+    public PropertyMetaModel componentTypePropertyMetaModel;
+
+    public PropertyMetaModel originPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/AssertStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AssertStmtMetaModel.java
new file mode 100644
index 0000000..c250832
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AssertStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class AssertStmtMetaModel extends StatementMetaModel {
+
+    AssertStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.AssertStmt.class, "AssertStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel checkPropertyMetaModel;
+
+    public PropertyMetaModel messagePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/AssignExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AssignExprMetaModel.java
new file mode 100644
index 0000000..8a0de9a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/AssignExprMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class AssignExprMetaModel extends ExpressionMetaModel {
+
+    AssignExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.AssignExpr.class, "AssignExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel operatorPropertyMetaModel;
+
+    public PropertyMetaModel targetPropertyMetaModel;
+
+    public PropertyMetaModel valuePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/BaseNodeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BaseNodeMetaModel.java
new file mode 100644
index 0000000..86e53fd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BaseNodeMetaModel.java
@@ -0,0 +1,180 @@
+package com.github.javaparser.metamodel;
+
+import com.github.javaparser.ast.Node;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.decapitalize;
+
+/**
+ * Meta-data about all classes in the AST. These are all Nodes, except NodeList.
+ */
+public abstract class BaseNodeMetaModel {
+    private final Optional<BaseNodeMetaModel> superNodeMetaModel;
+    private final List<PropertyMetaModel> declaredPropertyMetaModels = new ArrayList<>();
+    private final List<PropertyMetaModel> derivedPropertyMetaModels = new ArrayList<>();
+    private final List<PropertyMetaModel> constructorParameters = new ArrayList<>();
+    private final Class<? extends Node> type;
+    private final String name;
+    private final String packageName;
+    private final boolean isAbstract;
+    private final boolean hasWildcard;
+
+    public BaseNodeMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        this.superNodeMetaModel = superNodeMetaModel;
+        this.type = type;
+        this.name = name;
+        this.packageName = packageName;
+        this.isAbstract = isAbstract;
+        this.hasWildcard = hasWildcard;
+    }
+
+    /**
+     * @return is this the meta model for this node class?
+     */
+    public boolean is(Class<? extends Node> c) {
+        return type.equals(c);
+    }
+
+    /**
+     * @return package name + class name
+     */
+    public String getQualifiedClassName() {
+        return packageName + "." + name;
+    }
+
+    /**
+     * @return the meta model for the node that this node extends. Note that this is to be used to find properties
+     * defined in superclasses of a Node.
+     */
+    public Optional<BaseNodeMetaModel> getSuperNodeMetaModel() {
+        return superNodeMetaModel;
+    }
+
+    /**
+     * @return a list of all properties declared directly in this node (not its parent nodes.) These are also available
+     * as fields.
+     */
+    public List<PropertyMetaModel> getDeclaredPropertyMetaModels() {
+        return declaredPropertyMetaModels;
+    }
+
+    public List<PropertyMetaModel> getDerivedPropertyMetaModels() {
+        return derivedPropertyMetaModels;
+    }
+
+    /**
+     * @return a list of all properties that describe the parameters to the all-fields (but not "range" and "comment")
+     * constructor, in the order of appearance in the constructor parameter list.
+     */
+    public List<PropertyMetaModel> getConstructorParameters() {
+        return constructorParameters;
+    }
+
+    /**
+     * @return a list of all properties in this node and its parents. Note that a new list is created every time this
+     * method is called.
+     */
+    public List<PropertyMetaModel> getAllPropertyMetaModels() {
+        List<PropertyMetaModel> allPropertyMetaModels = new ArrayList<>(getDeclaredPropertyMetaModels());
+        BaseNodeMetaModel walkNode = this;
+        while (walkNode.getSuperNodeMetaModel().isPresent()) {
+            walkNode = walkNode.getSuperNodeMetaModel().get();
+            allPropertyMetaModels.addAll(walkNode.getDeclaredPropertyMetaModels());
+        }
+        return allPropertyMetaModels;
+    }
+
+    public boolean isInstanceOfMetaModel(BaseNodeMetaModel baseMetaModel) {
+        if (this == baseMetaModel) {
+            return true;
+        }
+        if (isRootNode()) {
+            return false;
+        }
+        return getSuperNodeMetaModel().get().isInstanceOfMetaModel(baseMetaModel);
+    }
+
+    /**
+     * @return the class for this AST node type.
+     */
+    public Class<? extends Node> getType() {
+        return type;
+    }
+
+    /**
+     * @return the package containing this AST node class.
+     */
+    public String getPackageName() {
+        return packageName;
+    }
+
+    /**
+     * @return whether this AST node is abstract.
+     */
+    public boolean isAbstract() {
+        return isAbstract;
+    }
+
+    /**
+     * @return whether this AST node has a &lt;?&gt; at the end of its type.
+     */
+    public boolean hasWildcard() {
+        return hasWildcard;
+    }
+
+    /**
+     * @return whether this AST node is the root node, meaning that it is the meta model for "Node": "NodeMetaModel".
+     */
+    public boolean isRootNode() {
+        return !superNodeMetaModel.isPresent();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BaseNodeMetaModel classMetaModel = (BaseNodeMetaModel) o;
+
+        if (!type.equals(classMetaModel.type)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return type.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    /**
+     * @return the type name, with generics.
+     */
+    public String getTypeNameGenerified() {
+        if (hasWildcard) {
+            return getTypeName() + "<?>";
+        }
+        return getTypeName();
+    }
+
+    /**
+     * @return the raw type name, so nothing but the name.
+     */
+    public String getTypeName() {
+        return type.getSimpleName();
+    }
+
+    /**
+     * The name of the field in JavaParserMetaModel for this node meta model.
+     */
+    public String getMetaModelFieldName() {
+        return decapitalize(getClass().getSimpleName());
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/BinaryExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BinaryExprMetaModel.java
new file mode 100644
index 0000000..f160ac8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BinaryExprMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class BinaryExprMetaModel extends ExpressionMetaModel {
+
+    BinaryExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.BinaryExpr.class, "BinaryExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel leftPropertyMetaModel;
+
+    public PropertyMetaModel operatorPropertyMetaModel;
+
+    public PropertyMetaModel rightPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/BlockCommentMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BlockCommentMetaModel.java
new file mode 100644
index 0000000..166397d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BlockCommentMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class BlockCommentMetaModel extends CommentMetaModel {
+
+    BlockCommentMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.comments.BlockComment.class, "BlockComment", "com.github.javaparser.ast.comments", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/BlockStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BlockStmtMetaModel.java
new file mode 100644
index 0000000..847809d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BlockStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class BlockStmtMetaModel extends StatementMetaModel {
+
+    BlockStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.BlockStmt.class, "BlockStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel statementsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/BodyDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BodyDeclarationMetaModel.java
new file mode 100644
index 0000000..c45d595
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BodyDeclarationMetaModel.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class BodyDeclarationMetaModel extends NodeMetaModel {
+
+    BodyDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.BodyDeclaration.class, "BodyDeclaration", "com.github.javaparser.ast.body", true, true);
+    }
+
+    protected BodyDeclarationMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/BooleanLiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BooleanLiteralExprMetaModel.java
new file mode 100644
index 0000000..eff913d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BooleanLiteralExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class BooleanLiteralExprMetaModel extends LiteralExprMetaModel {
+
+    BooleanLiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.BooleanLiteralExpr.class, "BooleanLiteralExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel valuePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/BreakStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BreakStmtMetaModel.java
new file mode 100644
index 0000000..39f7232
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/BreakStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class BreakStmtMetaModel extends StatementMetaModel {
+
+    BreakStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.BreakStmt.class, "BreakStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel labelPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/CallableDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CallableDeclarationMetaModel.java
new file mode 100644
index 0000000..040762f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CallableDeclarationMetaModel.java
@@ -0,0 +1,27 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class CallableDeclarationMetaModel extends BodyDeclarationMetaModel {
+
+    CallableDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.CallableDeclaration.class, "CallableDeclaration", "com.github.javaparser.ast.body", true, true);
+    }
+
+    protected CallableDeclarationMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel modifiersPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel parametersPropertyMetaModel;
+
+    public PropertyMetaModel receiverParameterPropertyMetaModel;
+
+    public PropertyMetaModel thrownExceptionsPropertyMetaModel;
+
+    public PropertyMetaModel typeParametersPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/CastExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CastExprMetaModel.java
new file mode 100644
index 0000000..9671d9b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CastExprMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class CastExprMetaModel extends ExpressionMetaModel {
+
+    CastExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.CastExpr.class, "CastExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/CatchClauseMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CatchClauseMetaModel.java
new file mode 100644
index 0000000..34cd102
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CatchClauseMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class CatchClauseMetaModel extends NodeMetaModel {
+
+    CatchClauseMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.CatchClause.class, "CatchClause", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel parameterPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/CharLiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CharLiteralExprMetaModel.java
new file mode 100644
index 0000000..d88595b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CharLiteralExprMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class CharLiteralExprMetaModel extends LiteralStringValueExprMetaModel {
+
+    CharLiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.CharLiteralExpr.class, "CharLiteralExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassExprMetaModel.java
new file mode 100644
index 0000000..fea3a12
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ClassExprMetaModel extends ExpressionMetaModel {
+
+    ClassExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.ClassExpr.class, "ClassExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceDeclarationMetaModel.java
new file mode 100644
index 0000000..7f0eff9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceDeclarationMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ClassOrInterfaceDeclarationMetaModel extends TypeDeclarationMetaModel {
+
+    ClassOrInterfaceDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.class, "ClassOrInterfaceDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel extendedTypesPropertyMetaModel;
+
+    public PropertyMetaModel implementedTypesPropertyMetaModel;
+
+    public PropertyMetaModel isInterfacePropertyMetaModel;
+
+    public PropertyMetaModel typeParametersPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceTypeMetaModel.java
new file mode 100644
index 0000000..b2747ed
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ClassOrInterfaceTypeMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ClassOrInterfaceTypeMetaModel extends ReferenceTypeMetaModel {
+
+    ClassOrInterfaceTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.ClassOrInterfaceType.class, "ClassOrInterfaceType", "com.github.javaparser.ast.type", false, false);
+    }
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel scopePropertyMetaModel;
+
+    public PropertyMetaModel typeArgumentsPropertyMetaModel;
+
+    public PropertyMetaModel usingDiamondOperatorPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/CommentMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CommentMetaModel.java
new file mode 100644
index 0000000..8cdd7a9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CommentMetaModel.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class CommentMetaModel extends NodeMetaModel {
+
+    CommentMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.comments.Comment.class, "Comment", "com.github.javaparser.ast.comments", true, false);
+    }
+
+    protected CommentMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel contentPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/CompilationUnitMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CompilationUnitMetaModel.java
new file mode 100644
index 0000000..34eacb7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/CompilationUnitMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class CompilationUnitMetaModel extends NodeMetaModel {
+
+    CompilationUnitMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.CompilationUnit.class, "CompilationUnit", "com.github.javaparser.ast", false, false);
+    }
+
+    public PropertyMetaModel importsPropertyMetaModel;
+
+    public PropertyMetaModel modulePropertyMetaModel;
+
+    public PropertyMetaModel packageDeclarationPropertyMetaModel;
+
+    public PropertyMetaModel typesPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ConditionalExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ConditionalExprMetaModel.java
new file mode 100644
index 0000000..dbc9119
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ConditionalExprMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ConditionalExprMetaModel extends ExpressionMetaModel {
+
+    ConditionalExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.ConditionalExpr.class, "ConditionalExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel conditionPropertyMetaModel;
+
+    public PropertyMetaModel elseExprPropertyMetaModel;
+
+    public PropertyMetaModel thenExprPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ConstructorDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ConstructorDeclarationMetaModel.java
new file mode 100644
index 0000000..4d0b9f3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ConstructorDeclarationMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ConstructorDeclarationMetaModel extends CallableDeclarationMetaModel {
+
+    ConstructorDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.ConstructorDeclaration.class, "ConstructorDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ContinueStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ContinueStmtMetaModel.java
new file mode 100644
index 0000000..d07db70
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ContinueStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ContinueStmtMetaModel extends StatementMetaModel {
+
+    ContinueStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.ContinueStmt.class, "ContinueStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel labelPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/DerivedProperty.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/DerivedProperty.java
new file mode 100644
index 0000000..3a29d78
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/DerivedProperty.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Indicate a derived property of a Node,
+ * meaning it does supply useful information,
+ * but it does so by taking information from other properties.
+ * (Used during generation of the meta model.)
+ */
+@Retention(RUNTIME)
+@Target(METHOD)
+public @interface DerivedProperty {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/DoStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/DoStmtMetaModel.java
new file mode 100644
index 0000000..45451c7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/DoStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class DoStmtMetaModel extends StatementMetaModel {
+
+    DoStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.DoStmt.class, "DoStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel conditionPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/DoubleLiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/DoubleLiteralExprMetaModel.java
new file mode 100644
index 0000000..2b77273
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/DoubleLiteralExprMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class DoubleLiteralExprMetaModel extends LiteralStringValueExprMetaModel {
+
+    DoubleLiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.DoubleLiteralExpr.class, "DoubleLiteralExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/EmptyStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EmptyStmtMetaModel.java
new file mode 100644
index 0000000..0943326
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EmptyStmtMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class EmptyStmtMetaModel extends StatementMetaModel {
+
+    EmptyStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.EmptyStmt.class, "EmptyStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnclosedExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnclosedExprMetaModel.java
new file mode 100644
index 0000000..4dd99b8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnclosedExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class EnclosedExprMetaModel extends ExpressionMetaModel {
+
+    EnclosedExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.EnclosedExpr.class, "EnclosedExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel innerPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnumConstantDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnumConstantDeclarationMetaModel.java
new file mode 100644
index 0000000..2067e6d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnumConstantDeclarationMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class EnumConstantDeclarationMetaModel extends BodyDeclarationMetaModel {
+
+    EnumConstantDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.EnumConstantDeclaration.class, "EnumConstantDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel argumentsPropertyMetaModel;
+
+    public PropertyMetaModel classBodyPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnumDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnumDeclarationMetaModel.java
new file mode 100644
index 0000000..d4ed813
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/EnumDeclarationMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class EnumDeclarationMetaModel extends TypeDeclarationMetaModel {
+
+    EnumDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.EnumDeclaration.class, "EnumDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel entriesPropertyMetaModel;
+
+    public PropertyMetaModel implementedTypesPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExplicitConstructorInvocationStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExplicitConstructorInvocationStmtMetaModel.java
new file mode 100644
index 0000000..9d47b43
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExplicitConstructorInvocationStmtMetaModel.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ExplicitConstructorInvocationStmtMetaModel extends StatementMetaModel {
+
+    ExplicitConstructorInvocationStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.class, "ExplicitConstructorInvocationStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel argumentsPropertyMetaModel;
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+
+    public PropertyMetaModel isThisPropertyMetaModel;
+
+    public PropertyMetaModel typeArgumentsPropertyMetaModel;
+
+    public PropertyMetaModel usingDiamondOperatorPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExpressionMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExpressionMetaModel.java
new file mode 100644
index 0000000..dc77368
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExpressionMetaModel.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class ExpressionMetaModel extends NodeMetaModel {
+
+    ExpressionMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.Expression.class, "Expression", "com.github.javaparser.ast.expr", true, false);
+    }
+
+    protected ExpressionMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExpressionStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExpressionStmtMetaModel.java
new file mode 100644
index 0000000..69d7a59
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ExpressionStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ExpressionStmtMetaModel extends StatementMetaModel {
+
+    ExpressionStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.ExpressionStmt.class, "ExpressionStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/FieldAccessExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/FieldAccessExprMetaModel.java
new file mode 100644
index 0000000..b9e820e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/FieldAccessExprMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class FieldAccessExprMetaModel extends ExpressionMetaModel {
+
+    FieldAccessExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.FieldAccessExpr.class, "FieldAccessExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel scopePropertyMetaModel;
+
+    public PropertyMetaModel typeArgumentsPropertyMetaModel;
+
+    public PropertyMetaModel usingDiamondOperatorPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/FieldDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/FieldDeclarationMetaModel.java
new file mode 100644
index 0000000..9f12fae
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/FieldDeclarationMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class FieldDeclarationMetaModel extends BodyDeclarationMetaModel {
+
+    FieldDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.FieldDeclaration.class, "FieldDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel modifiersPropertyMetaModel;
+
+    public PropertyMetaModel variablesPropertyMetaModel;
+
+    public PropertyMetaModel maximumCommonTypePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ForStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ForStmtMetaModel.java
new file mode 100644
index 0000000..c63039e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ForStmtMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ForStmtMetaModel extends StatementMetaModel {
+
+    ForStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.ForStmt.class, "ForStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel comparePropertyMetaModel;
+
+    public PropertyMetaModel initializationPropertyMetaModel;
+
+    public PropertyMetaModel updatePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ForeachStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ForeachStmtMetaModel.java
new file mode 100644
index 0000000..8a8dc4e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ForeachStmtMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ForeachStmtMetaModel extends StatementMetaModel {
+
+    ForeachStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.ForeachStmt.class, "ForeachStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel iterablePropertyMetaModel;
+
+    public PropertyMetaModel variablePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/IfStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/IfStmtMetaModel.java
new file mode 100644
index 0000000..91f4027
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/IfStmtMetaModel.java
@@ -0,0 +1,24 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class IfStmtMetaModel extends StatementMetaModel {
+
+    IfStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.IfStmt.class, "IfStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel conditionPropertyMetaModel;
+
+    public PropertyMetaModel elseStmtPropertyMetaModel;
+
+    public PropertyMetaModel thenStmtPropertyMetaModel;
+
+    public PropertyMetaModel cascadingIfStmtPropertyMetaModel;
+
+    public PropertyMetaModel elseBlockPropertyMetaModel;
+
+    public PropertyMetaModel elseBranchPropertyMetaModel;
+
+    public PropertyMetaModel thenBlockPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ImportDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ImportDeclarationMetaModel.java
new file mode 100644
index 0000000..3c1e4f8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ImportDeclarationMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ImportDeclarationMetaModel extends NodeMetaModel {
+
+    ImportDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.ImportDeclaration.class, "ImportDeclaration", "com.github.javaparser.ast", false, false);
+    }
+
+    public PropertyMetaModel isAsteriskPropertyMetaModel;
+
+    public PropertyMetaModel isStaticPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/InitializerDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/InitializerDeclarationMetaModel.java
new file mode 100644
index 0000000..035038c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/InitializerDeclarationMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class InitializerDeclarationMetaModel extends BodyDeclarationMetaModel {
+
+    InitializerDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.InitializerDeclaration.class, "InitializerDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel isStaticPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/InstanceOfExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/InstanceOfExprMetaModel.java
new file mode 100644
index 0000000..9b4534c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/InstanceOfExprMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class InstanceOfExprMetaModel extends ExpressionMetaModel {
+
+    InstanceOfExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.InstanceOfExpr.class, "InstanceOfExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/IntegerLiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/IntegerLiteralExprMetaModel.java
new file mode 100644
index 0000000..b793217
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/IntegerLiteralExprMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class IntegerLiteralExprMetaModel extends LiteralStringValueExprMetaModel {
+
+    IntegerLiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.IntegerLiteralExpr.class, "IntegerLiteralExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/InternalProperty.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/InternalProperty.java
new file mode 100644
index 0000000..83c5970
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/InternalProperty.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.metamodel;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Indicate an internal property of a Node,
+ * meaning it is not part of the meta model.
+ * (Used during generation of the meta model.)
+ */
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface InternalProperty {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/IntersectionTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/IntersectionTypeMetaModel.java
new file mode 100644
index 0000000..73ad36f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/IntersectionTypeMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class IntersectionTypeMetaModel extends TypeMetaModel {
+
+    IntersectionTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.IntersectionType.class, "IntersectionType", "com.github.javaparser.ast.type", false, false);
+    }
+
+    public PropertyMetaModel elementsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavaParserMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavaParserMetaModel.java
new file mode 100644
index 0000000..bffbd37
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavaParserMetaModel.java
@@ -0,0 +1,977 @@
+package com.github.javaparser.metamodel;
+
+import com.github.javaparser.ast.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * The model contains meta-data about all nodes in the AST.
+ */
+public final class JavaParserMetaModel {
+
+    private JavaParserMetaModel() {
+    }
+
+    private static final List<BaseNodeMetaModel> nodeMetaModels = new ArrayList<>();
+
+    private static void initializeConstructorParameters() {
+        bodyDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        callableDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.modifiersPropertyMetaModel);
+        callableDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        callableDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.typeParametersPropertyMetaModel);
+        callableDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.namePropertyMetaModel);
+        callableDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.parametersPropertyMetaModel);
+        callableDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.thrownExceptionsPropertyMetaModel);
+        callableDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.receiverParameterPropertyMetaModel);
+        typeMetaModel.getConstructorParameters().add(typeMetaModel.annotationsPropertyMetaModel);
+        annotationExprMetaModel.getConstructorParameters().add(annotationExprMetaModel.namePropertyMetaModel);
+        typeDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.modifiersPropertyMetaModel);
+        typeDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        typeDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.namePropertyMetaModel);
+        typeDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.membersPropertyMetaModel);
+        referenceTypeMetaModel.getConstructorParameters().add(typeMetaModel.annotationsPropertyMetaModel);
+        literalStringValueExprMetaModel.getConstructorParameters().add(literalStringValueExprMetaModel.valuePropertyMetaModel);
+        stringLiteralExprMetaModel.getConstructorParameters().add(literalStringValueExprMetaModel.valuePropertyMetaModel);
+        moduleDeclarationMetaModel.getConstructorParameters().add(moduleDeclarationMetaModel.annotationsPropertyMetaModel);
+        moduleDeclarationMetaModel.getConstructorParameters().add(moduleDeclarationMetaModel.namePropertyMetaModel);
+        moduleDeclarationMetaModel.getConstructorParameters().add(moduleDeclarationMetaModel.isOpenPropertyMetaModel);
+        moduleDeclarationMetaModel.getConstructorParameters().add(moduleDeclarationMetaModel.moduleStmtsPropertyMetaModel);
+        arrayCreationLevelMetaModel.getConstructorParameters().add(arrayCreationLevelMetaModel.dimensionPropertyMetaModel);
+        arrayCreationLevelMetaModel.getConstructorParameters().add(arrayCreationLevelMetaModel.annotationsPropertyMetaModel);
+        compilationUnitMetaModel.getConstructorParameters().add(compilationUnitMetaModel.packageDeclarationPropertyMetaModel);
+        compilationUnitMetaModel.getConstructorParameters().add(compilationUnitMetaModel.importsPropertyMetaModel);
+        compilationUnitMetaModel.getConstructorParameters().add(compilationUnitMetaModel.typesPropertyMetaModel);
+        compilationUnitMetaModel.getConstructorParameters().add(compilationUnitMetaModel.modulePropertyMetaModel);
+        packageDeclarationMetaModel.getConstructorParameters().add(packageDeclarationMetaModel.annotationsPropertyMetaModel);
+        packageDeclarationMetaModel.getConstructorParameters().add(packageDeclarationMetaModel.namePropertyMetaModel);
+        annotationDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.modifiersPropertyMetaModel);
+        annotationDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        annotationDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.namePropertyMetaModel);
+        annotationDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.membersPropertyMetaModel);
+        annotationMemberDeclarationMetaModel.getConstructorParameters().add(annotationMemberDeclarationMetaModel.modifiersPropertyMetaModel);
+        annotationMemberDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        annotationMemberDeclarationMetaModel.getConstructorParameters().add(annotationMemberDeclarationMetaModel.typePropertyMetaModel);
+        annotationMemberDeclarationMetaModel.getConstructorParameters().add(annotationMemberDeclarationMetaModel.namePropertyMetaModel);
+        annotationMemberDeclarationMetaModel.getConstructorParameters().add(annotationMemberDeclarationMetaModel.defaultValuePropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.modifiersPropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.isInterfacePropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.namePropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.typeParametersPropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.extendedTypesPropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(classOrInterfaceDeclarationMetaModel.implementedTypesPropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.membersPropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.modifiersPropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.typeParametersPropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.namePropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.parametersPropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.thrownExceptionsPropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(constructorDeclarationMetaModel.bodyPropertyMetaModel);
+        constructorDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.receiverParameterPropertyMetaModel);
+        enumConstantDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        enumConstantDeclarationMetaModel.getConstructorParameters().add(enumConstantDeclarationMetaModel.namePropertyMetaModel);
+        enumConstantDeclarationMetaModel.getConstructorParameters().add(enumConstantDeclarationMetaModel.argumentsPropertyMetaModel);
+        enumConstantDeclarationMetaModel.getConstructorParameters().add(enumConstantDeclarationMetaModel.classBodyPropertyMetaModel);
+        enumDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.modifiersPropertyMetaModel);
+        enumDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        enumDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.namePropertyMetaModel);
+        enumDeclarationMetaModel.getConstructorParameters().add(enumDeclarationMetaModel.implementedTypesPropertyMetaModel);
+        enumDeclarationMetaModel.getConstructorParameters().add(enumDeclarationMetaModel.entriesPropertyMetaModel);
+        enumDeclarationMetaModel.getConstructorParameters().add(typeDeclarationMetaModel.membersPropertyMetaModel);
+        fieldDeclarationMetaModel.getConstructorParameters().add(fieldDeclarationMetaModel.modifiersPropertyMetaModel);
+        fieldDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        fieldDeclarationMetaModel.getConstructorParameters().add(fieldDeclarationMetaModel.variablesPropertyMetaModel);
+        initializerDeclarationMetaModel.getConstructorParameters().add(initializerDeclarationMetaModel.isStaticPropertyMetaModel);
+        initializerDeclarationMetaModel.getConstructorParameters().add(initializerDeclarationMetaModel.bodyPropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.modifiersPropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.typeParametersPropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(methodDeclarationMetaModel.typePropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.namePropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.parametersPropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.thrownExceptionsPropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(methodDeclarationMetaModel.bodyPropertyMetaModel);
+        methodDeclarationMetaModel.getConstructorParameters().add(callableDeclarationMetaModel.receiverParameterPropertyMetaModel);
+        parameterMetaModel.getConstructorParameters().add(parameterMetaModel.modifiersPropertyMetaModel);
+        parameterMetaModel.getConstructorParameters().add(parameterMetaModel.annotationsPropertyMetaModel);
+        parameterMetaModel.getConstructorParameters().add(parameterMetaModel.typePropertyMetaModel);
+        parameterMetaModel.getConstructorParameters().add(parameterMetaModel.isVarArgsPropertyMetaModel);
+        parameterMetaModel.getConstructorParameters().add(parameterMetaModel.varArgsAnnotationsPropertyMetaModel);
+        parameterMetaModel.getConstructorParameters().add(parameterMetaModel.namePropertyMetaModel);
+        receiverParameterMetaModel.getConstructorParameters().add(receiverParameterMetaModel.annotationsPropertyMetaModel);
+        receiverParameterMetaModel.getConstructorParameters().add(receiverParameterMetaModel.typePropertyMetaModel);
+        receiverParameterMetaModel.getConstructorParameters().add(receiverParameterMetaModel.namePropertyMetaModel);
+        variableDeclaratorMetaModel.getConstructorParameters().add(variableDeclaratorMetaModel.typePropertyMetaModel);
+        variableDeclaratorMetaModel.getConstructorParameters().add(variableDeclaratorMetaModel.namePropertyMetaModel);
+        variableDeclaratorMetaModel.getConstructorParameters().add(variableDeclaratorMetaModel.initializerPropertyMetaModel);
+        commentMetaModel.getConstructorParameters().add(commentMetaModel.contentPropertyMetaModel);
+        blockCommentMetaModel.getConstructorParameters().add(commentMetaModel.contentPropertyMetaModel);
+        javadocCommentMetaModel.getConstructorParameters().add(commentMetaModel.contentPropertyMetaModel);
+        lineCommentMetaModel.getConstructorParameters().add(commentMetaModel.contentPropertyMetaModel);
+        arrayAccessExprMetaModel.getConstructorParameters().add(arrayAccessExprMetaModel.namePropertyMetaModel);
+        arrayAccessExprMetaModel.getConstructorParameters().add(arrayAccessExprMetaModel.indexPropertyMetaModel);
+        arrayCreationExprMetaModel.getConstructorParameters().add(arrayCreationExprMetaModel.elementTypePropertyMetaModel);
+        arrayCreationExprMetaModel.getConstructorParameters().add(arrayCreationExprMetaModel.levelsPropertyMetaModel);
+        arrayCreationExprMetaModel.getConstructorParameters().add(arrayCreationExprMetaModel.initializerPropertyMetaModel);
+        arrayInitializerExprMetaModel.getConstructorParameters().add(arrayInitializerExprMetaModel.valuesPropertyMetaModel);
+        assignExprMetaModel.getConstructorParameters().add(assignExprMetaModel.targetPropertyMetaModel);
+        assignExprMetaModel.getConstructorParameters().add(assignExprMetaModel.valuePropertyMetaModel);
+        assignExprMetaModel.getConstructorParameters().add(assignExprMetaModel.operatorPropertyMetaModel);
+        binaryExprMetaModel.getConstructorParameters().add(binaryExprMetaModel.leftPropertyMetaModel);
+        binaryExprMetaModel.getConstructorParameters().add(binaryExprMetaModel.rightPropertyMetaModel);
+        binaryExprMetaModel.getConstructorParameters().add(binaryExprMetaModel.operatorPropertyMetaModel);
+        booleanLiteralExprMetaModel.getConstructorParameters().add(booleanLiteralExprMetaModel.valuePropertyMetaModel);
+        castExprMetaModel.getConstructorParameters().add(castExprMetaModel.typePropertyMetaModel);
+        castExprMetaModel.getConstructorParameters().add(castExprMetaModel.expressionPropertyMetaModel);
+        charLiteralExprMetaModel.getConstructorParameters().add(literalStringValueExprMetaModel.valuePropertyMetaModel);
+        classExprMetaModel.getConstructorParameters().add(classExprMetaModel.typePropertyMetaModel);
+        conditionalExprMetaModel.getConstructorParameters().add(conditionalExprMetaModel.conditionPropertyMetaModel);
+        conditionalExprMetaModel.getConstructorParameters().add(conditionalExprMetaModel.thenExprPropertyMetaModel);
+        conditionalExprMetaModel.getConstructorParameters().add(conditionalExprMetaModel.elseExprPropertyMetaModel);
+        doubleLiteralExprMetaModel.getConstructorParameters().add(literalStringValueExprMetaModel.valuePropertyMetaModel);
+        enclosedExprMetaModel.getConstructorParameters().add(enclosedExprMetaModel.innerPropertyMetaModel);
+        fieldAccessExprMetaModel.getConstructorParameters().add(fieldAccessExprMetaModel.scopePropertyMetaModel);
+        fieldAccessExprMetaModel.getConstructorParameters().add(fieldAccessExprMetaModel.typeArgumentsPropertyMetaModel);
+        fieldAccessExprMetaModel.getConstructorParameters().add(fieldAccessExprMetaModel.namePropertyMetaModel);
+        instanceOfExprMetaModel.getConstructorParameters().add(instanceOfExprMetaModel.expressionPropertyMetaModel);
+        instanceOfExprMetaModel.getConstructorParameters().add(instanceOfExprMetaModel.typePropertyMetaModel);
+        integerLiteralExprMetaModel.getConstructorParameters().add(literalStringValueExprMetaModel.valuePropertyMetaModel);
+        lambdaExprMetaModel.getConstructorParameters().add(lambdaExprMetaModel.parametersPropertyMetaModel);
+        lambdaExprMetaModel.getConstructorParameters().add(lambdaExprMetaModel.bodyPropertyMetaModel);
+        lambdaExprMetaModel.getConstructorParameters().add(lambdaExprMetaModel.isEnclosingParametersPropertyMetaModel);
+        longLiteralExprMetaModel.getConstructorParameters().add(literalStringValueExprMetaModel.valuePropertyMetaModel);
+        markerAnnotationExprMetaModel.getConstructorParameters().add(annotationExprMetaModel.namePropertyMetaModel);
+        memberValuePairMetaModel.getConstructorParameters().add(memberValuePairMetaModel.namePropertyMetaModel);
+        memberValuePairMetaModel.getConstructorParameters().add(memberValuePairMetaModel.valuePropertyMetaModel);
+        methodCallExprMetaModel.getConstructorParameters().add(methodCallExprMetaModel.scopePropertyMetaModel);
+        methodCallExprMetaModel.getConstructorParameters().add(methodCallExprMetaModel.typeArgumentsPropertyMetaModel);
+        methodCallExprMetaModel.getConstructorParameters().add(methodCallExprMetaModel.namePropertyMetaModel);
+        methodCallExprMetaModel.getConstructorParameters().add(methodCallExprMetaModel.argumentsPropertyMetaModel);
+        methodReferenceExprMetaModel.getConstructorParameters().add(methodReferenceExprMetaModel.scopePropertyMetaModel);
+        methodReferenceExprMetaModel.getConstructorParameters().add(methodReferenceExprMetaModel.typeArgumentsPropertyMetaModel);
+        methodReferenceExprMetaModel.getConstructorParameters().add(methodReferenceExprMetaModel.identifierPropertyMetaModel);
+        nameExprMetaModel.getConstructorParameters().add(nameExprMetaModel.namePropertyMetaModel);
+        nameMetaModel.getConstructorParameters().add(nameMetaModel.qualifierPropertyMetaModel);
+        nameMetaModel.getConstructorParameters().add(nameMetaModel.identifierPropertyMetaModel);
+        nameMetaModel.getConstructorParameters().add(nameMetaModel.annotationsPropertyMetaModel);
+        normalAnnotationExprMetaModel.getConstructorParameters().add(annotationExprMetaModel.namePropertyMetaModel);
+        normalAnnotationExprMetaModel.getConstructorParameters().add(normalAnnotationExprMetaModel.pairsPropertyMetaModel);
+        objectCreationExprMetaModel.getConstructorParameters().add(objectCreationExprMetaModel.scopePropertyMetaModel);
+        objectCreationExprMetaModel.getConstructorParameters().add(objectCreationExprMetaModel.typePropertyMetaModel);
+        objectCreationExprMetaModel.getConstructorParameters().add(objectCreationExprMetaModel.typeArgumentsPropertyMetaModel);
+        objectCreationExprMetaModel.getConstructorParameters().add(objectCreationExprMetaModel.argumentsPropertyMetaModel);
+        objectCreationExprMetaModel.getConstructorParameters().add(objectCreationExprMetaModel.anonymousClassBodyPropertyMetaModel);
+        simpleNameMetaModel.getConstructorParameters().add(simpleNameMetaModel.identifierPropertyMetaModel);
+        singleMemberAnnotationExprMetaModel.getConstructorParameters().add(annotationExprMetaModel.namePropertyMetaModel);
+        singleMemberAnnotationExprMetaModel.getConstructorParameters().add(singleMemberAnnotationExprMetaModel.memberValuePropertyMetaModel);
+        superExprMetaModel.getConstructorParameters().add(superExprMetaModel.classExprPropertyMetaModel);
+        thisExprMetaModel.getConstructorParameters().add(thisExprMetaModel.classExprPropertyMetaModel);
+        typeExprMetaModel.getConstructorParameters().add(typeExprMetaModel.typePropertyMetaModel);
+        unaryExprMetaModel.getConstructorParameters().add(unaryExprMetaModel.expressionPropertyMetaModel);
+        unaryExprMetaModel.getConstructorParameters().add(unaryExprMetaModel.operatorPropertyMetaModel);
+        variableDeclarationExprMetaModel.getConstructorParameters().add(variableDeclarationExprMetaModel.modifiersPropertyMetaModel);
+        variableDeclarationExprMetaModel.getConstructorParameters().add(variableDeclarationExprMetaModel.annotationsPropertyMetaModel);
+        variableDeclarationExprMetaModel.getConstructorParameters().add(variableDeclarationExprMetaModel.variablesPropertyMetaModel);
+        importDeclarationMetaModel.getConstructorParameters().add(importDeclarationMetaModel.namePropertyMetaModel);
+        importDeclarationMetaModel.getConstructorParameters().add(importDeclarationMetaModel.isStaticPropertyMetaModel);
+        importDeclarationMetaModel.getConstructorParameters().add(importDeclarationMetaModel.isAsteriskPropertyMetaModel);
+        assertStmtMetaModel.getConstructorParameters().add(assertStmtMetaModel.checkPropertyMetaModel);
+        assertStmtMetaModel.getConstructorParameters().add(assertStmtMetaModel.messagePropertyMetaModel);
+        blockStmtMetaModel.getConstructorParameters().add(blockStmtMetaModel.statementsPropertyMetaModel);
+        breakStmtMetaModel.getConstructorParameters().add(breakStmtMetaModel.labelPropertyMetaModel);
+        catchClauseMetaModel.getConstructorParameters().add(catchClauseMetaModel.parameterPropertyMetaModel);
+        catchClauseMetaModel.getConstructorParameters().add(catchClauseMetaModel.bodyPropertyMetaModel);
+        continueStmtMetaModel.getConstructorParameters().add(continueStmtMetaModel.labelPropertyMetaModel);
+        doStmtMetaModel.getConstructorParameters().add(doStmtMetaModel.bodyPropertyMetaModel);
+        doStmtMetaModel.getConstructorParameters().add(doStmtMetaModel.conditionPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.getConstructorParameters().add(explicitConstructorInvocationStmtMetaModel.typeArgumentsPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.getConstructorParameters().add(explicitConstructorInvocationStmtMetaModel.isThisPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.getConstructorParameters().add(explicitConstructorInvocationStmtMetaModel.expressionPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.getConstructorParameters().add(explicitConstructorInvocationStmtMetaModel.argumentsPropertyMetaModel);
+        expressionStmtMetaModel.getConstructorParameters().add(expressionStmtMetaModel.expressionPropertyMetaModel);
+        foreachStmtMetaModel.getConstructorParameters().add(foreachStmtMetaModel.variablePropertyMetaModel);
+        foreachStmtMetaModel.getConstructorParameters().add(foreachStmtMetaModel.iterablePropertyMetaModel);
+        foreachStmtMetaModel.getConstructorParameters().add(foreachStmtMetaModel.bodyPropertyMetaModel);
+        forStmtMetaModel.getConstructorParameters().add(forStmtMetaModel.initializationPropertyMetaModel);
+        forStmtMetaModel.getConstructorParameters().add(forStmtMetaModel.comparePropertyMetaModel);
+        forStmtMetaModel.getConstructorParameters().add(forStmtMetaModel.updatePropertyMetaModel);
+        forStmtMetaModel.getConstructorParameters().add(forStmtMetaModel.bodyPropertyMetaModel);
+        ifStmtMetaModel.getConstructorParameters().add(ifStmtMetaModel.conditionPropertyMetaModel);
+        ifStmtMetaModel.getConstructorParameters().add(ifStmtMetaModel.thenStmtPropertyMetaModel);
+        ifStmtMetaModel.getConstructorParameters().add(ifStmtMetaModel.elseStmtPropertyMetaModel);
+        labeledStmtMetaModel.getConstructorParameters().add(labeledStmtMetaModel.labelPropertyMetaModel);
+        labeledStmtMetaModel.getConstructorParameters().add(labeledStmtMetaModel.statementPropertyMetaModel);
+        returnStmtMetaModel.getConstructorParameters().add(returnStmtMetaModel.expressionPropertyMetaModel);
+        switchEntryStmtMetaModel.getConstructorParameters().add(switchEntryStmtMetaModel.labelPropertyMetaModel);
+        switchEntryStmtMetaModel.getConstructorParameters().add(switchEntryStmtMetaModel.statementsPropertyMetaModel);
+        switchStmtMetaModel.getConstructorParameters().add(switchStmtMetaModel.selectorPropertyMetaModel);
+        switchStmtMetaModel.getConstructorParameters().add(switchStmtMetaModel.entriesPropertyMetaModel);
+        synchronizedStmtMetaModel.getConstructorParameters().add(synchronizedStmtMetaModel.expressionPropertyMetaModel);
+        synchronizedStmtMetaModel.getConstructorParameters().add(synchronizedStmtMetaModel.bodyPropertyMetaModel);
+        throwStmtMetaModel.getConstructorParameters().add(throwStmtMetaModel.expressionPropertyMetaModel);
+        tryStmtMetaModel.getConstructorParameters().add(tryStmtMetaModel.resourcesPropertyMetaModel);
+        tryStmtMetaModel.getConstructorParameters().add(tryStmtMetaModel.tryBlockPropertyMetaModel);
+        tryStmtMetaModel.getConstructorParameters().add(tryStmtMetaModel.catchClausesPropertyMetaModel);
+        tryStmtMetaModel.getConstructorParameters().add(tryStmtMetaModel.finallyBlockPropertyMetaModel);
+        localClassDeclarationStmtMetaModel.getConstructorParameters().add(localClassDeclarationStmtMetaModel.classDeclarationPropertyMetaModel);
+        whileStmtMetaModel.getConstructorParameters().add(whileStmtMetaModel.conditionPropertyMetaModel);
+        whileStmtMetaModel.getConstructorParameters().add(whileStmtMetaModel.bodyPropertyMetaModel);
+        arrayTypeMetaModel.getConstructorParameters().add(arrayTypeMetaModel.componentTypePropertyMetaModel);
+        arrayTypeMetaModel.getConstructorParameters().add(arrayTypeMetaModel.originPropertyMetaModel);
+        arrayTypeMetaModel.getConstructorParameters().add(typeMetaModel.annotationsPropertyMetaModel);
+        classOrInterfaceTypeMetaModel.getConstructorParameters().add(classOrInterfaceTypeMetaModel.scopePropertyMetaModel);
+        classOrInterfaceTypeMetaModel.getConstructorParameters().add(classOrInterfaceTypeMetaModel.namePropertyMetaModel);
+        classOrInterfaceTypeMetaModel.getConstructorParameters().add(classOrInterfaceTypeMetaModel.typeArgumentsPropertyMetaModel);
+        classOrInterfaceTypeMetaModel.getConstructorParameters().add(typeMetaModel.annotationsPropertyMetaModel);
+        intersectionTypeMetaModel.getConstructorParameters().add(intersectionTypeMetaModel.elementsPropertyMetaModel);
+        primitiveTypeMetaModel.getConstructorParameters().add(primitiveTypeMetaModel.typePropertyMetaModel);
+        primitiveTypeMetaModel.getConstructorParameters().add(typeMetaModel.annotationsPropertyMetaModel);
+        typeParameterMetaModel.getConstructorParameters().add(typeParameterMetaModel.namePropertyMetaModel);
+        typeParameterMetaModel.getConstructorParameters().add(typeParameterMetaModel.typeBoundPropertyMetaModel);
+        typeParameterMetaModel.getConstructorParameters().add(typeMetaModel.annotationsPropertyMetaModel);
+        unionTypeMetaModel.getConstructorParameters().add(unionTypeMetaModel.elementsPropertyMetaModel);
+        wildcardTypeMetaModel.getConstructorParameters().add(wildcardTypeMetaModel.extendedTypePropertyMetaModel);
+        wildcardTypeMetaModel.getConstructorParameters().add(wildcardTypeMetaModel.superTypePropertyMetaModel);
+        wildcardTypeMetaModel.getConstructorParameters().add(typeMetaModel.annotationsPropertyMetaModel);
+        moduleRequiresStmtMetaModel.getConstructorParameters().add(moduleRequiresStmtMetaModel.modifiersPropertyMetaModel);
+        moduleRequiresStmtMetaModel.getConstructorParameters().add(moduleRequiresStmtMetaModel.namePropertyMetaModel);
+        moduleExportsStmtMetaModel.getConstructorParameters().add(moduleExportsStmtMetaModel.namePropertyMetaModel);
+        moduleExportsStmtMetaModel.getConstructorParameters().add(moduleExportsStmtMetaModel.moduleNamesPropertyMetaModel);
+        moduleProvidesStmtMetaModel.getConstructorParameters().add(moduleProvidesStmtMetaModel.typePropertyMetaModel);
+        moduleProvidesStmtMetaModel.getConstructorParameters().add(moduleProvidesStmtMetaModel.withTypesPropertyMetaModel);
+        moduleUsesStmtMetaModel.getConstructorParameters().add(moduleUsesStmtMetaModel.typePropertyMetaModel);
+        moduleOpensStmtMetaModel.getConstructorParameters().add(moduleOpensStmtMetaModel.namePropertyMetaModel);
+        moduleOpensStmtMetaModel.getConstructorParameters().add(moduleOpensStmtMetaModel.moduleNamesPropertyMetaModel);
+    }
+
+    public static List<BaseNodeMetaModel> getNodeMetaModels() {
+        return nodeMetaModels;
+    }
+
+    private static void initializeNodeMetaModels() {
+        nodeMetaModels.add(annotationDeclarationMetaModel);
+        nodeMetaModels.add(annotationExprMetaModel);
+        nodeMetaModels.add(annotationMemberDeclarationMetaModel);
+        nodeMetaModels.add(arrayAccessExprMetaModel);
+        nodeMetaModels.add(arrayCreationExprMetaModel);
+        nodeMetaModels.add(arrayCreationLevelMetaModel);
+        nodeMetaModels.add(arrayInitializerExprMetaModel);
+        nodeMetaModels.add(arrayTypeMetaModel);
+        nodeMetaModels.add(assertStmtMetaModel);
+        nodeMetaModels.add(assignExprMetaModel);
+        nodeMetaModels.add(binaryExprMetaModel);
+        nodeMetaModels.add(blockCommentMetaModel);
+        nodeMetaModels.add(blockStmtMetaModel);
+        nodeMetaModels.add(bodyDeclarationMetaModel);
+        nodeMetaModels.add(booleanLiteralExprMetaModel);
+        nodeMetaModels.add(breakStmtMetaModel);
+        nodeMetaModels.add(callableDeclarationMetaModel);
+        nodeMetaModels.add(castExprMetaModel);
+        nodeMetaModels.add(catchClauseMetaModel);
+        nodeMetaModels.add(charLiteralExprMetaModel);
+        nodeMetaModels.add(classExprMetaModel);
+        nodeMetaModels.add(classOrInterfaceDeclarationMetaModel);
+        nodeMetaModels.add(classOrInterfaceTypeMetaModel);
+        nodeMetaModels.add(commentMetaModel);
+        nodeMetaModels.add(compilationUnitMetaModel);
+        nodeMetaModels.add(conditionalExprMetaModel);
+        nodeMetaModels.add(constructorDeclarationMetaModel);
+        nodeMetaModels.add(continueStmtMetaModel);
+        nodeMetaModels.add(doStmtMetaModel);
+        nodeMetaModels.add(doubleLiteralExprMetaModel);
+        nodeMetaModels.add(emptyStmtMetaModel);
+        nodeMetaModels.add(enclosedExprMetaModel);
+        nodeMetaModels.add(enumConstantDeclarationMetaModel);
+        nodeMetaModels.add(enumDeclarationMetaModel);
+        nodeMetaModels.add(explicitConstructorInvocationStmtMetaModel);
+        nodeMetaModels.add(expressionMetaModel);
+        nodeMetaModels.add(expressionStmtMetaModel);
+        nodeMetaModels.add(fieldAccessExprMetaModel);
+        nodeMetaModels.add(fieldDeclarationMetaModel);
+        nodeMetaModels.add(forStmtMetaModel);
+        nodeMetaModels.add(foreachStmtMetaModel);
+        nodeMetaModels.add(ifStmtMetaModel);
+        nodeMetaModels.add(importDeclarationMetaModel);
+        nodeMetaModels.add(initializerDeclarationMetaModel);
+        nodeMetaModels.add(instanceOfExprMetaModel);
+        nodeMetaModels.add(integerLiteralExprMetaModel);
+        nodeMetaModels.add(intersectionTypeMetaModel);
+        nodeMetaModels.add(javadocCommentMetaModel);
+        nodeMetaModels.add(labeledStmtMetaModel);
+        nodeMetaModels.add(lambdaExprMetaModel);
+        nodeMetaModels.add(lineCommentMetaModel);
+        nodeMetaModels.add(literalExprMetaModel);
+        nodeMetaModels.add(literalStringValueExprMetaModel);
+        nodeMetaModels.add(localClassDeclarationStmtMetaModel);
+        nodeMetaModels.add(longLiteralExprMetaModel);
+        nodeMetaModels.add(markerAnnotationExprMetaModel);
+        nodeMetaModels.add(memberValuePairMetaModel);
+        nodeMetaModels.add(methodCallExprMetaModel);
+        nodeMetaModels.add(methodDeclarationMetaModel);
+        nodeMetaModels.add(methodReferenceExprMetaModel);
+        nodeMetaModels.add(moduleDeclarationMetaModel);
+        nodeMetaModels.add(moduleExportsStmtMetaModel);
+        nodeMetaModels.add(moduleOpensStmtMetaModel);
+        nodeMetaModels.add(moduleProvidesStmtMetaModel);
+        nodeMetaModels.add(moduleRequiresStmtMetaModel);
+        nodeMetaModels.add(moduleStmtMetaModel);
+        nodeMetaModels.add(moduleUsesStmtMetaModel);
+        nodeMetaModels.add(nameExprMetaModel);
+        nodeMetaModels.add(nameMetaModel);
+        nodeMetaModels.add(nodeMetaModel);
+        nodeMetaModels.add(normalAnnotationExprMetaModel);
+        nodeMetaModels.add(nullLiteralExprMetaModel);
+        nodeMetaModels.add(objectCreationExprMetaModel);
+        nodeMetaModels.add(packageDeclarationMetaModel);
+        nodeMetaModels.add(parameterMetaModel);
+        nodeMetaModels.add(primitiveTypeMetaModel);
+        nodeMetaModels.add(receiverParameterMetaModel);
+        nodeMetaModels.add(referenceTypeMetaModel);
+        nodeMetaModels.add(returnStmtMetaModel);
+        nodeMetaModels.add(simpleNameMetaModel);
+        nodeMetaModels.add(singleMemberAnnotationExprMetaModel);
+        nodeMetaModels.add(statementMetaModel);
+        nodeMetaModels.add(stringLiteralExprMetaModel);
+        nodeMetaModels.add(superExprMetaModel);
+        nodeMetaModels.add(switchEntryStmtMetaModel);
+        nodeMetaModels.add(switchStmtMetaModel);
+        nodeMetaModels.add(synchronizedStmtMetaModel);
+        nodeMetaModels.add(thisExprMetaModel);
+        nodeMetaModels.add(throwStmtMetaModel);
+        nodeMetaModels.add(tryStmtMetaModel);
+        nodeMetaModels.add(typeDeclarationMetaModel);
+        nodeMetaModels.add(typeExprMetaModel);
+        nodeMetaModels.add(typeMetaModel);
+        nodeMetaModels.add(typeParameterMetaModel);
+        nodeMetaModels.add(unaryExprMetaModel);
+        nodeMetaModels.add(unionTypeMetaModel);
+        nodeMetaModels.add(unknownTypeMetaModel);
+        nodeMetaModels.add(unparsableStmtMetaModel);
+        nodeMetaModels.add(varTypeMetaModel);
+        nodeMetaModels.add(variableDeclarationExprMetaModel);
+        nodeMetaModels.add(variableDeclaratorMetaModel);
+        nodeMetaModels.add(voidTypeMetaModel);
+        nodeMetaModels.add(whileStmtMetaModel);
+        nodeMetaModels.add(wildcardTypeMetaModel);
+    }
+
+    private static void initializePropertyMetaModels() {
+        nodeMetaModel.commentPropertyMetaModel = new PropertyMetaModel(nodeMetaModel, "comment", com.github.javaparser.ast.comments.Comment.class, Optional.of(commentMetaModel), true, false, false, false, false);
+        nodeMetaModel.getDeclaredPropertyMetaModels().add(nodeMetaModel.commentPropertyMetaModel);
+        bodyDeclarationMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(bodyDeclarationMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        bodyDeclarationMetaModel.getDeclaredPropertyMetaModels().add(bodyDeclarationMetaModel.annotationsPropertyMetaModel);
+        callableDeclarationMetaModel.modifiersPropertyMetaModel = new PropertyMetaModel(callableDeclarationMetaModel, "modifiers", com.github.javaparser.ast.Modifier.class, Optional.empty(), false, false, false, true, false);
+        callableDeclarationMetaModel.getDeclaredPropertyMetaModels().add(callableDeclarationMetaModel.modifiersPropertyMetaModel);
+        callableDeclarationMetaModel.namePropertyMetaModel = new PropertyMetaModel(callableDeclarationMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        callableDeclarationMetaModel.getDeclaredPropertyMetaModels().add(callableDeclarationMetaModel.namePropertyMetaModel);
+        callableDeclarationMetaModel.parametersPropertyMetaModel = new PropertyMetaModel(callableDeclarationMetaModel, "parameters", com.github.javaparser.ast.body.Parameter.class, Optional.of(parameterMetaModel), false, false, true, false, false);
+        callableDeclarationMetaModel.getDeclaredPropertyMetaModels().add(callableDeclarationMetaModel.parametersPropertyMetaModel);
+        callableDeclarationMetaModel.receiverParameterPropertyMetaModel = new PropertyMetaModel(callableDeclarationMetaModel, "receiverParameter", com.github.javaparser.ast.body.ReceiverParameter.class, Optional.of(receiverParameterMetaModel), true, false, false, false, false);
+        callableDeclarationMetaModel.getDeclaredPropertyMetaModels().add(callableDeclarationMetaModel.receiverParameterPropertyMetaModel);
+        callableDeclarationMetaModel.thrownExceptionsPropertyMetaModel = new PropertyMetaModel(callableDeclarationMetaModel, "thrownExceptions", com.github.javaparser.ast.type.ReferenceType.class, Optional.of(referenceTypeMetaModel), false, false, true, false, false);
+        callableDeclarationMetaModel.getDeclaredPropertyMetaModels().add(callableDeclarationMetaModel.thrownExceptionsPropertyMetaModel);
+        callableDeclarationMetaModel.typeParametersPropertyMetaModel = new PropertyMetaModel(callableDeclarationMetaModel, "typeParameters", com.github.javaparser.ast.type.TypeParameter.class, Optional.of(typeParameterMetaModel), false, false, true, false, false);
+        callableDeclarationMetaModel.getDeclaredPropertyMetaModels().add(callableDeclarationMetaModel.typeParametersPropertyMetaModel);
+        typeMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(typeMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        typeMetaModel.getDeclaredPropertyMetaModels().add(typeMetaModel.annotationsPropertyMetaModel);
+        annotationExprMetaModel.namePropertyMetaModel = new PropertyMetaModel(annotationExprMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        annotationExprMetaModel.getDeclaredPropertyMetaModels().add(annotationExprMetaModel.namePropertyMetaModel);
+        typeDeclarationMetaModel.membersPropertyMetaModel = new PropertyMetaModel(typeDeclarationMetaModel, "members", com.github.javaparser.ast.body.BodyDeclaration.class, Optional.of(bodyDeclarationMetaModel), false, false, true, false, true);
+        typeDeclarationMetaModel.getDeclaredPropertyMetaModels().add(typeDeclarationMetaModel.membersPropertyMetaModel);
+        typeDeclarationMetaModel.modifiersPropertyMetaModel = new PropertyMetaModel(typeDeclarationMetaModel, "modifiers", com.github.javaparser.ast.Modifier.class, Optional.empty(), false, false, false, true, false);
+        typeDeclarationMetaModel.getDeclaredPropertyMetaModels().add(typeDeclarationMetaModel.modifiersPropertyMetaModel);
+        typeDeclarationMetaModel.namePropertyMetaModel = new PropertyMetaModel(typeDeclarationMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        typeDeclarationMetaModel.getDeclaredPropertyMetaModels().add(typeDeclarationMetaModel.namePropertyMetaModel);
+        literalStringValueExprMetaModel.valuePropertyMetaModel = new PropertyMetaModel(literalStringValueExprMetaModel, "value", java.lang.String.class, Optional.empty(), false, false, false, false, false);
+        literalStringValueExprMetaModel.getDeclaredPropertyMetaModels().add(literalStringValueExprMetaModel.valuePropertyMetaModel);
+        moduleDeclarationMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(moduleDeclarationMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        moduleDeclarationMetaModel.getDeclaredPropertyMetaModels().add(moduleDeclarationMetaModel.annotationsPropertyMetaModel);
+        moduleDeclarationMetaModel.isOpenPropertyMetaModel = new PropertyMetaModel(moduleDeclarationMetaModel, "isOpen", boolean.class, Optional.empty(), false, false, false, false, false);
+        moduleDeclarationMetaModel.getDeclaredPropertyMetaModels().add(moduleDeclarationMetaModel.isOpenPropertyMetaModel);
+        moduleDeclarationMetaModel.moduleStmtsPropertyMetaModel = new PropertyMetaModel(moduleDeclarationMetaModel, "moduleStmts", com.github.javaparser.ast.modules.ModuleStmt.class, Optional.of(moduleStmtMetaModel), false, false, true, false, false);
+        moduleDeclarationMetaModel.getDeclaredPropertyMetaModels().add(moduleDeclarationMetaModel.moduleStmtsPropertyMetaModel);
+        moduleDeclarationMetaModel.namePropertyMetaModel = new PropertyMetaModel(moduleDeclarationMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        moduleDeclarationMetaModel.getDeclaredPropertyMetaModels().add(moduleDeclarationMetaModel.namePropertyMetaModel);
+        arrayCreationLevelMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(arrayCreationLevelMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        arrayCreationLevelMetaModel.getDeclaredPropertyMetaModels().add(arrayCreationLevelMetaModel.annotationsPropertyMetaModel);
+        arrayCreationLevelMetaModel.dimensionPropertyMetaModel = new PropertyMetaModel(arrayCreationLevelMetaModel, "dimension", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        arrayCreationLevelMetaModel.getDeclaredPropertyMetaModels().add(arrayCreationLevelMetaModel.dimensionPropertyMetaModel);
+        compilationUnitMetaModel.importsPropertyMetaModel = new PropertyMetaModel(compilationUnitMetaModel, "imports", com.github.javaparser.ast.ImportDeclaration.class, Optional.of(importDeclarationMetaModel), false, false, true, false, false);
+        compilationUnitMetaModel.getDeclaredPropertyMetaModels().add(compilationUnitMetaModel.importsPropertyMetaModel);
+        compilationUnitMetaModel.modulePropertyMetaModel = new PropertyMetaModel(compilationUnitMetaModel, "module", com.github.javaparser.ast.modules.ModuleDeclaration.class, Optional.of(moduleDeclarationMetaModel), true, false, false, false, false);
+        compilationUnitMetaModel.getDeclaredPropertyMetaModels().add(compilationUnitMetaModel.modulePropertyMetaModel);
+        compilationUnitMetaModel.packageDeclarationPropertyMetaModel = new PropertyMetaModel(compilationUnitMetaModel, "packageDeclaration", com.github.javaparser.ast.PackageDeclaration.class, Optional.of(packageDeclarationMetaModel), true, false, false, false, false);
+        compilationUnitMetaModel.getDeclaredPropertyMetaModels().add(compilationUnitMetaModel.packageDeclarationPropertyMetaModel);
+        compilationUnitMetaModel.typesPropertyMetaModel = new PropertyMetaModel(compilationUnitMetaModel, "types", com.github.javaparser.ast.body.TypeDeclaration.class, Optional.of(typeDeclarationMetaModel), false, false, true, false, true);
+        compilationUnitMetaModel.getDeclaredPropertyMetaModels().add(compilationUnitMetaModel.typesPropertyMetaModel);
+        packageDeclarationMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(packageDeclarationMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        packageDeclarationMetaModel.getDeclaredPropertyMetaModels().add(packageDeclarationMetaModel.annotationsPropertyMetaModel);
+        packageDeclarationMetaModel.namePropertyMetaModel = new PropertyMetaModel(packageDeclarationMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        packageDeclarationMetaModel.getDeclaredPropertyMetaModels().add(packageDeclarationMetaModel.namePropertyMetaModel);
+        annotationMemberDeclarationMetaModel.defaultValuePropertyMetaModel = new PropertyMetaModel(annotationMemberDeclarationMetaModel, "defaultValue", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        annotationMemberDeclarationMetaModel.getDeclaredPropertyMetaModels().add(annotationMemberDeclarationMetaModel.defaultValuePropertyMetaModel);
+        annotationMemberDeclarationMetaModel.modifiersPropertyMetaModel = new PropertyMetaModel(annotationMemberDeclarationMetaModel, "modifiers", com.github.javaparser.ast.Modifier.class, Optional.empty(), false, false, false, true, false);
+        annotationMemberDeclarationMetaModel.getDeclaredPropertyMetaModels().add(annotationMemberDeclarationMetaModel.modifiersPropertyMetaModel);
+        annotationMemberDeclarationMetaModel.namePropertyMetaModel = new PropertyMetaModel(annotationMemberDeclarationMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        annotationMemberDeclarationMetaModel.getDeclaredPropertyMetaModels().add(annotationMemberDeclarationMetaModel.namePropertyMetaModel);
+        annotationMemberDeclarationMetaModel.typePropertyMetaModel = new PropertyMetaModel(annotationMemberDeclarationMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        annotationMemberDeclarationMetaModel.getDeclaredPropertyMetaModels().add(annotationMemberDeclarationMetaModel.typePropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.extendedTypesPropertyMetaModel = new PropertyMetaModel(classOrInterfaceDeclarationMetaModel, "extendedTypes", com.github.javaparser.ast.type.ClassOrInterfaceType.class, Optional.of(classOrInterfaceTypeMetaModel), false, false, true, false, false);
+        classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.extendedTypesPropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.implementedTypesPropertyMetaModel = new PropertyMetaModel(classOrInterfaceDeclarationMetaModel, "implementedTypes", com.github.javaparser.ast.type.ClassOrInterfaceType.class, Optional.of(classOrInterfaceTypeMetaModel), false, false, true, false, false);
+        classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.implementedTypesPropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.isInterfacePropertyMetaModel = new PropertyMetaModel(classOrInterfaceDeclarationMetaModel, "isInterface", boolean.class, Optional.empty(), false, false, false, false, false);
+        classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.isInterfacePropertyMetaModel);
+        classOrInterfaceDeclarationMetaModel.typeParametersPropertyMetaModel = new PropertyMetaModel(classOrInterfaceDeclarationMetaModel, "typeParameters", com.github.javaparser.ast.type.TypeParameter.class, Optional.of(typeParameterMetaModel), false, false, true, false, false);
+        classOrInterfaceDeclarationMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceDeclarationMetaModel.typeParametersPropertyMetaModel);
+        constructorDeclarationMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(constructorDeclarationMetaModel, "body", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), false, false, false, false, false);
+        constructorDeclarationMetaModel.getDeclaredPropertyMetaModels().add(constructorDeclarationMetaModel.bodyPropertyMetaModel);
+        enumConstantDeclarationMetaModel.argumentsPropertyMetaModel = new PropertyMetaModel(enumConstantDeclarationMetaModel, "arguments", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        enumConstantDeclarationMetaModel.getDeclaredPropertyMetaModels().add(enumConstantDeclarationMetaModel.argumentsPropertyMetaModel);
+        enumConstantDeclarationMetaModel.classBodyPropertyMetaModel = new PropertyMetaModel(enumConstantDeclarationMetaModel, "classBody", com.github.javaparser.ast.body.BodyDeclaration.class, Optional.of(bodyDeclarationMetaModel), false, false, true, false, true);
+        enumConstantDeclarationMetaModel.getDeclaredPropertyMetaModels().add(enumConstantDeclarationMetaModel.classBodyPropertyMetaModel);
+        enumConstantDeclarationMetaModel.namePropertyMetaModel = new PropertyMetaModel(enumConstantDeclarationMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        enumConstantDeclarationMetaModel.getDeclaredPropertyMetaModels().add(enumConstantDeclarationMetaModel.namePropertyMetaModel);
+        enumDeclarationMetaModel.entriesPropertyMetaModel = new PropertyMetaModel(enumDeclarationMetaModel, "entries", com.github.javaparser.ast.body.EnumConstantDeclaration.class, Optional.of(enumConstantDeclarationMetaModel), false, false, true, false, false);
+        enumDeclarationMetaModel.getDeclaredPropertyMetaModels().add(enumDeclarationMetaModel.entriesPropertyMetaModel);
+        enumDeclarationMetaModel.implementedTypesPropertyMetaModel = new PropertyMetaModel(enumDeclarationMetaModel, "implementedTypes", com.github.javaparser.ast.type.ClassOrInterfaceType.class, Optional.of(classOrInterfaceTypeMetaModel), false, false, true, false, false);
+        enumDeclarationMetaModel.getDeclaredPropertyMetaModels().add(enumDeclarationMetaModel.implementedTypesPropertyMetaModel);
+        fieldDeclarationMetaModel.modifiersPropertyMetaModel = new PropertyMetaModel(fieldDeclarationMetaModel, "modifiers", com.github.javaparser.ast.Modifier.class, Optional.empty(), false, false, false, true, false);
+        fieldDeclarationMetaModel.getDeclaredPropertyMetaModels().add(fieldDeclarationMetaModel.modifiersPropertyMetaModel);
+        fieldDeclarationMetaModel.variablesPropertyMetaModel = new PropertyMetaModel(fieldDeclarationMetaModel, "variables", com.github.javaparser.ast.body.VariableDeclarator.class, Optional.of(variableDeclaratorMetaModel), false, true, true, false, false);
+        fieldDeclarationMetaModel.getDeclaredPropertyMetaModels().add(fieldDeclarationMetaModel.variablesPropertyMetaModel);
+        fieldDeclarationMetaModel.maximumCommonTypePropertyMetaModel = new PropertyMetaModel(fieldDeclarationMetaModel, "maximumCommonType", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, false, false, false);
+        fieldDeclarationMetaModel.getDerivedPropertyMetaModels().add(fieldDeclarationMetaModel.maximumCommonTypePropertyMetaModel);
+        initializerDeclarationMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(initializerDeclarationMetaModel, "body", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), false, false, false, false, false);
+        initializerDeclarationMetaModel.getDeclaredPropertyMetaModels().add(initializerDeclarationMetaModel.bodyPropertyMetaModel);
+        initializerDeclarationMetaModel.isStaticPropertyMetaModel = new PropertyMetaModel(initializerDeclarationMetaModel, "isStatic", boolean.class, Optional.empty(), false, false, false, false, false);
+        initializerDeclarationMetaModel.getDeclaredPropertyMetaModels().add(initializerDeclarationMetaModel.isStaticPropertyMetaModel);
+        methodDeclarationMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(methodDeclarationMetaModel, "body", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), true, false, false, false, false);
+        methodDeclarationMetaModel.getDeclaredPropertyMetaModels().add(methodDeclarationMetaModel.bodyPropertyMetaModel);
+        methodDeclarationMetaModel.typePropertyMetaModel = new PropertyMetaModel(methodDeclarationMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        methodDeclarationMetaModel.getDeclaredPropertyMetaModels().add(methodDeclarationMetaModel.typePropertyMetaModel);
+        parameterMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(parameterMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        parameterMetaModel.getDeclaredPropertyMetaModels().add(parameterMetaModel.annotationsPropertyMetaModel);
+        parameterMetaModel.isVarArgsPropertyMetaModel = new PropertyMetaModel(parameterMetaModel, "isVarArgs", boolean.class, Optional.empty(), false, false, false, false, false);
+        parameterMetaModel.getDeclaredPropertyMetaModels().add(parameterMetaModel.isVarArgsPropertyMetaModel);
+        parameterMetaModel.modifiersPropertyMetaModel = new PropertyMetaModel(parameterMetaModel, "modifiers", com.github.javaparser.ast.Modifier.class, Optional.empty(), false, false, false, true, false);
+        parameterMetaModel.getDeclaredPropertyMetaModels().add(parameterMetaModel.modifiersPropertyMetaModel);
+        parameterMetaModel.namePropertyMetaModel = new PropertyMetaModel(parameterMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        parameterMetaModel.getDeclaredPropertyMetaModels().add(parameterMetaModel.namePropertyMetaModel);
+        parameterMetaModel.typePropertyMetaModel = new PropertyMetaModel(parameterMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        parameterMetaModel.getDeclaredPropertyMetaModels().add(parameterMetaModel.typePropertyMetaModel);
+        parameterMetaModel.varArgsAnnotationsPropertyMetaModel = new PropertyMetaModel(parameterMetaModel, "varArgsAnnotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        parameterMetaModel.getDeclaredPropertyMetaModels().add(parameterMetaModel.varArgsAnnotationsPropertyMetaModel);
+        receiverParameterMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(receiverParameterMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        receiverParameterMetaModel.getDeclaredPropertyMetaModels().add(receiverParameterMetaModel.annotationsPropertyMetaModel);
+        receiverParameterMetaModel.namePropertyMetaModel = new PropertyMetaModel(receiverParameterMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        receiverParameterMetaModel.getDeclaredPropertyMetaModels().add(receiverParameterMetaModel.namePropertyMetaModel);
+        receiverParameterMetaModel.typePropertyMetaModel = new PropertyMetaModel(receiverParameterMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        receiverParameterMetaModel.getDeclaredPropertyMetaModels().add(receiverParameterMetaModel.typePropertyMetaModel);
+        variableDeclaratorMetaModel.initializerPropertyMetaModel = new PropertyMetaModel(variableDeclaratorMetaModel, "initializer", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, true, false, false, false);
+        variableDeclaratorMetaModel.getDeclaredPropertyMetaModels().add(variableDeclaratorMetaModel.initializerPropertyMetaModel);
+        variableDeclaratorMetaModel.namePropertyMetaModel = new PropertyMetaModel(variableDeclaratorMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        variableDeclaratorMetaModel.getDeclaredPropertyMetaModels().add(variableDeclaratorMetaModel.namePropertyMetaModel);
+        variableDeclaratorMetaModel.typePropertyMetaModel = new PropertyMetaModel(variableDeclaratorMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        variableDeclaratorMetaModel.getDeclaredPropertyMetaModels().add(variableDeclaratorMetaModel.typePropertyMetaModel);
+        commentMetaModel.contentPropertyMetaModel = new PropertyMetaModel(commentMetaModel, "content", java.lang.String.class, Optional.empty(), false, false, false, false, false);
+        commentMetaModel.getDeclaredPropertyMetaModels().add(commentMetaModel.contentPropertyMetaModel);
+        arrayAccessExprMetaModel.indexPropertyMetaModel = new PropertyMetaModel(arrayAccessExprMetaModel, "index", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        arrayAccessExprMetaModel.getDeclaredPropertyMetaModels().add(arrayAccessExprMetaModel.indexPropertyMetaModel);
+        arrayAccessExprMetaModel.namePropertyMetaModel = new PropertyMetaModel(arrayAccessExprMetaModel, "name", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        arrayAccessExprMetaModel.getDeclaredPropertyMetaModels().add(arrayAccessExprMetaModel.namePropertyMetaModel);
+        arrayCreationExprMetaModel.elementTypePropertyMetaModel = new PropertyMetaModel(arrayCreationExprMetaModel, "elementType", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        arrayCreationExprMetaModel.getDeclaredPropertyMetaModels().add(arrayCreationExprMetaModel.elementTypePropertyMetaModel);
+        arrayCreationExprMetaModel.initializerPropertyMetaModel = new PropertyMetaModel(arrayCreationExprMetaModel, "initializer", com.github.javaparser.ast.expr.ArrayInitializerExpr.class, Optional.of(arrayInitializerExprMetaModel), true, false, false, false, false);
+        arrayCreationExprMetaModel.getDeclaredPropertyMetaModels().add(arrayCreationExprMetaModel.initializerPropertyMetaModel);
+        arrayCreationExprMetaModel.levelsPropertyMetaModel = new PropertyMetaModel(arrayCreationExprMetaModel, "levels", com.github.javaparser.ast.ArrayCreationLevel.class, Optional.of(arrayCreationLevelMetaModel), false, true, true, false, false);
+        arrayCreationExprMetaModel.getDeclaredPropertyMetaModels().add(arrayCreationExprMetaModel.levelsPropertyMetaModel);
+        arrayInitializerExprMetaModel.valuesPropertyMetaModel = new PropertyMetaModel(arrayInitializerExprMetaModel, "values", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        arrayInitializerExprMetaModel.getDeclaredPropertyMetaModels().add(arrayInitializerExprMetaModel.valuesPropertyMetaModel);
+        assignExprMetaModel.operatorPropertyMetaModel = new PropertyMetaModel(assignExprMetaModel, "operator", com.github.javaparser.ast.expr.AssignExpr.Operator.class, Optional.empty(), false, false, false, false, false);
+        assignExprMetaModel.getDeclaredPropertyMetaModels().add(assignExprMetaModel.operatorPropertyMetaModel);
+        assignExprMetaModel.targetPropertyMetaModel = new PropertyMetaModel(assignExprMetaModel, "target", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        assignExprMetaModel.getDeclaredPropertyMetaModels().add(assignExprMetaModel.targetPropertyMetaModel);
+        assignExprMetaModel.valuePropertyMetaModel = new PropertyMetaModel(assignExprMetaModel, "value", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        assignExprMetaModel.getDeclaredPropertyMetaModels().add(assignExprMetaModel.valuePropertyMetaModel);
+        binaryExprMetaModel.leftPropertyMetaModel = new PropertyMetaModel(binaryExprMetaModel, "left", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        binaryExprMetaModel.getDeclaredPropertyMetaModels().add(binaryExprMetaModel.leftPropertyMetaModel);
+        binaryExprMetaModel.operatorPropertyMetaModel = new PropertyMetaModel(binaryExprMetaModel, "operator", com.github.javaparser.ast.expr.BinaryExpr.Operator.class, Optional.empty(), false, false, false, false, false);
+        binaryExprMetaModel.getDeclaredPropertyMetaModels().add(binaryExprMetaModel.operatorPropertyMetaModel);
+        binaryExprMetaModel.rightPropertyMetaModel = new PropertyMetaModel(binaryExprMetaModel, "right", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        binaryExprMetaModel.getDeclaredPropertyMetaModels().add(binaryExprMetaModel.rightPropertyMetaModel);
+        booleanLiteralExprMetaModel.valuePropertyMetaModel = new PropertyMetaModel(booleanLiteralExprMetaModel, "value", boolean.class, Optional.empty(), false, false, false, false, false);
+        booleanLiteralExprMetaModel.getDeclaredPropertyMetaModels().add(booleanLiteralExprMetaModel.valuePropertyMetaModel);
+        castExprMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(castExprMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        castExprMetaModel.getDeclaredPropertyMetaModels().add(castExprMetaModel.expressionPropertyMetaModel);
+        castExprMetaModel.typePropertyMetaModel = new PropertyMetaModel(castExprMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        castExprMetaModel.getDeclaredPropertyMetaModels().add(castExprMetaModel.typePropertyMetaModel);
+        classExprMetaModel.typePropertyMetaModel = new PropertyMetaModel(classExprMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        classExprMetaModel.getDeclaredPropertyMetaModels().add(classExprMetaModel.typePropertyMetaModel);
+        conditionalExprMetaModel.conditionPropertyMetaModel = new PropertyMetaModel(conditionalExprMetaModel, "condition", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        conditionalExprMetaModel.getDeclaredPropertyMetaModels().add(conditionalExprMetaModel.conditionPropertyMetaModel);
+        conditionalExprMetaModel.elseExprPropertyMetaModel = new PropertyMetaModel(conditionalExprMetaModel, "elseExpr", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        conditionalExprMetaModel.getDeclaredPropertyMetaModels().add(conditionalExprMetaModel.elseExprPropertyMetaModel);
+        conditionalExprMetaModel.thenExprPropertyMetaModel = new PropertyMetaModel(conditionalExprMetaModel, "thenExpr", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        conditionalExprMetaModel.getDeclaredPropertyMetaModels().add(conditionalExprMetaModel.thenExprPropertyMetaModel);
+        enclosedExprMetaModel.innerPropertyMetaModel = new PropertyMetaModel(enclosedExprMetaModel, "inner", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        enclosedExprMetaModel.getDeclaredPropertyMetaModels().add(enclosedExprMetaModel.innerPropertyMetaModel);
+        fieldAccessExprMetaModel.namePropertyMetaModel = new PropertyMetaModel(fieldAccessExprMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        fieldAccessExprMetaModel.getDeclaredPropertyMetaModels().add(fieldAccessExprMetaModel.namePropertyMetaModel);
+        fieldAccessExprMetaModel.scopePropertyMetaModel = new PropertyMetaModel(fieldAccessExprMetaModel, "scope", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        fieldAccessExprMetaModel.getDeclaredPropertyMetaModels().add(fieldAccessExprMetaModel.scopePropertyMetaModel);
+        fieldAccessExprMetaModel.typeArgumentsPropertyMetaModel = new PropertyMetaModel(fieldAccessExprMetaModel, "typeArguments", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, true, false, false);
+        fieldAccessExprMetaModel.getDeclaredPropertyMetaModels().add(fieldAccessExprMetaModel.typeArgumentsPropertyMetaModel);
+        fieldAccessExprMetaModel.usingDiamondOperatorPropertyMetaModel = new PropertyMetaModel(fieldAccessExprMetaModel, "usingDiamondOperator", boolean.class, Optional.empty(), false, false, false, false, false);
+        fieldAccessExprMetaModel.getDerivedPropertyMetaModels().add(fieldAccessExprMetaModel.usingDiamondOperatorPropertyMetaModel);
+        instanceOfExprMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(instanceOfExprMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        instanceOfExprMetaModel.getDeclaredPropertyMetaModels().add(instanceOfExprMetaModel.expressionPropertyMetaModel);
+        instanceOfExprMetaModel.typePropertyMetaModel = new PropertyMetaModel(instanceOfExprMetaModel, "type", com.github.javaparser.ast.type.ReferenceType.class, Optional.of(referenceTypeMetaModel), false, false, false, false, false);
+        instanceOfExprMetaModel.getDeclaredPropertyMetaModels().add(instanceOfExprMetaModel.typePropertyMetaModel);
+        lambdaExprMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(lambdaExprMetaModel, "body", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, false, false, false);
+        lambdaExprMetaModel.getDeclaredPropertyMetaModels().add(lambdaExprMetaModel.bodyPropertyMetaModel);
+        lambdaExprMetaModel.isEnclosingParametersPropertyMetaModel = new PropertyMetaModel(lambdaExprMetaModel, "isEnclosingParameters", boolean.class, Optional.empty(), false, false, false, false, false);
+        lambdaExprMetaModel.getDeclaredPropertyMetaModels().add(lambdaExprMetaModel.isEnclosingParametersPropertyMetaModel);
+        lambdaExprMetaModel.parametersPropertyMetaModel = new PropertyMetaModel(lambdaExprMetaModel, "parameters", com.github.javaparser.ast.body.Parameter.class, Optional.of(parameterMetaModel), false, false, true, false, false);
+        lambdaExprMetaModel.getDeclaredPropertyMetaModels().add(lambdaExprMetaModel.parametersPropertyMetaModel);
+        lambdaExprMetaModel.expressionBodyPropertyMetaModel = new PropertyMetaModel(lambdaExprMetaModel, "expressionBody", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        lambdaExprMetaModel.getDerivedPropertyMetaModels().add(lambdaExprMetaModel.expressionBodyPropertyMetaModel);
+        memberValuePairMetaModel.namePropertyMetaModel = new PropertyMetaModel(memberValuePairMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        memberValuePairMetaModel.getDeclaredPropertyMetaModels().add(memberValuePairMetaModel.namePropertyMetaModel);
+        memberValuePairMetaModel.valuePropertyMetaModel = new PropertyMetaModel(memberValuePairMetaModel, "value", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        memberValuePairMetaModel.getDeclaredPropertyMetaModels().add(memberValuePairMetaModel.valuePropertyMetaModel);
+        methodCallExprMetaModel.argumentsPropertyMetaModel = new PropertyMetaModel(methodCallExprMetaModel, "arguments", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        methodCallExprMetaModel.getDeclaredPropertyMetaModels().add(methodCallExprMetaModel.argumentsPropertyMetaModel);
+        methodCallExprMetaModel.namePropertyMetaModel = new PropertyMetaModel(methodCallExprMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        methodCallExprMetaModel.getDeclaredPropertyMetaModels().add(methodCallExprMetaModel.namePropertyMetaModel);
+        methodCallExprMetaModel.scopePropertyMetaModel = new PropertyMetaModel(methodCallExprMetaModel, "scope", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        methodCallExprMetaModel.getDeclaredPropertyMetaModels().add(methodCallExprMetaModel.scopePropertyMetaModel);
+        methodCallExprMetaModel.typeArgumentsPropertyMetaModel = new PropertyMetaModel(methodCallExprMetaModel, "typeArguments", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, true, false, false);
+        methodCallExprMetaModel.getDeclaredPropertyMetaModels().add(methodCallExprMetaModel.typeArgumentsPropertyMetaModel);
+        methodCallExprMetaModel.usingDiamondOperatorPropertyMetaModel = new PropertyMetaModel(methodCallExprMetaModel, "usingDiamondOperator", boolean.class, Optional.empty(), false, false, false, false, false);
+        methodCallExprMetaModel.getDerivedPropertyMetaModels().add(methodCallExprMetaModel.usingDiamondOperatorPropertyMetaModel);
+        methodReferenceExprMetaModel.identifierPropertyMetaModel = new PropertyMetaModel(methodReferenceExprMetaModel, "identifier", java.lang.String.class, Optional.empty(), false, true, false, false, false);
+        methodReferenceExprMetaModel.getDeclaredPropertyMetaModels().add(methodReferenceExprMetaModel.identifierPropertyMetaModel);
+        methodReferenceExprMetaModel.scopePropertyMetaModel = new PropertyMetaModel(methodReferenceExprMetaModel, "scope", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        methodReferenceExprMetaModel.getDeclaredPropertyMetaModels().add(methodReferenceExprMetaModel.scopePropertyMetaModel);
+        methodReferenceExprMetaModel.typeArgumentsPropertyMetaModel = new PropertyMetaModel(methodReferenceExprMetaModel, "typeArguments", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, true, false, false);
+        methodReferenceExprMetaModel.getDeclaredPropertyMetaModels().add(methodReferenceExprMetaModel.typeArgumentsPropertyMetaModel);
+        methodReferenceExprMetaModel.usingDiamondOperatorPropertyMetaModel = new PropertyMetaModel(methodReferenceExprMetaModel, "usingDiamondOperator", boolean.class, Optional.empty(), false, false, false, false, false);
+        methodReferenceExprMetaModel.getDerivedPropertyMetaModels().add(methodReferenceExprMetaModel.usingDiamondOperatorPropertyMetaModel);
+        nameExprMetaModel.namePropertyMetaModel = new PropertyMetaModel(nameExprMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        nameExprMetaModel.getDeclaredPropertyMetaModels().add(nameExprMetaModel.namePropertyMetaModel);
+        nameMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(nameMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        nameMetaModel.getDeclaredPropertyMetaModels().add(nameMetaModel.annotationsPropertyMetaModel);
+        nameMetaModel.identifierPropertyMetaModel = new PropertyMetaModel(nameMetaModel, "identifier", java.lang.String.class, Optional.empty(), false, true, false, false, false);
+        nameMetaModel.getDeclaredPropertyMetaModels().add(nameMetaModel.identifierPropertyMetaModel);
+        nameMetaModel.qualifierPropertyMetaModel = new PropertyMetaModel(nameMetaModel, "qualifier", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), true, false, false, false, false);
+        nameMetaModel.getDeclaredPropertyMetaModels().add(nameMetaModel.qualifierPropertyMetaModel);
+        normalAnnotationExprMetaModel.pairsPropertyMetaModel = new PropertyMetaModel(normalAnnotationExprMetaModel, "pairs", com.github.javaparser.ast.expr.MemberValuePair.class, Optional.of(memberValuePairMetaModel), false, false, true, false, false);
+        normalAnnotationExprMetaModel.getDeclaredPropertyMetaModels().add(normalAnnotationExprMetaModel.pairsPropertyMetaModel);
+        objectCreationExprMetaModel.anonymousClassBodyPropertyMetaModel = new PropertyMetaModel(objectCreationExprMetaModel, "anonymousClassBody", com.github.javaparser.ast.body.BodyDeclaration.class, Optional.of(bodyDeclarationMetaModel), true, false, true, false, true);
+        objectCreationExprMetaModel.getDeclaredPropertyMetaModels().add(objectCreationExprMetaModel.anonymousClassBodyPropertyMetaModel);
+        objectCreationExprMetaModel.argumentsPropertyMetaModel = new PropertyMetaModel(objectCreationExprMetaModel, "arguments", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        objectCreationExprMetaModel.getDeclaredPropertyMetaModels().add(objectCreationExprMetaModel.argumentsPropertyMetaModel);
+        objectCreationExprMetaModel.scopePropertyMetaModel = new PropertyMetaModel(objectCreationExprMetaModel, "scope", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        objectCreationExprMetaModel.getDeclaredPropertyMetaModels().add(objectCreationExprMetaModel.scopePropertyMetaModel);
+        objectCreationExprMetaModel.typePropertyMetaModel = new PropertyMetaModel(objectCreationExprMetaModel, "type", com.github.javaparser.ast.type.ClassOrInterfaceType.class, Optional.of(classOrInterfaceTypeMetaModel), false, false, false, false, false);
+        objectCreationExprMetaModel.getDeclaredPropertyMetaModels().add(objectCreationExprMetaModel.typePropertyMetaModel);
+        objectCreationExprMetaModel.typeArgumentsPropertyMetaModel = new PropertyMetaModel(objectCreationExprMetaModel, "typeArguments", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, true, false, false);
+        objectCreationExprMetaModel.getDeclaredPropertyMetaModels().add(objectCreationExprMetaModel.typeArgumentsPropertyMetaModel);
+        objectCreationExprMetaModel.usingDiamondOperatorPropertyMetaModel = new PropertyMetaModel(objectCreationExprMetaModel, "usingDiamondOperator", boolean.class, Optional.empty(), false, false, false, false, false);
+        objectCreationExprMetaModel.getDerivedPropertyMetaModels().add(objectCreationExprMetaModel.usingDiamondOperatorPropertyMetaModel);
+        simpleNameMetaModel.identifierPropertyMetaModel = new PropertyMetaModel(simpleNameMetaModel, "identifier", java.lang.String.class, Optional.empty(), false, true, false, false, false);
+        simpleNameMetaModel.getDeclaredPropertyMetaModels().add(simpleNameMetaModel.identifierPropertyMetaModel);
+        singleMemberAnnotationExprMetaModel.memberValuePropertyMetaModel = new PropertyMetaModel(singleMemberAnnotationExprMetaModel, "memberValue", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        singleMemberAnnotationExprMetaModel.getDeclaredPropertyMetaModels().add(singleMemberAnnotationExprMetaModel.memberValuePropertyMetaModel);
+        superExprMetaModel.classExprPropertyMetaModel = new PropertyMetaModel(superExprMetaModel, "classExpr", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        superExprMetaModel.getDeclaredPropertyMetaModels().add(superExprMetaModel.classExprPropertyMetaModel);
+        thisExprMetaModel.classExprPropertyMetaModel = new PropertyMetaModel(thisExprMetaModel, "classExpr", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        thisExprMetaModel.getDeclaredPropertyMetaModels().add(thisExprMetaModel.classExprPropertyMetaModel);
+        typeExprMetaModel.typePropertyMetaModel = new PropertyMetaModel(typeExprMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        typeExprMetaModel.getDeclaredPropertyMetaModels().add(typeExprMetaModel.typePropertyMetaModel);
+        unaryExprMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(unaryExprMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        unaryExprMetaModel.getDeclaredPropertyMetaModels().add(unaryExprMetaModel.expressionPropertyMetaModel);
+        unaryExprMetaModel.operatorPropertyMetaModel = new PropertyMetaModel(unaryExprMetaModel, "operator", com.github.javaparser.ast.expr.UnaryExpr.Operator.class, Optional.empty(), false, false, false, false, false);
+        unaryExprMetaModel.getDeclaredPropertyMetaModels().add(unaryExprMetaModel.operatorPropertyMetaModel);
+        unaryExprMetaModel.postfixPropertyMetaModel = new PropertyMetaModel(unaryExprMetaModel, "postfix", boolean.class, Optional.empty(), false, false, false, false, false);
+        unaryExprMetaModel.getDerivedPropertyMetaModels().add(unaryExprMetaModel.postfixPropertyMetaModel);
+        unaryExprMetaModel.prefixPropertyMetaModel = new PropertyMetaModel(unaryExprMetaModel, "prefix", boolean.class, Optional.empty(), false, false, false, false, false);
+        unaryExprMetaModel.getDerivedPropertyMetaModels().add(unaryExprMetaModel.prefixPropertyMetaModel);
+        variableDeclarationExprMetaModel.annotationsPropertyMetaModel = new PropertyMetaModel(variableDeclarationExprMetaModel, "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, Optional.of(annotationExprMetaModel), false, false, true, false, false);
+        variableDeclarationExprMetaModel.getDeclaredPropertyMetaModels().add(variableDeclarationExprMetaModel.annotationsPropertyMetaModel);
+        variableDeclarationExprMetaModel.modifiersPropertyMetaModel = new PropertyMetaModel(variableDeclarationExprMetaModel, "modifiers", com.github.javaparser.ast.Modifier.class, Optional.empty(), false, false, false, true, false);
+        variableDeclarationExprMetaModel.getDeclaredPropertyMetaModels().add(variableDeclarationExprMetaModel.modifiersPropertyMetaModel);
+        variableDeclarationExprMetaModel.variablesPropertyMetaModel = new PropertyMetaModel(variableDeclarationExprMetaModel, "variables", com.github.javaparser.ast.body.VariableDeclarator.class, Optional.of(variableDeclaratorMetaModel), false, true, true, false, false);
+        variableDeclarationExprMetaModel.getDeclaredPropertyMetaModels().add(variableDeclarationExprMetaModel.variablesPropertyMetaModel);
+        variableDeclarationExprMetaModel.maximumCommonTypePropertyMetaModel = new PropertyMetaModel(variableDeclarationExprMetaModel, "maximumCommonType", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, false, false, false);
+        variableDeclarationExprMetaModel.getDerivedPropertyMetaModels().add(variableDeclarationExprMetaModel.maximumCommonTypePropertyMetaModel);
+        importDeclarationMetaModel.isAsteriskPropertyMetaModel = new PropertyMetaModel(importDeclarationMetaModel, "isAsterisk", boolean.class, Optional.empty(), false, false, false, false, false);
+        importDeclarationMetaModel.getDeclaredPropertyMetaModels().add(importDeclarationMetaModel.isAsteriskPropertyMetaModel);
+        importDeclarationMetaModel.isStaticPropertyMetaModel = new PropertyMetaModel(importDeclarationMetaModel, "isStatic", boolean.class, Optional.empty(), false, false, false, false, false);
+        importDeclarationMetaModel.getDeclaredPropertyMetaModels().add(importDeclarationMetaModel.isStaticPropertyMetaModel);
+        importDeclarationMetaModel.namePropertyMetaModel = new PropertyMetaModel(importDeclarationMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        importDeclarationMetaModel.getDeclaredPropertyMetaModels().add(importDeclarationMetaModel.namePropertyMetaModel);
+        assertStmtMetaModel.checkPropertyMetaModel = new PropertyMetaModel(assertStmtMetaModel, "check", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        assertStmtMetaModel.getDeclaredPropertyMetaModels().add(assertStmtMetaModel.checkPropertyMetaModel);
+        assertStmtMetaModel.messagePropertyMetaModel = new PropertyMetaModel(assertStmtMetaModel, "message", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        assertStmtMetaModel.getDeclaredPropertyMetaModels().add(assertStmtMetaModel.messagePropertyMetaModel);
+        blockStmtMetaModel.statementsPropertyMetaModel = new PropertyMetaModel(blockStmtMetaModel, "statements", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, true, false, false);
+        blockStmtMetaModel.getDeclaredPropertyMetaModels().add(blockStmtMetaModel.statementsPropertyMetaModel);
+        breakStmtMetaModel.labelPropertyMetaModel = new PropertyMetaModel(breakStmtMetaModel, "label", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), true, false, false, false, false);
+        breakStmtMetaModel.getDeclaredPropertyMetaModels().add(breakStmtMetaModel.labelPropertyMetaModel);
+        catchClauseMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(catchClauseMetaModel, "body", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), false, false, false, false, false);
+        catchClauseMetaModel.getDeclaredPropertyMetaModels().add(catchClauseMetaModel.bodyPropertyMetaModel);
+        catchClauseMetaModel.parameterPropertyMetaModel = new PropertyMetaModel(catchClauseMetaModel, "parameter", com.github.javaparser.ast.body.Parameter.class, Optional.of(parameterMetaModel), false, false, false, false, false);
+        catchClauseMetaModel.getDeclaredPropertyMetaModels().add(catchClauseMetaModel.parameterPropertyMetaModel);
+        continueStmtMetaModel.labelPropertyMetaModel = new PropertyMetaModel(continueStmtMetaModel, "label", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), true, false, false, false, false);
+        continueStmtMetaModel.getDeclaredPropertyMetaModels().add(continueStmtMetaModel.labelPropertyMetaModel);
+        doStmtMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(doStmtMetaModel, "body", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, false, false, false);
+        doStmtMetaModel.getDeclaredPropertyMetaModels().add(doStmtMetaModel.bodyPropertyMetaModel);
+        doStmtMetaModel.conditionPropertyMetaModel = new PropertyMetaModel(doStmtMetaModel, "condition", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        doStmtMetaModel.getDeclaredPropertyMetaModels().add(doStmtMetaModel.conditionPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.argumentsPropertyMetaModel = new PropertyMetaModel(explicitConstructorInvocationStmtMetaModel, "arguments", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        explicitConstructorInvocationStmtMetaModel.getDeclaredPropertyMetaModels().add(explicitConstructorInvocationStmtMetaModel.argumentsPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(explicitConstructorInvocationStmtMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        explicitConstructorInvocationStmtMetaModel.getDeclaredPropertyMetaModels().add(explicitConstructorInvocationStmtMetaModel.expressionPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.isThisPropertyMetaModel = new PropertyMetaModel(explicitConstructorInvocationStmtMetaModel, "isThis", boolean.class, Optional.empty(), false, false, false, false, false);
+        explicitConstructorInvocationStmtMetaModel.getDeclaredPropertyMetaModels().add(explicitConstructorInvocationStmtMetaModel.isThisPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.typeArgumentsPropertyMetaModel = new PropertyMetaModel(explicitConstructorInvocationStmtMetaModel, "typeArguments", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, true, false, false);
+        explicitConstructorInvocationStmtMetaModel.getDeclaredPropertyMetaModels().add(explicitConstructorInvocationStmtMetaModel.typeArgumentsPropertyMetaModel);
+        explicitConstructorInvocationStmtMetaModel.usingDiamondOperatorPropertyMetaModel = new PropertyMetaModel(explicitConstructorInvocationStmtMetaModel, "usingDiamondOperator", boolean.class, Optional.empty(), false, false, false, false, false);
+        explicitConstructorInvocationStmtMetaModel.getDerivedPropertyMetaModels().add(explicitConstructorInvocationStmtMetaModel.usingDiamondOperatorPropertyMetaModel);
+        expressionStmtMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(expressionStmtMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        expressionStmtMetaModel.getDeclaredPropertyMetaModels().add(expressionStmtMetaModel.expressionPropertyMetaModel);
+        foreachStmtMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(foreachStmtMetaModel, "body", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, false, false, false);
+        foreachStmtMetaModel.getDeclaredPropertyMetaModels().add(foreachStmtMetaModel.bodyPropertyMetaModel);
+        foreachStmtMetaModel.iterablePropertyMetaModel = new PropertyMetaModel(foreachStmtMetaModel, "iterable", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        foreachStmtMetaModel.getDeclaredPropertyMetaModels().add(foreachStmtMetaModel.iterablePropertyMetaModel);
+        foreachStmtMetaModel.variablePropertyMetaModel = new PropertyMetaModel(foreachStmtMetaModel, "variable", com.github.javaparser.ast.expr.VariableDeclarationExpr.class, Optional.of(variableDeclarationExprMetaModel), false, false, false, false, false);
+        foreachStmtMetaModel.getDeclaredPropertyMetaModels().add(foreachStmtMetaModel.variablePropertyMetaModel);
+        forStmtMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(forStmtMetaModel, "body", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, false, false, false);
+        forStmtMetaModel.getDeclaredPropertyMetaModels().add(forStmtMetaModel.bodyPropertyMetaModel);
+        forStmtMetaModel.comparePropertyMetaModel = new PropertyMetaModel(forStmtMetaModel, "compare", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        forStmtMetaModel.getDeclaredPropertyMetaModels().add(forStmtMetaModel.comparePropertyMetaModel);
+        forStmtMetaModel.initializationPropertyMetaModel = new PropertyMetaModel(forStmtMetaModel, "initialization", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        forStmtMetaModel.getDeclaredPropertyMetaModels().add(forStmtMetaModel.initializationPropertyMetaModel);
+        forStmtMetaModel.updatePropertyMetaModel = new PropertyMetaModel(forStmtMetaModel, "update", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        forStmtMetaModel.getDeclaredPropertyMetaModels().add(forStmtMetaModel.updatePropertyMetaModel);
+        ifStmtMetaModel.conditionPropertyMetaModel = new PropertyMetaModel(ifStmtMetaModel, "condition", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        ifStmtMetaModel.getDeclaredPropertyMetaModels().add(ifStmtMetaModel.conditionPropertyMetaModel);
+        ifStmtMetaModel.elseStmtPropertyMetaModel = new PropertyMetaModel(ifStmtMetaModel, "elseStmt", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), true, false, false, false, false);
+        ifStmtMetaModel.getDeclaredPropertyMetaModels().add(ifStmtMetaModel.elseStmtPropertyMetaModel);
+        ifStmtMetaModel.thenStmtPropertyMetaModel = new PropertyMetaModel(ifStmtMetaModel, "thenStmt", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, false, false, false);
+        ifStmtMetaModel.getDeclaredPropertyMetaModels().add(ifStmtMetaModel.thenStmtPropertyMetaModel);
+        ifStmtMetaModel.cascadingIfStmtPropertyMetaModel = new PropertyMetaModel(ifStmtMetaModel, "cascadingIfStmt", boolean.class, Optional.empty(), false, false, false, false, false);
+        ifStmtMetaModel.getDerivedPropertyMetaModels().add(ifStmtMetaModel.cascadingIfStmtPropertyMetaModel);
+        ifStmtMetaModel.elseBlockPropertyMetaModel = new PropertyMetaModel(ifStmtMetaModel, "elseBlock", boolean.class, Optional.empty(), false, false, false, false, false);
+        ifStmtMetaModel.getDerivedPropertyMetaModels().add(ifStmtMetaModel.elseBlockPropertyMetaModel);
+        ifStmtMetaModel.elseBranchPropertyMetaModel = new PropertyMetaModel(ifStmtMetaModel, "elseBranch", boolean.class, Optional.empty(), false, false, false, false, false);
+        ifStmtMetaModel.getDerivedPropertyMetaModels().add(ifStmtMetaModel.elseBranchPropertyMetaModel);
+        ifStmtMetaModel.thenBlockPropertyMetaModel = new PropertyMetaModel(ifStmtMetaModel, "thenBlock", boolean.class, Optional.empty(), false, false, false, false, false);
+        ifStmtMetaModel.getDerivedPropertyMetaModels().add(ifStmtMetaModel.thenBlockPropertyMetaModel);
+        labeledStmtMetaModel.labelPropertyMetaModel = new PropertyMetaModel(labeledStmtMetaModel, "label", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        labeledStmtMetaModel.getDeclaredPropertyMetaModels().add(labeledStmtMetaModel.labelPropertyMetaModel);
+        labeledStmtMetaModel.statementPropertyMetaModel = new PropertyMetaModel(labeledStmtMetaModel, "statement", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, false, false, false);
+        labeledStmtMetaModel.getDeclaredPropertyMetaModels().add(labeledStmtMetaModel.statementPropertyMetaModel);
+        returnStmtMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(returnStmtMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        returnStmtMetaModel.getDeclaredPropertyMetaModels().add(returnStmtMetaModel.expressionPropertyMetaModel);
+        switchEntryStmtMetaModel.labelPropertyMetaModel = new PropertyMetaModel(switchEntryStmtMetaModel, "label", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), true, false, false, false, false);
+        switchEntryStmtMetaModel.getDeclaredPropertyMetaModels().add(switchEntryStmtMetaModel.labelPropertyMetaModel);
+        switchEntryStmtMetaModel.statementsPropertyMetaModel = new PropertyMetaModel(switchEntryStmtMetaModel, "statements", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, true, false, false);
+        switchEntryStmtMetaModel.getDeclaredPropertyMetaModels().add(switchEntryStmtMetaModel.statementsPropertyMetaModel);
+        switchStmtMetaModel.entriesPropertyMetaModel = new PropertyMetaModel(switchStmtMetaModel, "entries", com.github.javaparser.ast.stmt.SwitchEntryStmt.class, Optional.of(switchEntryStmtMetaModel), false, false, true, false, false);
+        switchStmtMetaModel.getDeclaredPropertyMetaModels().add(switchStmtMetaModel.entriesPropertyMetaModel);
+        switchStmtMetaModel.selectorPropertyMetaModel = new PropertyMetaModel(switchStmtMetaModel, "selector", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        switchStmtMetaModel.getDeclaredPropertyMetaModels().add(switchStmtMetaModel.selectorPropertyMetaModel);
+        synchronizedStmtMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(synchronizedStmtMetaModel, "body", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), false, false, false, false, false);
+        synchronizedStmtMetaModel.getDeclaredPropertyMetaModels().add(synchronizedStmtMetaModel.bodyPropertyMetaModel);
+        synchronizedStmtMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(synchronizedStmtMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        synchronizedStmtMetaModel.getDeclaredPropertyMetaModels().add(synchronizedStmtMetaModel.expressionPropertyMetaModel);
+        throwStmtMetaModel.expressionPropertyMetaModel = new PropertyMetaModel(throwStmtMetaModel, "expression", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        throwStmtMetaModel.getDeclaredPropertyMetaModels().add(throwStmtMetaModel.expressionPropertyMetaModel);
+        tryStmtMetaModel.catchClausesPropertyMetaModel = new PropertyMetaModel(tryStmtMetaModel, "catchClauses", com.github.javaparser.ast.stmt.CatchClause.class, Optional.of(catchClauseMetaModel), false, false, true, false, false);
+        tryStmtMetaModel.getDeclaredPropertyMetaModels().add(tryStmtMetaModel.catchClausesPropertyMetaModel);
+        tryStmtMetaModel.finallyBlockPropertyMetaModel = new PropertyMetaModel(tryStmtMetaModel, "finallyBlock", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), true, false, false, false, false);
+        tryStmtMetaModel.getDeclaredPropertyMetaModels().add(tryStmtMetaModel.finallyBlockPropertyMetaModel);
+        tryStmtMetaModel.resourcesPropertyMetaModel = new PropertyMetaModel(tryStmtMetaModel, "resources", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, true, false, false);
+        tryStmtMetaModel.getDeclaredPropertyMetaModels().add(tryStmtMetaModel.resourcesPropertyMetaModel);
+        tryStmtMetaModel.tryBlockPropertyMetaModel = new PropertyMetaModel(tryStmtMetaModel, "tryBlock", com.github.javaparser.ast.stmt.BlockStmt.class, Optional.of(blockStmtMetaModel), false, false, false, false, false);
+        tryStmtMetaModel.getDeclaredPropertyMetaModels().add(tryStmtMetaModel.tryBlockPropertyMetaModel);
+        localClassDeclarationStmtMetaModel.classDeclarationPropertyMetaModel = new PropertyMetaModel(localClassDeclarationStmtMetaModel, "classDeclaration", com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.class, Optional.of(classOrInterfaceDeclarationMetaModel), false, false, false, false, false);
+        localClassDeclarationStmtMetaModel.getDeclaredPropertyMetaModels().add(localClassDeclarationStmtMetaModel.classDeclarationPropertyMetaModel);
+        whileStmtMetaModel.bodyPropertyMetaModel = new PropertyMetaModel(whileStmtMetaModel, "body", com.github.javaparser.ast.stmt.Statement.class, Optional.of(statementMetaModel), false, false, false, false, false);
+        whileStmtMetaModel.getDeclaredPropertyMetaModels().add(whileStmtMetaModel.bodyPropertyMetaModel);
+        whileStmtMetaModel.conditionPropertyMetaModel = new PropertyMetaModel(whileStmtMetaModel, "condition", com.github.javaparser.ast.expr.Expression.class, Optional.of(expressionMetaModel), false, false, false, false, false);
+        whileStmtMetaModel.getDeclaredPropertyMetaModels().add(whileStmtMetaModel.conditionPropertyMetaModel);
+        arrayTypeMetaModel.componentTypePropertyMetaModel = new PropertyMetaModel(arrayTypeMetaModel, "componentType", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        arrayTypeMetaModel.getDeclaredPropertyMetaModels().add(arrayTypeMetaModel.componentTypePropertyMetaModel);
+        arrayTypeMetaModel.originPropertyMetaModel = new PropertyMetaModel(arrayTypeMetaModel, "origin", com.github.javaparser.ast.type.ArrayType.Origin.class, Optional.empty(), false, false, false, false, false);
+        arrayTypeMetaModel.getDeclaredPropertyMetaModels().add(arrayTypeMetaModel.originPropertyMetaModel);
+        classOrInterfaceTypeMetaModel.namePropertyMetaModel = new PropertyMetaModel(classOrInterfaceTypeMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        classOrInterfaceTypeMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceTypeMetaModel.namePropertyMetaModel);
+        classOrInterfaceTypeMetaModel.scopePropertyMetaModel = new PropertyMetaModel(classOrInterfaceTypeMetaModel, "scope", com.github.javaparser.ast.type.ClassOrInterfaceType.class, Optional.of(classOrInterfaceTypeMetaModel), true, false, false, false, false);
+        classOrInterfaceTypeMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceTypeMetaModel.scopePropertyMetaModel);
+        classOrInterfaceTypeMetaModel.typeArgumentsPropertyMetaModel = new PropertyMetaModel(classOrInterfaceTypeMetaModel, "typeArguments", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), true, false, true, false, false);
+        classOrInterfaceTypeMetaModel.getDeclaredPropertyMetaModels().add(classOrInterfaceTypeMetaModel.typeArgumentsPropertyMetaModel);
+        classOrInterfaceTypeMetaModel.usingDiamondOperatorPropertyMetaModel = new PropertyMetaModel(classOrInterfaceTypeMetaModel, "usingDiamondOperator", boolean.class, Optional.empty(), false, false, false, false, false);
+        classOrInterfaceTypeMetaModel.getDerivedPropertyMetaModels().add(classOrInterfaceTypeMetaModel.usingDiamondOperatorPropertyMetaModel);
+        intersectionTypeMetaModel.elementsPropertyMetaModel = new PropertyMetaModel(intersectionTypeMetaModel, "elements", com.github.javaparser.ast.type.ReferenceType.class, Optional.of(referenceTypeMetaModel), false, true, true, false, false);
+        intersectionTypeMetaModel.getDeclaredPropertyMetaModels().add(intersectionTypeMetaModel.elementsPropertyMetaModel);
+        primitiveTypeMetaModel.typePropertyMetaModel = new PropertyMetaModel(primitiveTypeMetaModel, "type", com.github.javaparser.ast.type.PrimitiveType.Primitive.class, Optional.empty(), false, false, false, false, false);
+        primitiveTypeMetaModel.getDeclaredPropertyMetaModels().add(primitiveTypeMetaModel.typePropertyMetaModel);
+        typeParameterMetaModel.namePropertyMetaModel = new PropertyMetaModel(typeParameterMetaModel, "name", com.github.javaparser.ast.expr.SimpleName.class, Optional.of(simpleNameMetaModel), false, false, false, false, false);
+        typeParameterMetaModel.getDeclaredPropertyMetaModels().add(typeParameterMetaModel.namePropertyMetaModel);
+        typeParameterMetaModel.typeBoundPropertyMetaModel = new PropertyMetaModel(typeParameterMetaModel, "typeBound", com.github.javaparser.ast.type.ClassOrInterfaceType.class, Optional.of(classOrInterfaceTypeMetaModel), false, false, true, false, false);
+        typeParameterMetaModel.getDeclaredPropertyMetaModels().add(typeParameterMetaModel.typeBoundPropertyMetaModel);
+        unionTypeMetaModel.elementsPropertyMetaModel = new PropertyMetaModel(unionTypeMetaModel, "elements", com.github.javaparser.ast.type.ReferenceType.class, Optional.of(referenceTypeMetaModel), false, true, true, false, false);
+        unionTypeMetaModel.getDeclaredPropertyMetaModels().add(unionTypeMetaModel.elementsPropertyMetaModel);
+        wildcardTypeMetaModel.extendedTypePropertyMetaModel = new PropertyMetaModel(wildcardTypeMetaModel, "extendedType", com.github.javaparser.ast.type.ReferenceType.class, Optional.of(referenceTypeMetaModel), true, false, false, false, false);
+        wildcardTypeMetaModel.getDeclaredPropertyMetaModels().add(wildcardTypeMetaModel.extendedTypePropertyMetaModel);
+        wildcardTypeMetaModel.superTypePropertyMetaModel = new PropertyMetaModel(wildcardTypeMetaModel, "superType", com.github.javaparser.ast.type.ReferenceType.class, Optional.of(referenceTypeMetaModel), true, false, false, false, false);
+        wildcardTypeMetaModel.getDeclaredPropertyMetaModels().add(wildcardTypeMetaModel.superTypePropertyMetaModel);
+        moduleRequiresStmtMetaModel.modifiersPropertyMetaModel = new PropertyMetaModel(moduleRequiresStmtMetaModel, "modifiers", com.github.javaparser.ast.Modifier.class, Optional.empty(), false, false, false, true, false);
+        moduleRequiresStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleRequiresStmtMetaModel.modifiersPropertyMetaModel);
+        moduleRequiresStmtMetaModel.namePropertyMetaModel = new PropertyMetaModel(moduleRequiresStmtMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        moduleRequiresStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleRequiresStmtMetaModel.namePropertyMetaModel);
+        moduleExportsStmtMetaModel.moduleNamesPropertyMetaModel = new PropertyMetaModel(moduleExportsStmtMetaModel, "moduleNames", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, true, false, false);
+        moduleExportsStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleExportsStmtMetaModel.moduleNamesPropertyMetaModel);
+        moduleExportsStmtMetaModel.namePropertyMetaModel = new PropertyMetaModel(moduleExportsStmtMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        moduleExportsStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleExportsStmtMetaModel.namePropertyMetaModel);
+        moduleProvidesStmtMetaModel.typePropertyMetaModel = new PropertyMetaModel(moduleProvidesStmtMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        moduleProvidesStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleProvidesStmtMetaModel.typePropertyMetaModel);
+        moduleProvidesStmtMetaModel.withTypesPropertyMetaModel = new PropertyMetaModel(moduleProvidesStmtMetaModel, "withTypes", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, true, false, false);
+        moduleProvidesStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleProvidesStmtMetaModel.withTypesPropertyMetaModel);
+        moduleUsesStmtMetaModel.typePropertyMetaModel = new PropertyMetaModel(moduleUsesStmtMetaModel, "type", com.github.javaparser.ast.type.Type.class, Optional.of(typeMetaModel), false, false, false, false, false);
+        moduleUsesStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleUsesStmtMetaModel.typePropertyMetaModel);
+        moduleOpensStmtMetaModel.moduleNamesPropertyMetaModel = new PropertyMetaModel(moduleOpensStmtMetaModel, "moduleNames", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, true, false, false);
+        moduleOpensStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleOpensStmtMetaModel.moduleNamesPropertyMetaModel);
+        moduleOpensStmtMetaModel.namePropertyMetaModel = new PropertyMetaModel(moduleOpensStmtMetaModel, "name", com.github.javaparser.ast.expr.Name.class, Optional.of(nameMetaModel), false, false, false, false, false);
+        moduleOpensStmtMetaModel.getDeclaredPropertyMetaModels().add(moduleOpensStmtMetaModel.namePropertyMetaModel);
+    }
+
+    public static Optional<BaseNodeMetaModel> getNodeMetaModel(Class<? extends Node> c) {
+        for (BaseNodeMetaModel nodeMetaModel : nodeMetaModels) {
+            if (nodeMetaModel.getTypeNameGenerified().equals(c.getSimpleName())) {
+                return Optional.of(nodeMetaModel);
+            }
+        }
+        return Optional.empty();
+    }
+
+    public static final NodeMetaModel nodeMetaModel = new NodeMetaModel(Optional.empty());
+
+    public static final BodyDeclarationMetaModel bodyDeclarationMetaModel = new BodyDeclarationMetaModel(Optional.of(nodeMetaModel));
+
+    public static final CallableDeclarationMetaModel callableDeclarationMetaModel = new CallableDeclarationMetaModel(Optional.of(bodyDeclarationMetaModel));
+
+    public static final StatementMetaModel statementMetaModel = new StatementMetaModel(Optional.of(nodeMetaModel));
+
+    public static final ExpressionMetaModel expressionMetaModel = new ExpressionMetaModel(Optional.of(nodeMetaModel));
+
+    public static final TypeMetaModel typeMetaModel = new TypeMetaModel(Optional.of(nodeMetaModel));
+
+    public static final AnnotationExprMetaModel annotationExprMetaModel = new AnnotationExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final TypeDeclarationMetaModel typeDeclarationMetaModel = new TypeDeclarationMetaModel(Optional.of(bodyDeclarationMetaModel));
+
+    public static final ReferenceTypeMetaModel referenceTypeMetaModel = new ReferenceTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final LiteralExprMetaModel literalExprMetaModel = new LiteralExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final LiteralStringValueExprMetaModel literalStringValueExprMetaModel = new LiteralStringValueExprMetaModel(Optional.of(literalExprMetaModel));
+
+    public static final StringLiteralExprMetaModel stringLiteralExprMetaModel = new StringLiteralExprMetaModel(Optional.of(literalStringValueExprMetaModel));
+
+    public static final ModuleDeclarationMetaModel moduleDeclarationMetaModel = new ModuleDeclarationMetaModel(Optional.of(nodeMetaModel));
+
+    public static final ModuleStmtMetaModel moduleStmtMetaModel = new ModuleStmtMetaModel(Optional.of(nodeMetaModel));
+
+    public static final ArrayCreationLevelMetaModel arrayCreationLevelMetaModel = new ArrayCreationLevelMetaModel(Optional.of(nodeMetaModel));
+
+    public static final CompilationUnitMetaModel compilationUnitMetaModel = new CompilationUnitMetaModel(Optional.of(nodeMetaModel));
+
+    public static final PackageDeclarationMetaModel packageDeclarationMetaModel = new PackageDeclarationMetaModel(Optional.of(nodeMetaModel));
+
+    public static final AnnotationDeclarationMetaModel annotationDeclarationMetaModel = new AnnotationDeclarationMetaModel(Optional.of(typeDeclarationMetaModel));
+
+    public static final AnnotationMemberDeclarationMetaModel annotationMemberDeclarationMetaModel = new AnnotationMemberDeclarationMetaModel(Optional.of(bodyDeclarationMetaModel));
+
+    public static final ClassOrInterfaceDeclarationMetaModel classOrInterfaceDeclarationMetaModel = new ClassOrInterfaceDeclarationMetaModel(Optional.of(typeDeclarationMetaModel));
+
+    public static final ConstructorDeclarationMetaModel constructorDeclarationMetaModel = new ConstructorDeclarationMetaModel(Optional.of(callableDeclarationMetaModel));
+
+    public static final EnumConstantDeclarationMetaModel enumConstantDeclarationMetaModel = new EnumConstantDeclarationMetaModel(Optional.of(bodyDeclarationMetaModel));
+
+    public static final EnumDeclarationMetaModel enumDeclarationMetaModel = new EnumDeclarationMetaModel(Optional.of(typeDeclarationMetaModel));
+
+    public static final FieldDeclarationMetaModel fieldDeclarationMetaModel = new FieldDeclarationMetaModel(Optional.of(bodyDeclarationMetaModel));
+
+    public static final InitializerDeclarationMetaModel initializerDeclarationMetaModel = new InitializerDeclarationMetaModel(Optional.of(bodyDeclarationMetaModel));
+
+    public static final MethodDeclarationMetaModel methodDeclarationMetaModel = new MethodDeclarationMetaModel(Optional.of(callableDeclarationMetaModel));
+
+    public static final ParameterMetaModel parameterMetaModel = new ParameterMetaModel(Optional.of(nodeMetaModel));
+
+    public static final ReceiverParameterMetaModel receiverParameterMetaModel = new ReceiverParameterMetaModel(Optional.of(nodeMetaModel));
+
+    public static final VariableDeclaratorMetaModel variableDeclaratorMetaModel = new VariableDeclaratorMetaModel(Optional.of(nodeMetaModel));
+
+    public static final CommentMetaModel commentMetaModel = new CommentMetaModel(Optional.of(nodeMetaModel));
+
+    public static final BlockCommentMetaModel blockCommentMetaModel = new BlockCommentMetaModel(Optional.of(commentMetaModel));
+
+    public static final JavadocCommentMetaModel javadocCommentMetaModel = new JavadocCommentMetaModel(Optional.of(commentMetaModel));
+
+    public static final LineCommentMetaModel lineCommentMetaModel = new LineCommentMetaModel(Optional.of(commentMetaModel));
+
+    public static final ArrayAccessExprMetaModel arrayAccessExprMetaModel = new ArrayAccessExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final ArrayCreationExprMetaModel arrayCreationExprMetaModel = new ArrayCreationExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final ArrayInitializerExprMetaModel arrayInitializerExprMetaModel = new ArrayInitializerExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final AssignExprMetaModel assignExprMetaModel = new AssignExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final BinaryExprMetaModel binaryExprMetaModel = new BinaryExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final BooleanLiteralExprMetaModel booleanLiteralExprMetaModel = new BooleanLiteralExprMetaModel(Optional.of(literalExprMetaModel));
+
+    public static final CastExprMetaModel castExprMetaModel = new CastExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final CharLiteralExprMetaModel charLiteralExprMetaModel = new CharLiteralExprMetaModel(Optional.of(literalStringValueExprMetaModel));
+
+    public static final ClassExprMetaModel classExprMetaModel = new ClassExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final ConditionalExprMetaModel conditionalExprMetaModel = new ConditionalExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final DoubleLiteralExprMetaModel doubleLiteralExprMetaModel = new DoubleLiteralExprMetaModel(Optional.of(literalStringValueExprMetaModel));
+
+    public static final EnclosedExprMetaModel enclosedExprMetaModel = new EnclosedExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final FieldAccessExprMetaModel fieldAccessExprMetaModel = new FieldAccessExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final InstanceOfExprMetaModel instanceOfExprMetaModel = new InstanceOfExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final IntegerLiteralExprMetaModel integerLiteralExprMetaModel = new IntegerLiteralExprMetaModel(Optional.of(literalStringValueExprMetaModel));
+
+    public static final LambdaExprMetaModel lambdaExprMetaModel = new LambdaExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final LongLiteralExprMetaModel longLiteralExprMetaModel = new LongLiteralExprMetaModel(Optional.of(literalStringValueExprMetaModel));
+
+    public static final MarkerAnnotationExprMetaModel markerAnnotationExprMetaModel = new MarkerAnnotationExprMetaModel(Optional.of(annotationExprMetaModel));
+
+    public static final MemberValuePairMetaModel memberValuePairMetaModel = new MemberValuePairMetaModel(Optional.of(nodeMetaModel));
+
+    public static final MethodCallExprMetaModel methodCallExprMetaModel = new MethodCallExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final MethodReferenceExprMetaModel methodReferenceExprMetaModel = new MethodReferenceExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final NameExprMetaModel nameExprMetaModel = new NameExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final NameMetaModel nameMetaModel = new NameMetaModel(Optional.of(nodeMetaModel));
+
+    public static final NormalAnnotationExprMetaModel normalAnnotationExprMetaModel = new NormalAnnotationExprMetaModel(Optional.of(annotationExprMetaModel));
+
+    public static final NullLiteralExprMetaModel nullLiteralExprMetaModel = new NullLiteralExprMetaModel(Optional.of(literalExprMetaModel));
+
+    public static final ObjectCreationExprMetaModel objectCreationExprMetaModel = new ObjectCreationExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final SimpleNameMetaModel simpleNameMetaModel = new SimpleNameMetaModel(Optional.of(nodeMetaModel));
+
+    public static final SingleMemberAnnotationExprMetaModel singleMemberAnnotationExprMetaModel = new SingleMemberAnnotationExprMetaModel(Optional.of(annotationExprMetaModel));
+
+    public static final SuperExprMetaModel superExprMetaModel = new SuperExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final ThisExprMetaModel thisExprMetaModel = new ThisExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final TypeExprMetaModel typeExprMetaModel = new TypeExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final UnaryExprMetaModel unaryExprMetaModel = new UnaryExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final VariableDeclarationExprMetaModel variableDeclarationExprMetaModel = new VariableDeclarationExprMetaModel(Optional.of(expressionMetaModel));
+
+    public static final ImportDeclarationMetaModel importDeclarationMetaModel = new ImportDeclarationMetaModel(Optional.of(nodeMetaModel));
+
+    public static final AssertStmtMetaModel assertStmtMetaModel = new AssertStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final BlockStmtMetaModel blockStmtMetaModel = new BlockStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final BreakStmtMetaModel breakStmtMetaModel = new BreakStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final CatchClauseMetaModel catchClauseMetaModel = new CatchClauseMetaModel(Optional.of(nodeMetaModel));
+
+    public static final ContinueStmtMetaModel continueStmtMetaModel = new ContinueStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final DoStmtMetaModel doStmtMetaModel = new DoStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final EmptyStmtMetaModel emptyStmtMetaModel = new EmptyStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final ExplicitConstructorInvocationStmtMetaModel explicitConstructorInvocationStmtMetaModel = new ExplicitConstructorInvocationStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final ExpressionStmtMetaModel expressionStmtMetaModel = new ExpressionStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final ForeachStmtMetaModel foreachStmtMetaModel = new ForeachStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final ForStmtMetaModel forStmtMetaModel = new ForStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final IfStmtMetaModel ifStmtMetaModel = new IfStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final LabeledStmtMetaModel labeledStmtMetaModel = new LabeledStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final ReturnStmtMetaModel returnStmtMetaModel = new ReturnStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final SwitchEntryStmtMetaModel switchEntryStmtMetaModel = new SwitchEntryStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final SwitchStmtMetaModel switchStmtMetaModel = new SwitchStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final SynchronizedStmtMetaModel synchronizedStmtMetaModel = new SynchronizedStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final ThrowStmtMetaModel throwStmtMetaModel = new ThrowStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final TryStmtMetaModel tryStmtMetaModel = new TryStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final LocalClassDeclarationStmtMetaModel localClassDeclarationStmtMetaModel = new LocalClassDeclarationStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final WhileStmtMetaModel whileStmtMetaModel = new WhileStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final UnparsableStmtMetaModel unparsableStmtMetaModel = new UnparsableStmtMetaModel(Optional.of(statementMetaModel));
+
+    public static final ArrayTypeMetaModel arrayTypeMetaModel = new ArrayTypeMetaModel(Optional.of(referenceTypeMetaModel));
+
+    public static final ClassOrInterfaceTypeMetaModel classOrInterfaceTypeMetaModel = new ClassOrInterfaceTypeMetaModel(Optional.of(referenceTypeMetaModel));
+
+    public static final IntersectionTypeMetaModel intersectionTypeMetaModel = new IntersectionTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final PrimitiveTypeMetaModel primitiveTypeMetaModel = new PrimitiveTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final TypeParameterMetaModel typeParameterMetaModel = new TypeParameterMetaModel(Optional.of(referenceTypeMetaModel));
+
+    public static final UnionTypeMetaModel unionTypeMetaModel = new UnionTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final UnknownTypeMetaModel unknownTypeMetaModel = new UnknownTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final VoidTypeMetaModel voidTypeMetaModel = new VoidTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final WildcardTypeMetaModel wildcardTypeMetaModel = new WildcardTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final VarTypeMetaModel varTypeMetaModel = new VarTypeMetaModel(Optional.of(typeMetaModel));
+
+    public static final ModuleRequiresStmtMetaModel moduleRequiresStmtMetaModel = new ModuleRequiresStmtMetaModel(Optional.of(moduleStmtMetaModel));
+
+    public static final ModuleExportsStmtMetaModel moduleExportsStmtMetaModel = new ModuleExportsStmtMetaModel(Optional.of(moduleStmtMetaModel));
+
+    public static final ModuleProvidesStmtMetaModel moduleProvidesStmtMetaModel = new ModuleProvidesStmtMetaModel(Optional.of(moduleStmtMetaModel));
+
+    public static final ModuleUsesStmtMetaModel moduleUsesStmtMetaModel = new ModuleUsesStmtMetaModel(Optional.of(moduleStmtMetaModel));
+
+    public static final ModuleOpensStmtMetaModel moduleOpensStmtMetaModel = new ModuleOpensStmtMetaModel(Optional.of(moduleStmtMetaModel));
+
+    static {
+        initializeNodeMetaModels();
+        initializePropertyMetaModels();
+        initializeConstructorParameters();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavadocCommentMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavadocCommentMetaModel.java
new file mode 100644
index 0000000..4da2007
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/JavadocCommentMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class JavadocCommentMetaModel extends CommentMetaModel {
+
+    JavadocCommentMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.comments.JavadocComment.class, "JavadocComment", "com.github.javaparser.ast.comments", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/LabeledStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LabeledStmtMetaModel.java
new file mode 100644
index 0000000..d8532ef
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LabeledStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class LabeledStmtMetaModel extends StatementMetaModel {
+
+    LabeledStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.LabeledStmt.class, "LabeledStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel labelPropertyMetaModel;
+
+    public PropertyMetaModel statementPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/LambdaExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LambdaExprMetaModel.java
new file mode 100644
index 0000000..ad50a65
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LambdaExprMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class LambdaExprMetaModel extends ExpressionMetaModel {
+
+    LambdaExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.LambdaExpr.class, "LambdaExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel isEnclosingParametersPropertyMetaModel;
+
+    public PropertyMetaModel parametersPropertyMetaModel;
+
+    public PropertyMetaModel expressionBodyPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/LineCommentMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LineCommentMetaModel.java
new file mode 100644
index 0000000..dfc8bbd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LineCommentMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class LineCommentMetaModel extends CommentMetaModel {
+
+    LineCommentMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.comments.LineComment.class, "LineComment", "com.github.javaparser.ast.comments", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/LiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LiteralExprMetaModel.java
new file mode 100644
index 0000000..47f9fcd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LiteralExprMetaModel.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class LiteralExprMetaModel extends ExpressionMetaModel {
+
+    LiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.LiteralExpr.class, "LiteralExpr", "com.github.javaparser.ast.expr", true, false);
+    }
+
+    protected LiteralExprMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/LiteralStringValueExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LiteralStringValueExprMetaModel.java
new file mode 100644
index 0000000..6ed8578
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LiteralStringValueExprMetaModel.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class LiteralStringValueExprMetaModel extends LiteralExprMetaModel {
+
+    LiteralStringValueExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.LiteralStringValueExpr.class, "LiteralStringValueExpr", "com.github.javaparser.ast.expr", true, false);
+    }
+
+    protected LiteralStringValueExprMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel valuePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/LocalClassDeclarationStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LocalClassDeclarationStmtMetaModel.java
new file mode 100644
index 0000000..d936eb0
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LocalClassDeclarationStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class LocalClassDeclarationStmtMetaModel extends StatementMetaModel {
+
+    LocalClassDeclarationStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.LocalClassDeclarationStmt.class, "LocalClassDeclarationStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel classDeclarationPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/LongLiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LongLiteralExprMetaModel.java
new file mode 100644
index 0000000..42006b5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/LongLiteralExprMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class LongLiteralExprMetaModel extends LiteralStringValueExprMetaModel {
+
+    LongLiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.LongLiteralExpr.class, "LongLiteralExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/MarkerAnnotationExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MarkerAnnotationExprMetaModel.java
new file mode 100644
index 0000000..0371b51
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MarkerAnnotationExprMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class MarkerAnnotationExprMetaModel extends AnnotationExprMetaModel {
+
+    MarkerAnnotationExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.MarkerAnnotationExpr.class, "MarkerAnnotationExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/MemberValuePairMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MemberValuePairMetaModel.java
new file mode 100644
index 0000000..6521818
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MemberValuePairMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class MemberValuePairMetaModel extends NodeMetaModel {
+
+    MemberValuePairMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.MemberValuePair.class, "MemberValuePair", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel valuePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodCallExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodCallExprMetaModel.java
new file mode 100644
index 0000000..728407c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodCallExprMetaModel.java
@@ -0,0 +1,20 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class MethodCallExprMetaModel extends ExpressionMetaModel {
+
+    MethodCallExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.MethodCallExpr.class, "MethodCallExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel argumentsPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel scopePropertyMetaModel;
+
+    public PropertyMetaModel typeArgumentsPropertyMetaModel;
+
+    public PropertyMetaModel usingDiamondOperatorPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodDeclarationMetaModel.java
new file mode 100644
index 0000000..74aaeae
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodDeclarationMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class MethodDeclarationMetaModel extends CallableDeclarationMetaModel {
+
+    MethodDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.MethodDeclaration.class, "MethodDeclaration", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodReferenceExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodReferenceExprMetaModel.java
new file mode 100644
index 0000000..4968046
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/MethodReferenceExprMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class MethodReferenceExprMetaModel extends ExpressionMetaModel {
+
+    MethodReferenceExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.MethodReferenceExpr.class, "MethodReferenceExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel identifierPropertyMetaModel;
+
+    public PropertyMetaModel scopePropertyMetaModel;
+
+    public PropertyMetaModel typeArgumentsPropertyMetaModel;
+
+    public PropertyMetaModel usingDiamondOperatorPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleDeclarationMetaModel.java
new file mode 100644
index 0000000..0cf3c3e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleDeclarationMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ModuleDeclarationMetaModel extends NodeMetaModel {
+
+    ModuleDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.modules.ModuleDeclaration.class, "ModuleDeclaration", "com.github.javaparser.ast.modules", false, false);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+
+    public PropertyMetaModel isOpenPropertyMetaModel;
+
+    public PropertyMetaModel moduleStmtsPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleExportsStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleExportsStmtMetaModel.java
new file mode 100644
index 0000000..7b6af7e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleExportsStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ModuleExportsStmtMetaModel extends ModuleStmtMetaModel {
+
+    ModuleExportsStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.modules.ModuleExportsStmt.class, "ModuleExportsStmt", "com.github.javaparser.ast.modules", false, false);
+    }
+
+    public PropertyMetaModel moduleNamesPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleOpensStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleOpensStmtMetaModel.java
new file mode 100644
index 0000000..16a5a48
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleOpensStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ModuleOpensStmtMetaModel extends ModuleStmtMetaModel {
+
+    ModuleOpensStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.modules.ModuleOpensStmt.class, "ModuleOpensStmt", "com.github.javaparser.ast.modules", false, false);
+    }
+
+    public PropertyMetaModel moduleNamesPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleProvidesStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleProvidesStmtMetaModel.java
new file mode 100644
index 0000000..2c3bffc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleProvidesStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ModuleProvidesStmtMetaModel extends ModuleStmtMetaModel {
+
+    ModuleProvidesStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.modules.ModuleProvidesStmt.class, "ModuleProvidesStmt", "com.github.javaparser.ast.modules", false, false);
+    }
+
+    public PropertyMetaModel typePropertyMetaModel;
+
+    public PropertyMetaModel withTypesPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleRequiresStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleRequiresStmtMetaModel.java
new file mode 100644
index 0000000..320a811
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleRequiresStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ModuleRequiresStmtMetaModel extends ModuleStmtMetaModel {
+
+    ModuleRequiresStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.modules.ModuleRequiresStmt.class, "ModuleRequiresStmt", "com.github.javaparser.ast.modules", false, false);
+    }
+
+    public PropertyMetaModel modifiersPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleStmtMetaModel.java
new file mode 100644
index 0000000..63ca214
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleStmtMetaModel.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class ModuleStmtMetaModel extends NodeMetaModel {
+
+    ModuleStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.modules.ModuleStmt.class, "ModuleStmt", "com.github.javaparser.ast.modules", true, false);
+    }
+
+    protected ModuleStmtMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleUsesStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleUsesStmtMetaModel.java
new file mode 100644
index 0000000..bac9043
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ModuleUsesStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ModuleUsesStmtMetaModel extends ModuleStmtMetaModel {
+
+    ModuleUsesStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.modules.ModuleUsesStmt.class, "ModuleUsesStmt", "com.github.javaparser.ast.modules", false, false);
+    }
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/NameExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NameExprMetaModel.java
new file mode 100644
index 0000000..bed2961
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NameExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class NameExprMetaModel extends ExpressionMetaModel {
+
+    NameExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.NameExpr.class, "NameExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/NameMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NameMetaModel.java
new file mode 100644
index 0000000..cd54085
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NameMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class NameMetaModel extends NodeMetaModel {
+
+    NameMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.Name.class, "Name", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+
+    public PropertyMetaModel identifierPropertyMetaModel;
+
+    public PropertyMetaModel qualifierPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/NodeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NodeMetaModel.java
new file mode 100644
index 0000000..332dfd4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NodeMetaModel.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class NodeMetaModel extends BaseNodeMetaModel {
+
+    NodeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.Node.class, "Node", "com.github.javaparser.ast", true, false);
+    }
+
+    protected NodeMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel commentPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/NonEmptyProperty.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NonEmptyProperty.java
new file mode 100644
index 0000000..7be7fdc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NonEmptyProperty.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Indicate that leaving this property empty does not lead to a correct AST.
+ * Empty means either empty string or empty collection.
+ * (Used during generation of the meta model.)
+ */
+@Retention(RUNTIME)
+@Target({FIELD, METHOD})
+public @interface NonEmptyProperty {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/NormalAnnotationExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NormalAnnotationExprMetaModel.java
new file mode 100644
index 0000000..a88a777
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NormalAnnotationExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class NormalAnnotationExprMetaModel extends AnnotationExprMetaModel {
+
+    NormalAnnotationExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.NormalAnnotationExpr.class, "NormalAnnotationExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel pairsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/NullLiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NullLiteralExprMetaModel.java
new file mode 100644
index 0000000..698fb30
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/NullLiteralExprMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class NullLiteralExprMetaModel extends LiteralExprMetaModel {
+
+    NullLiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.NullLiteralExpr.class, "NullLiteralExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ObjectCreationExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ObjectCreationExprMetaModel.java
new file mode 100644
index 0000000..4149d1d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ObjectCreationExprMetaModel.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ObjectCreationExprMetaModel extends ExpressionMetaModel {
+
+    ObjectCreationExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.ObjectCreationExpr.class, "ObjectCreationExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel anonymousClassBodyPropertyMetaModel;
+
+    public PropertyMetaModel argumentsPropertyMetaModel;
+
+    public PropertyMetaModel scopePropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+
+    public PropertyMetaModel typeArgumentsPropertyMetaModel;
+
+    public PropertyMetaModel usingDiamondOperatorPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/OptionalProperty.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/OptionalProperty.java
new file mode 100644
index 0000000..5052e3b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/OptionalProperty.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Indicate an optional property of a Node.
+ * (Used during generation of the meta model.)
+ */
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface OptionalProperty {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/PackageDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/PackageDeclarationMetaModel.java
new file mode 100644
index 0000000..3ae52b4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/PackageDeclarationMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class PackageDeclarationMetaModel extends NodeMetaModel {
+
+    PackageDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.PackageDeclaration.class, "PackageDeclaration", "com.github.javaparser.ast", false, false);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ParameterMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ParameterMetaModel.java
new file mode 100644
index 0000000..034b5c7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ParameterMetaModel.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ParameterMetaModel extends NodeMetaModel {
+
+    ParameterMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.Parameter.class, "Parameter", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+
+    public PropertyMetaModel isVarArgsPropertyMetaModel;
+
+    public PropertyMetaModel modifiersPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+
+    public PropertyMetaModel varArgsAnnotationsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/PrimitiveTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/PrimitiveTypeMetaModel.java
new file mode 100644
index 0000000..71ee28c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/PrimitiveTypeMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class PrimitiveTypeMetaModel extends TypeMetaModel {
+
+    PrimitiveTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.PrimitiveType.class, "PrimitiveType", "com.github.javaparser.ast.type", false, false);
+    }
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/PropertyMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/PropertyMetaModel.java
new file mode 100644
index 0000000..5dcf4af
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/PropertyMetaModel.java
@@ -0,0 +1,248 @@
+package com.github.javaparser.metamodel;
+
+import com.github.javaparser.ast.Node;
+
+import java.lang.reflect.Field;
+import java.util.Optional;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.getterName;
+import static com.github.javaparser.utils.CodeGenerationUtils.setterName;
+
+/**
+ * Meta-data about a property of a node in the AST.
+ */
+public class PropertyMetaModel {
+    private final BaseNodeMetaModel containingNodeMetaModel;
+    private final String name;
+    private final Class<?> type;
+    private final Optional<BaseNodeMetaModel> nodeReference;
+    private final boolean isOptional;
+    private final boolean isNonEmpty;
+    private final boolean isNodeList;
+    private final boolean isEnumSet;
+    private final boolean hasWildcard;
+
+    public PropertyMetaModel(BaseNodeMetaModel containingNodeMetaModel, String name, Class<?> type, Optional<BaseNodeMetaModel> nodeReference, boolean isOptional, boolean isNonEmpty, boolean isNodeList, boolean isEnumSet, boolean hasWildcard) {
+        this.containingNodeMetaModel = containingNodeMetaModel;
+        this.name = name;
+        this.type = type;
+        this.nodeReference = nodeReference;
+        this.isOptional = isOptional;
+        this.isNonEmpty = isNonEmpty;
+        this.isNodeList = isNodeList;
+        this.isEnumSet = isEnumSet;
+        this.hasWildcard = hasWildcard;
+    }
+
+    /**
+     * @return is this the field fieldName on class c?
+     */
+    public boolean is(Class<? extends Node> c, String fieldName) {
+        return containingNodeMetaModel.is(c) && name.equals(fieldName);
+    }
+
+    /**
+     * @return is this fields called fieldName?
+     */
+    public boolean is(String fieldName) {
+        return name.equals(fieldName);
+    }
+
+    /**
+     * @return the name used in the AST for the setter
+     */
+    public String getSetterMethodName() {
+        return setterName(name);
+    }
+
+    /**
+     * @return the name used in the AST for the getter
+     */
+    public String getGetterMethodName() {
+        return getterName(type, name);
+    }
+
+    /**
+     * @return the NodeMetaModel that "has" this property.
+     */
+    public BaseNodeMetaModel getContainingNodeMetaModel() {
+        return containingNodeMetaModel;
+    }
+
+    /**
+     * @return the name of the property. This is equal to the name of the field in the AST.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @return if this property is a String or a NodeList: whether it may be empty.
+     */
+    public boolean isNonEmpty() {
+        return isNonEmpty;
+    }
+
+    /**
+     * @return the class of the field.
+     */
+    public Class<?> getType() {
+        return type;
+    }
+
+    /**
+     * @return if this property is a Node, this will get the node meta model.
+     */
+    public Optional<BaseNodeMetaModel> getNodeReference() {
+        return nodeReference;
+    }
+
+    /**
+     * @return whether this property is optional.
+     */
+    public boolean isOptional() {
+        return isOptional;
+    }
+
+    /**
+     * @return whether this property is not optional.
+     */
+    public boolean isRequired() {
+        return !isOptional;
+    }
+
+    /**
+     * @return whether this property is contained in a NodeList.
+     */
+    public boolean isNodeList() {
+        return isNodeList;
+    }
+
+    /**
+     * @return whether this property is contained in an EnumSet.
+     */
+    public boolean isEnumSet() {
+        return isEnumSet;
+    }
+
+    /**
+     * @return whether this property has a wildcard following it, like BodyDeclaration&lt;?&gt;.
+     */
+    public boolean hasWildcard() {
+        return hasWildcard;
+    }
+
+    /**
+     * @return whether this property is not a list or set.
+     */
+    public boolean isSingular() {
+        return !(isNodeList || isEnumSet);
+    }
+
+    @Override
+    public String toString() {
+        return "(" + getTypeName() + ")\t" + containingNodeMetaModel + "#" + name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PropertyMetaModel that = (PropertyMetaModel) o;
+
+        if (!name.equals(that.name)) return false;
+        if (!type.equals(that.type)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = 31 * result + type.hashCode();
+        return result;
+    }
+
+    /**
+     * @return the type of a single element of this property, so no Optional or NodeList or EnumSet.
+     */
+    public String getTypeNameGenerified() {
+        if (hasWildcard) {
+            return getTypeName() + "<?>";
+        }
+        return getTypeName();
+    }
+
+    /**
+     * @return the raw type of a single element of this property, so nothing but the name.
+     */
+    public String getTypeName() {
+        return type.getSimpleName();
+    }
+
+    /**
+     * @return the type that is returned from getters in the AST.
+     */
+    public String getTypeNameForGetter() {
+        if (isOptional) {
+            return "Optional<" + getTypeNameForSetter() + ">";
+        }
+        return getTypeNameForSetter();
+    }
+
+    /**
+     * @return the type that is passed to setters in the AST.
+     */
+    public String getTypeNameForSetter() {
+        if (isNodeList) {
+            return "NodeList<" + getTypeNameGenerified() + ">";
+        }
+        if (isEnumSet) {
+            return "EnumSet<" + getTypeNameGenerified() + ">";
+        }
+        return getTypeNameGenerified();
+    }
+
+    /**
+     * @return is this property an AST Node?
+     */
+    public boolean isNode() {
+        return getNodeReference().isPresent();
+    }
+
+    /**
+     * The name of the field in the containing BaseNodeMetaModel for this property meta model.
+     */
+    public String getMetaModelFieldName() {
+        return getName() + "PropertyMetaModel";
+    }
+
+    /**
+     * @return is this property an attribute, meaning: not a node?
+     */
+    public boolean isAttribute() {
+        return !isNode();
+    }
+
+    /**
+     * Introspects the node to get the value from this field.
+     * Note that an optional empty field will return null here.
+     */
+    public Object getValue(Node node) {
+        try {
+            for (Class<?> c = node.getClass(); c != null; c = c.getSuperclass()) {
+                Field[] fields = c.getDeclaredFields();
+                for (Field classField : fields) {
+                    if (classField.getName().equals(getName())) {
+                        classField.setAccessible(true);
+                        return classField.get(node);
+                    }
+                }
+            }
+            throw new NoSuchFieldError(getName());
+        } catch (IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReceiverParameterMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReceiverParameterMetaModel.java
new file mode 100644
index 0000000..e0fb463
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReceiverParameterMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ReceiverParameterMetaModel extends NodeMetaModel {
+
+    ReceiverParameterMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.ReceiverParameter.class, "ReceiverParameter", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReferenceTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReferenceTypeMetaModel.java
new file mode 100644
index 0000000..fa0361b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReferenceTypeMetaModel.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class ReferenceTypeMetaModel extends TypeMetaModel {
+
+    ReferenceTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.ReferenceType.class, "ReferenceType", "com.github.javaparser.ast.type", true, false);
+    }
+
+    protected ReferenceTypeMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReturnStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReturnStmtMetaModel.java
new file mode 100644
index 0000000..27af5ec
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ReturnStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ReturnStmtMetaModel extends StatementMetaModel {
+
+    ReturnStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.ReturnStmt.class, "ReturnStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/SimpleNameMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SimpleNameMetaModel.java
new file mode 100644
index 0000000..1c04296
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SimpleNameMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class SimpleNameMetaModel extends NodeMetaModel {
+
+    SimpleNameMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.SimpleName.class, "SimpleName", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel identifierPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/SingleMemberAnnotationExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SingleMemberAnnotationExprMetaModel.java
new file mode 100644
index 0000000..a5223cd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SingleMemberAnnotationExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class SingleMemberAnnotationExprMetaModel extends AnnotationExprMetaModel {
+
+    SingleMemberAnnotationExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.class, "SingleMemberAnnotationExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel memberValuePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/StatementMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/StatementMetaModel.java
new file mode 100644
index 0000000..8433ab0
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/StatementMetaModel.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class StatementMetaModel extends NodeMetaModel {
+
+    StatementMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.Statement.class, "Statement", "com.github.javaparser.ast.stmt", true, false);
+    }
+
+    protected StatementMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/StringLiteralExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/StringLiteralExprMetaModel.java
new file mode 100644
index 0000000..1dc0acf
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/StringLiteralExprMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class StringLiteralExprMetaModel extends LiteralStringValueExprMetaModel {
+
+    StringLiteralExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.StringLiteralExpr.class, "StringLiteralExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/SuperExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SuperExprMetaModel.java
new file mode 100644
index 0000000..745df8b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SuperExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class SuperExprMetaModel extends ExpressionMetaModel {
+
+    SuperExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.SuperExpr.class, "SuperExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel classExprPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/SwitchEntryStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SwitchEntryStmtMetaModel.java
new file mode 100644
index 0000000..b8e6252
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SwitchEntryStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class SwitchEntryStmtMetaModel extends StatementMetaModel {
+
+    SwitchEntryStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.SwitchEntryStmt.class, "SwitchEntryStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel labelPropertyMetaModel;
+
+    public PropertyMetaModel statementsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/SwitchStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SwitchStmtMetaModel.java
new file mode 100644
index 0000000..dc9df0e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SwitchStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class SwitchStmtMetaModel extends StatementMetaModel {
+
+    SwitchStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.SwitchStmt.class, "SwitchStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel entriesPropertyMetaModel;
+
+    public PropertyMetaModel selectorPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/SynchronizedStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SynchronizedStmtMetaModel.java
new file mode 100644
index 0000000..01a8709
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/SynchronizedStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class SynchronizedStmtMetaModel extends StatementMetaModel {
+
+    SynchronizedStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.SynchronizedStmt.class, "SynchronizedStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ThisExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ThisExprMetaModel.java
new file mode 100644
index 0000000..fbfd5a5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ThisExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ThisExprMetaModel extends ExpressionMetaModel {
+
+    ThisExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.ThisExpr.class, "ThisExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel classExprPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/ThrowStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ThrowStmtMetaModel.java
new file mode 100644
index 0000000..c5bd2e1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/ThrowStmtMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class ThrowStmtMetaModel extends StatementMetaModel {
+
+    ThrowStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.ThrowStmt.class, "ThrowStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/TryStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TryStmtMetaModel.java
new file mode 100644
index 0000000..28756db
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TryStmtMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class TryStmtMetaModel extends StatementMetaModel {
+
+    TryStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.TryStmt.class, "TryStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel catchClausesPropertyMetaModel;
+
+    public PropertyMetaModel finallyBlockPropertyMetaModel;
+
+    public PropertyMetaModel resourcesPropertyMetaModel;
+
+    public PropertyMetaModel tryBlockPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeDeclarationMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeDeclarationMetaModel.java
new file mode 100644
index 0000000..f7f0d00
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeDeclarationMetaModel.java
@@ -0,0 +1,21 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class TypeDeclarationMetaModel extends BodyDeclarationMetaModel {
+
+    TypeDeclarationMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.TypeDeclaration.class, "TypeDeclaration", "com.github.javaparser.ast.body", true, true);
+    }
+
+    protected TypeDeclarationMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel membersPropertyMetaModel;
+
+    public PropertyMetaModel modifiersPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeExprMetaModel.java
new file mode 100644
index 0000000..8d0b90d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeExprMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class TypeExprMetaModel extends ExpressionMetaModel {
+
+    TypeExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.TypeExpr.class, "TypeExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeMetaModel.java
new file mode 100644
index 0000000..76b084b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeMetaModel.java
@@ -0,0 +1,17 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+import com.github.javaparser.ast.Node;
+
+public class TypeMetaModel extends NodeMetaModel {
+
+    TypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.Type.class, "Type", "com.github.javaparser.ast.type", true, false);
+    }
+
+    protected TypeMetaModel(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {
+        super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeParameterMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeParameterMetaModel.java
new file mode 100644
index 0000000..2e87402
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/TypeParameterMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class TypeParameterMetaModel extends ReferenceTypeMetaModel {
+
+    TypeParameterMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.TypeParameter.class, "TypeParameter", "com.github.javaparser.ast.type", false, false);
+    }
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel typeBoundPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnaryExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnaryExprMetaModel.java
new file mode 100644
index 0000000..309af9a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnaryExprMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class UnaryExprMetaModel extends ExpressionMetaModel {
+
+    UnaryExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.UnaryExpr.class, "UnaryExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel expressionPropertyMetaModel;
+
+    public PropertyMetaModel operatorPropertyMetaModel;
+
+    public PropertyMetaModel postfixPropertyMetaModel;
+
+    public PropertyMetaModel prefixPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnionTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnionTypeMetaModel.java
new file mode 100644
index 0000000..14e81be
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnionTypeMetaModel.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class UnionTypeMetaModel extends TypeMetaModel {
+
+    UnionTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.UnionType.class, "UnionType", "com.github.javaparser.ast.type", false, false);
+    }
+
+    public PropertyMetaModel elementsPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnknownTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnknownTypeMetaModel.java
new file mode 100644
index 0000000..d83518b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnknownTypeMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class UnknownTypeMetaModel extends TypeMetaModel {
+
+    UnknownTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.UnknownType.class, "UnknownType", "com.github.javaparser.ast.type", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnparsableStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnparsableStmtMetaModel.java
new file mode 100644
index 0000000..7d18f74
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/UnparsableStmtMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class UnparsableStmtMetaModel extends StatementMetaModel {
+
+    UnparsableStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.UnparsableStmt.class, "UnparsableStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/VarTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VarTypeMetaModel.java
new file mode 100644
index 0000000..1ada830
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VarTypeMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class VarTypeMetaModel extends TypeMetaModel {
+
+    VarTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.VarType.class, "VarType", "com.github.javaparser.ast.type", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/VariableDeclarationExprMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VariableDeclarationExprMetaModel.java
new file mode 100644
index 0000000..c9c30c0
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VariableDeclarationExprMetaModel.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class VariableDeclarationExprMetaModel extends ExpressionMetaModel {
+
+    VariableDeclarationExprMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.expr.VariableDeclarationExpr.class, "VariableDeclarationExpr", "com.github.javaparser.ast.expr", false, false);
+    }
+
+    public PropertyMetaModel annotationsPropertyMetaModel;
+
+    public PropertyMetaModel modifiersPropertyMetaModel;
+
+    public PropertyMetaModel variablesPropertyMetaModel;
+
+    public PropertyMetaModel maximumCommonTypePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/VariableDeclaratorMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VariableDeclaratorMetaModel.java
new file mode 100644
index 0000000..83f12ac
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VariableDeclaratorMetaModel.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class VariableDeclaratorMetaModel extends NodeMetaModel {
+
+    VariableDeclaratorMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.body.VariableDeclarator.class, "VariableDeclarator", "com.github.javaparser.ast.body", false, false);
+    }
+
+    public PropertyMetaModel initializerPropertyMetaModel;
+
+    public PropertyMetaModel namePropertyMetaModel;
+
+    public PropertyMetaModel typePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/VoidTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VoidTypeMetaModel.java
new file mode 100644
index 0000000..bb92f56
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/VoidTypeMetaModel.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class VoidTypeMetaModel extends TypeMetaModel {
+
+    VoidTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.VoidType.class, "VoidType", "com.github.javaparser.ast.type", false, false);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/WhileStmtMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/WhileStmtMetaModel.java
new file mode 100644
index 0000000..83a122d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/WhileStmtMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class WhileStmtMetaModel extends StatementMetaModel {
+
+    WhileStmtMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.stmt.WhileStmt.class, "WhileStmt", "com.github.javaparser.ast.stmt", false, false);
+    }
+
+    public PropertyMetaModel bodyPropertyMetaModel;
+
+    public PropertyMetaModel conditionPropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/metamodel/WildcardTypeMetaModel.java b/javaparser-core/src/main/java/com/github/javaparser/metamodel/WildcardTypeMetaModel.java
new file mode 100644
index 0000000..0d4b9fc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/metamodel/WildcardTypeMetaModel.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.metamodel;
+
+import java.util.Optional;
+
+public class WildcardTypeMetaModel extends TypeMetaModel {
+
+    WildcardTypeMetaModel(Optional<BaseNodeMetaModel> superBaseNodeMetaModel) {
+        super(superBaseNodeMetaModel, com.github.javaparser.ast.type.WildcardType.class, "WildcardType", "com.github.javaparser.ast.type", false, false);
+    }
+
+    public PropertyMetaModel extendedTypePropertyMetaModel;
+
+    public PropertyMetaModel superTypePropertyMetaModel;
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/ConcreteSyntaxModel.java b/javaparser-core/src/main/java/com/github/javaparser/printer/ConcreteSyntaxModel.java
new file mode 100644
index 0000000..e45ed75
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/ConcreteSyntaxModel.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.metamodel.JavaParserMetaModel;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmConditional;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmElement;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmMix;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.*;
+import static com.github.javaparser.ast.observer.ObservableProperty.*;
+import static com.github.javaparser.printer.concretesyntaxmodel.CsmConditional.Condition.*;
+import static com.github.javaparser.printer.concretesyntaxmodel.CsmElement.*;
+import static com.github.javaparser.utils.Utils.EOL;
+
+/**
+ * The Concrete Syntax Model for a single node type. It knows the syntax used to represent a certain element in Java
+ * code.
+ */
+public class ConcreteSyntaxModel {
+
+    private static final Map<Class, CsmElement> concreteSyntaxModelByClass = new HashMap<>();
+    private static Optional<String> initializationError;
+
+    private static CsmElement modifiers() {
+        return list(ObservableProperty.MODIFIERS, space(), none(), space());
+    }
+
+    /**
+     * Build a mix collecting all the elements specified.
+     */
+    private static CsmElement mix(CsmElement... elements) {
+        return new CsmMix(Arrays.asList(elements));
+    }
+
+    private static CsmElement memberAnnotations() {
+        return list(ObservableProperty.ANNOTATIONS, newline(), none(), newline());
+    }
+
+    private static CsmElement annotations() {
+        return list(ObservableProperty.ANNOTATIONS, space(), none(), newline());
+    }
+
+    private static CsmElement typeParameters() {
+        return list(ObservableProperty.TYPE_PARAMETERS, CsmElement.sequence(CsmElement.comma(), CsmElement.space()), CsmElement.token(GeneratedJavaParserConstants.LT),
+                CsmElement.sequence(CsmElement.token(GeneratedJavaParserConstants.GT), CsmElement.space()));
+    }
+
+    private static CsmElement typeArguments() {
+        return list(ObservableProperty.TYPE_ARGUMENTS, CsmElement.sequence(CsmElement.comma(), CsmElement.space()), CsmElement.token(GeneratedJavaParserConstants.LT),
+                CsmElement.sequence(CsmElement.token(GeneratedJavaParserConstants.GT)));
+    }
+
+    static {
+
+        ///
+        /// Body
+        ///
+
+        concreteSyntaxModelByClass.put(AnnotationDeclaration.class, CsmElement.sequence(
+                CsmElement.comment(),
+                memberAnnotations(),
+                modifiers(),
+                CsmElement.token(GeneratedJavaParserConstants.AT),
+                CsmElement.token(GeneratedJavaParserConstants.INTERFACE),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.space(),
+                CsmElement.token(LBRACE),
+                CsmElement.newline(),
+                CsmElement.indent(),
+                CsmElement.list(ObservableProperty.MEMBERS, CsmElement.newline(), CsmElement.none(), CsmElement.none(), CsmElement.newline()),
+                CsmElement.unindent(),
+                CsmElement.token(RBRACE)
+        ));
+
+        concreteSyntaxModelByClass.put(AnnotationMemberDeclaration.class, CsmElement.sequence(
+                CsmElement.comment(),
+                memberAnnotations(),
+                modifiers(),
+                CsmElement.child(ObservableProperty.TYPE),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.token(LPAREN),
+                CsmElement.token(RPAREN),
+                CsmElement.conditional(ObservableProperty.DEFAULT_VALUE, IS_PRESENT, CsmElement.sequence(CsmElement.space(), CsmElement.token(GeneratedJavaParserConstants._DEFAULT), CsmElement.space(), CsmElement.child(DEFAULT_VALUE))),
+                CsmElement.semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(ClassOrInterfaceDeclaration.class, sequence(
+                comment(),
+                list(ObservableProperty.ANNOTATIONS, newline(), none(), newline()),
+                modifiers(),
+                conditional(ObservableProperty.INTERFACE, FLAG, token(GeneratedJavaParserConstants.INTERFACE), token(GeneratedJavaParserConstants.CLASS)),
+                space(),
+                child(ObservableProperty.NAME),
+                list(TYPE_PARAMETERS, sequence(comma(), space()), string(GeneratedJavaParserConstants.LT), string(GeneratedJavaParserConstants.GT)),
+                list(ObservableProperty.EXTENDED_TYPES,
+                        sequence(string(GeneratedJavaParserConstants.COMMA), space()),
+                        sequence(space(), token(GeneratedJavaParserConstants.EXTENDS), space()),
+                        none()),
+                list(ObservableProperty.IMPLEMENTED_TYPES, sequence(string(GeneratedJavaParserConstants.COMMA), space()), sequence(
+                        space(),
+                        token(GeneratedJavaParserConstants.IMPLEMENTS),
+                        space()), none()),
+                space(),
+                block(sequence(newline(), list(ObservableProperty.MEMBERS, sequence(newline(), newline()), CsmElement.newline(), newline())))
+        ));
+
+        concreteSyntaxModelByClass.put(ConstructorDeclaration.class, sequence(
+                comment(),
+                memberAnnotations(),
+                modifiers(),
+                typeParameters(),
+                child(ObservableProperty.NAME),
+                token(GeneratedJavaParserConstants.LPAREN),
+                list(ObservableProperty.PARAMETERS, sequence(comma(), space()), none(), none()),
+                token(GeneratedJavaParserConstants.RPAREN),
+                list(ObservableProperty.THROWN_EXCEPTIONS, sequence(comma(), space()), sequence(space(), token(GeneratedJavaParserConstants.THROWS), space()), none()),
+                space(),
+                child(ObservableProperty.BODY)
+        ));
+
+        concreteSyntaxModelByClass.put(EnumConstantDeclaration.class, sequence(
+                comment(),
+                memberAnnotations(),
+                child(ObservableProperty.NAME),
+                list(ObservableProperty.ARGUMENTS, sequence(comma(), space()), token(GeneratedJavaParserConstants.LPAREN), token(GeneratedJavaParserConstants.RPAREN)),
+                conditional(CLASS_BODY, IS_NOT_EMPTY, sequence(space(), token(GeneratedJavaParserConstants.LBRACE), CsmElement.newline(), CsmElement.indent(), CsmElement.newline(),
+                        list(ObservableProperty.CLASS_BODY, newline(), newline(), none(), CsmElement.newline()),
+                        unindent(),
+                        token(RBRACE), CsmElement.newline()))
+        ));
+
+        concreteSyntaxModelByClass.put(EnumDeclaration.class, sequence(
+                comment(),
+                annotations(),
+                modifiers(),
+                token(GeneratedJavaParserConstants.ENUM),
+                space(),
+                child(ObservableProperty.NAME),
+                list(ObservableProperty.IMPLEMENTED_TYPES,
+                        sequence(comma(), space()),
+                        sequence(space(), token(GeneratedJavaParserConstants.IMPLEMENTS), space()),
+                        none()),
+                space(),
+                token(GeneratedJavaParserConstants.LBRACE),
+                CsmElement.newline(),
+                CsmElement.indent(),
+                CsmElement.newline(),
+                list(ObservableProperty.ENTRIES,
+                        sequence(comma(), space()),
+                        CsmElement.none(),
+                        none()),
+                conditional(ObservableProperty.MEMBERS, IS_EMPTY,
+                        conditional(ObservableProperty.ENTRIES, IS_NOT_EMPTY, newline()),
+                        sequence(CsmElement.semicolon(), newline(), CsmElement.newline(), list(ObservableProperty.MEMBERS, newline(), newline(), none(), CsmElement.newline()))),
+                unindent(),
+                token(RBRACE)
+        ));
+
+        concreteSyntaxModelByClass.put(FieldDeclaration.class, sequence(
+                orphanCommentsBeforeThis(),
+                comment(),
+                annotations(),
+                modifiers(),
+                conditional(ObservableProperty.VARIABLES, IS_NOT_EMPTY, child(ObservableProperty.MAXIMUM_COMMON_TYPE)),
+                space(),
+                list(ObservableProperty.VARIABLES, sequence(comma(), space())),
+                semicolon()));
+
+        concreteSyntaxModelByClass.put(InitializerDeclaration.class, sequence(
+                comment(),
+                conditional(ObservableProperty.STATIC, FLAG, sequence(token(GeneratedJavaParserConstants.STATIC), space())),
+                child(ObservableProperty.BODY)));
+
+        concreteSyntaxModelByClass.put(MethodDeclaration.class, sequence(
+                orphanCommentsBeforeThis(),
+                comment(),
+                mix(memberAnnotations(), modifiers()),
+                typeParameters(),
+                child(ObservableProperty.TYPE),
+                space(),
+                child(ObservableProperty.NAME),
+                token(GeneratedJavaParserConstants.LPAREN),
+                conditional(ObservableProperty.RECEIVER_PARAMETER, IS_PRESENT, sequence(child(ObservableProperty.RECEIVER_PARAMETER), comma(), space())),
+                list(ObservableProperty.PARAMETERS, sequence(comma(), space()), none(), none()),
+                token(GeneratedJavaParserConstants.RPAREN),
+                list(ObservableProperty.THROWN_EXCEPTIONS, sequence(comma(), space()), sequence(space(), token(GeneratedJavaParserConstants.THROWS), space()), none()),
+                conditional(ObservableProperty.BODY, IS_PRESENT, sequence(space(), child(ObservableProperty.BODY)), semicolon())
+        ));
+
+        concreteSyntaxModelByClass.put(Parameter.class, sequence(
+                comment(),
+                list(ObservableProperty.ANNOTATIONS, CsmElement.space(), CsmElement.none(), CsmElement.space()),
+                modifiers(),
+                child(ObservableProperty.TYPE),
+                conditional(ObservableProperty.VAR_ARGS, FLAG, CsmElement.sequence(
+                        list(ObservableProperty.VAR_ARGS_ANNOTATIONS, CsmElement.space(), CsmElement.none(), CsmElement.none()),
+                        token(GeneratedJavaParserConstants.ELLIPSIS))),
+                space(),
+                child(ObservableProperty.NAME)));
+
+        concreteSyntaxModelByClass.put(ReceiverParameter.class, sequence(
+                comment(),
+                list(ObservableProperty.ANNOTATIONS, CsmElement.space(), CsmElement.none(), CsmElement.space()),
+                child(ObservableProperty.TYPE),
+                space(),
+                child(ObservableProperty.NAME)));
+
+        concreteSyntaxModelByClass.put(VariableDeclarator.class, sequence(
+                comment(),
+                child(ObservableProperty.NAME),
+                // FIXME: we should introduce a derived property
+                // list(ObservableProperty.EXTRA_ARRAY_LEVELS),
+                conditional(ObservableProperty.INITIALIZER, IS_PRESENT, sequence(space(), token(GeneratedJavaParserConstants.ASSIGN), space(),
+                        child(ObservableProperty.INITIALIZER)))
+        ));
+
+        ///
+        /// Expressions
+        ///
+
+        concreteSyntaxModelByClass.put(ArrayAccessExpr.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.token(GeneratedJavaParserConstants.LBRACKET),
+                CsmElement.child(ObservableProperty.INDEX),
+                CsmElement.token(GeneratedJavaParserConstants.RBRACKET)
+        ));
+
+        concreteSyntaxModelByClass.put(ArrayCreationExpr.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.NEW),
+                space(),
+                CsmElement.child(ObservableProperty.ELEMENT_TYPE),
+                list(ObservableProperty.LEVELS),
+                conditional(ObservableProperty.INITIALIZER, IS_PRESENT, sequence(space(), child(ObservableProperty.INITIALIZER)))
+        ));
+
+        concreteSyntaxModelByClass.put(ArrayInitializerExpr.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.LBRACE),
+                list(ObservableProperty.VALUES, sequence(comma(), space()), space(), space()),
+                orphanCommentsEnding(),
+                token(RBRACE)));
+
+        concreteSyntaxModelByClass.put(AssignExpr.class, sequence(
+                comment(),
+                child(ObservableProperty.TARGET),
+                space(),
+                attribute(ObservableProperty.OPERATOR),
+                space(),
+                child(ObservableProperty.VALUE)
+        ));
+
+        concreteSyntaxModelByClass.put(BinaryExpr.class, sequence(
+                comment(),
+                child(ObservableProperty.LEFT),
+                space(),
+                attribute(ObservableProperty.OPERATOR),
+                space(),
+                child(ObservableProperty.RIGHT)
+        ));
+
+        concreteSyntaxModelByClass.put(BooleanLiteralExpr.class, sequence(
+                comment(), attribute(VALUE)
+        ));
+
+        concreteSyntaxModelByClass.put(CastExpr.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.LPAREN),
+                child(ObservableProperty.TYPE),
+                token(GeneratedJavaParserConstants.RPAREN),
+                space(),
+                child(ObservableProperty.EXPRESSION)
+        ));
+
+        concreteSyntaxModelByClass.put(CharLiteralExpr.class, sequence(
+                comment(),
+                charToken(ObservableProperty.VALUE)
+        ));
+
+        concreteSyntaxModelByClass.put(ClassExpr.class, sequence(
+                comment(), child(ObservableProperty.TYPE), token(GeneratedJavaParserConstants.DOT), token(GeneratedJavaParserConstants.CLASS)));
+
+        concreteSyntaxModelByClass.put(ConditionalExpr.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.child(ObservableProperty.CONDITION),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.HOOK),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.THEN_EXPR),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.COLON),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.ELSE_EXPR)
+        ));
+
+        concreteSyntaxModelByClass.put(DoubleLiteralExpr.class, sequence(
+                comment(),
+                attribute(ObservableProperty.VALUE)
+        ));
+
+        concreteSyntaxModelByClass.put(EnclosedExpr.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.LPAREN),
+                child(ObservableProperty.INNER),
+                token(GeneratedJavaParserConstants.RPAREN)
+        ));
+
+        concreteSyntaxModelByClass.put(FieldAccessExpr.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.child(SCOPE), 
+                CsmElement.token(GeneratedJavaParserConstants.DOT),
+                child(ObservableProperty.NAME)
+        ));
+
+        concreteSyntaxModelByClass.put(InstanceOfExpr.class, sequence(
+                comment(),
+                child(ObservableProperty.EXPRESSION),
+                space(),
+                token(GeneratedJavaParserConstants.INSTANCEOF),
+                space(),
+                child(ObservableProperty.TYPE)
+        ));
+
+        concreteSyntaxModelByClass.put(IntegerLiteralExpr.class, sequence(
+                comment(),
+                attribute(ObservableProperty.VALUE)
+        ));
+
+        concreteSyntaxModelByClass.put(LambdaExpr.class, sequence(
+                comment(),
+                conditional(ObservableProperty.ENCLOSING_PARAMETERS, FLAG, token(GeneratedJavaParserConstants.LPAREN)),
+                list(ObservableProperty.PARAMETERS, sequence(comma(), space())),
+                conditional(ObservableProperty.ENCLOSING_PARAMETERS, FLAG, token(GeneratedJavaParserConstants.RPAREN)),
+                space(),
+                token(GeneratedJavaParserConstants.ARROW),
+                space(),
+                conditional(ObservableProperty.EXPRESSION_BODY, IS_PRESENT, child(ObservableProperty.EXPRESSION_BODY), child(ObservableProperty.BODY))
+        ));
+
+        concreteSyntaxModelByClass.put(LongLiteralExpr.class, sequence(
+                comment(),
+                attribute(ObservableProperty.VALUE)
+        ));
+
+        concreteSyntaxModelByClass.put(MarkerAnnotationExpr.class, sequence(comment(), token(GeneratedJavaParserConstants.AT), attribute(ObservableProperty.NAME)));
+
+        concreteSyntaxModelByClass.put(MemberValuePair.class, CsmElement.sequence(CsmElement.comment(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.ASSIGN),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.VALUE)));
+
+        concreteSyntaxModelByClass.put(MethodCallExpr.class, sequence(
+                comment(),
+                conditional(ObservableProperty.SCOPE, IS_PRESENT, sequence(child(ObservableProperty.SCOPE), token(GeneratedJavaParserConstants.DOT))),
+                typeArguments(),
+                child(ObservableProperty.NAME),
+                token(GeneratedJavaParserConstants.LPAREN),
+                list(ObservableProperty.ARGUMENTS, sequence(comma(), space()), none(), none()),
+                token(GeneratedJavaParserConstants.RPAREN)
+        ));
+
+        concreteSyntaxModelByClass.put(MethodReferenceExpr.class, sequence(
+                comment(),
+                child(ObservableProperty.SCOPE),
+                token(GeneratedJavaParserConstants.DOUBLECOLON),
+                typeArguments(),
+                attribute(ObservableProperty.IDENTIFIER)
+        ));
+
+        concreteSyntaxModelByClass.put(Name.class, sequence(
+                comment(),
+                conditional(ObservableProperty.QUALIFIER, IS_PRESENT, sequence(child(ObservableProperty.QUALIFIER), token(GeneratedJavaParserConstants.DOT))),
+                list(ObservableProperty.ANNOTATIONS, CsmElement.space(), CsmElement.none(), CsmElement.space()),
+                attribute(ObservableProperty.IDENTIFIER),
+                orphanCommentsEnding()
+        ));
+
+        concreteSyntaxModelByClass.put(NameExpr.class, sequence(
+                comment(),
+                child(ObservableProperty.NAME),
+                orphanCommentsEnding()
+        ));
+
+        concreteSyntaxModelByClass.put(NormalAnnotationExpr.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.AT),
+                child(ObservableProperty.NAME),
+                token(GeneratedJavaParserConstants.LPAREN),
+                list(ObservableProperty.PAIRS, sequence(comma(), space())),
+                token(GeneratedJavaParserConstants.RPAREN)
+        ));
+
+        concreteSyntaxModelByClass.put(NullLiteralExpr.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.NULL)
+        ));
+
+        concreteSyntaxModelByClass.put(ObjectCreationExpr.class, sequence(
+                comment(),
+                conditional(ObservableProperty.SCOPE, IS_PRESENT, sequence(child(ObservableProperty.SCOPE), token(GeneratedJavaParserConstants.DOT))),
+                token(GeneratedJavaParserConstants.NEW),
+                space(),
+                list(ObservableProperty.TYPE_ARGUMENTS, CsmElement.sequence(CsmElement.comma(), CsmElement.space()), CsmElement.token(LT), CsmElement.token(GT)),
+                conditional(ObservableProperty.TYPE_ARGUMENTS, IS_NOT_EMPTY, space()),
+                child(ObservableProperty.TYPE),
+                token(GeneratedJavaParserConstants.LPAREN),
+                list(ObservableProperty.ARGUMENTS, sequence(comma(), space()), none(), none()),
+                token(GeneratedJavaParserConstants.RPAREN),
+                conditional(ObservableProperty.ANONYMOUS_CLASS_BODY, IS_PRESENT,
+                        CsmElement.sequence(
+                                CsmElement.space(), CsmElement.token(LBRACE), CsmElement.newline(), CsmElement.indent(),
+                                CsmElement.list(ObservableProperty.ANONYMOUS_CLASS_BODY,
+                                        CsmElement.newline(),
+                                        CsmElement.newline(),
+                                        CsmElement.newline(),
+                                        CsmElement.newline()),
+                                CsmElement.unindent(),
+                                CsmElement.token(RBRACE)
+                        ))
+        ));
+
+        concreteSyntaxModelByClass.put(SimpleName.class, attribute(ObservableProperty.IDENTIFIER));
+
+        concreteSyntaxModelByClass.put(SingleMemberAnnotationExpr.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.AT),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.token(GeneratedJavaParserConstants.LPAREN),
+                CsmElement.child(ObservableProperty.MEMBER_VALUE),
+                CsmElement.token(GeneratedJavaParserConstants.RPAREN)));
+
+        concreteSyntaxModelByClass.put(StringLiteralExpr.class, sequence(
+                comment(),
+                stringToken(ObservableProperty.VALUE)
+        ));
+
+        concreteSyntaxModelByClass.put(SuperExpr.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.conditional(ObservableProperty.CLASS_EXPR, IS_PRESENT, CsmElement.sequence(CsmElement.child(ObservableProperty.CLASS_EXPR), CsmElement.token(GeneratedJavaParserConstants.DOT))),
+                CsmElement.token(GeneratedJavaParserConstants.SUPER)
+        ));
+
+        concreteSyntaxModelByClass.put(ThisExpr.class, sequence(
+                comment(),
+                conditional(ObservableProperty.CLASS_EXPR, IS_PRESENT, sequence(child(CLASS_EXPR), token(GeneratedJavaParserConstants.DOT))),
+                token(GeneratedJavaParserConstants.THIS)
+        ));
+
+        concreteSyntaxModelByClass.put(TypeExpr.class, sequence(
+                comment(),
+                child(ObservableProperty.TYPE)
+        ));
+
+        concreteSyntaxModelByClass.put(UnaryExpr.class, sequence(
+                conditional(ObservableProperty.PREFIX, FLAG, attribute(ObservableProperty.OPERATOR)),
+                child(ObservableProperty.EXPRESSION),
+                conditional(ObservableProperty.POSTFIX, FLAG, attribute(ObservableProperty.OPERATOR))
+        ));
+
+        concreteSyntaxModelByClass.put(VariableDeclarationExpr.class, sequence(
+                comment(),
+                list(ObservableProperty.ANNOTATIONS, CsmElement.space(), CsmElement.none(), CsmElement.space()),
+                modifiers(),
+                child(ObservableProperty.MAXIMUM_COMMON_TYPE),
+                space(),
+                list(ObservableProperty.VARIABLES, sequence(comma(), space()))
+        ));
+
+        ///
+        /// Statements
+        ///
+
+        concreteSyntaxModelByClass.put(AssertStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.ASSERT),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.CHECK),
+                CsmElement.conditional(ObservableProperty.MESSAGE, IS_PRESENT, CsmElement.sequence(
+                        CsmElement.space(),
+                        CsmElement.token(GeneratedJavaParserConstants.COLON),
+                        CsmElement.space(),
+                        CsmElement.child(ObservableProperty.MESSAGE)
+                )),
+                CsmElement.semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(BlockStmt.class, sequence(
+                orphanCommentsBeforeThis(),
+                comment(),
+                token(GeneratedJavaParserConstants.LBRACE),
+                newline(),
+                list(ObservableProperty.STATEMENTS, newline(), indent(), sequence(newline(), unindent())),
+                orphanCommentsEnding(),
+                token(RBRACE)
+        ));
+
+        concreteSyntaxModelByClass.put(BreakStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.BREAK),
+                CsmElement.conditional(ObservableProperty.LABEL, IS_PRESENT, CsmElement.sequence(CsmElement.space(), CsmElement.child(ObservableProperty.LABEL))),
+                CsmElement.semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(CatchClause.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.CATCH),
+                CsmElement.space(),
+                CsmElement.token(LPAREN),
+                CsmElement.child(ObservableProperty.PARAMETER),
+                CsmElement.token(RPAREN),
+                CsmElement.space(),
+                CsmElement.child(BODY)
+        ));
+
+        concreteSyntaxModelByClass.put(ContinueStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.CONTINUE),
+                CsmElement.conditional(ObservableProperty.LABEL, IS_PRESENT, CsmElement.sequence(CsmElement.space(), CsmElement.child(ObservableProperty.LABEL))),
+                CsmElement.semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(DoStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.DO),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.BODY),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.WHILE),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.LPAREN),
+                child(ObservableProperty.CONDITION),
+                CsmElement.token(GeneratedJavaParserConstants.RPAREN),
+                CsmElement.semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(EmptyStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.SEMICOLON)
+        ));
+
+        concreteSyntaxModelByClass.put(UnparsableStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.SEMICOLON)
+        ));
+
+        concreteSyntaxModelByClass.put(ExplicitConstructorInvocationStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.conditional(ObservableProperty.THIS, FLAG,
+                        CsmElement.sequence(typeArguments(), CsmElement.token(GeneratedJavaParserConstants.THIS)),
+                        CsmElement.sequence(
+                                CsmElement.conditional(ObservableProperty.EXPRESSION, IS_PRESENT, CsmElement.sequence(CsmElement.child(ObservableProperty.EXPRESSION), CsmElement.token(GeneratedJavaParserConstants.DOT))),
+                                typeArguments(),
+                                CsmElement.token(GeneratedJavaParserConstants.SUPER)
+                        )),
+                CsmElement.token(GeneratedJavaParserConstants.LPAREN),
+                CsmElement.list(ObservableProperty.ARGUMENTS, CsmElement.sequence(CsmElement.comma(), CsmElement.space())),
+                CsmElement.token(GeneratedJavaParserConstants.RPAREN),
+                CsmElement.semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(ExpressionStmt.class, sequence(
+                orphanCommentsBeforeThis(),
+                comment(),
+                child(ObservableProperty.EXPRESSION),
+                semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(ForeachStmt.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.FOR),
+                space(),
+                token(GeneratedJavaParserConstants.LPAREN),
+                child(ObservableProperty.VARIABLE),
+                space(),
+                token(GeneratedJavaParserConstants.COLON),
+                space(),
+                child(ObservableProperty.ITERABLE),
+                token(GeneratedJavaParserConstants.RPAREN),
+                space(),
+                child(ObservableProperty.BODY)
+        ));
+
+        concreteSyntaxModelByClass.put(ForStmt.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.FOR),
+                space(),
+                token(GeneratedJavaParserConstants.LPAREN),
+                list(ObservableProperty.INITIALIZATION, sequence(comma(), space())),
+                semicolon(),
+                space(),
+                child(ObservableProperty.COMPARE),
+                semicolon(),
+                space(),
+                list(ObservableProperty.UPDATE, sequence(comma(), space())),
+                token(GeneratedJavaParserConstants.RPAREN),
+                space(),
+                child(ObservableProperty.BODY)
+        ));
+
+        concreteSyntaxModelByClass.put(IfStmt.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.IF),
+                space(),
+                token(GeneratedJavaParserConstants.LPAREN),
+                child(ObservableProperty.CONDITION),
+                token(GeneratedJavaParserConstants.RPAREN),
+                conditional(ObservableProperty.THEN_BLOCK, CsmConditional.Condition.FLAG,
+                        sequence(space(), child(ObservableProperty.THEN_STMT),
+                                conditional(ObservableProperty.ELSE_STMT, IS_PRESENT, space())),
+                        sequence(newline(), CsmElement.indent(), child(ObservableProperty.THEN_STMT),
+                                conditional(ObservableProperty.ELSE_STMT, IS_PRESENT, newline()),
+                                unindent())),
+                conditional(ObservableProperty.ELSE_STMT, IS_PRESENT,
+                        sequence(token(GeneratedJavaParserConstants.ELSE),
+                                conditional(Arrays.asList(ObservableProperty.ELSE_BLOCK, ObservableProperty.CASCADING_IF_STMT), CsmConditional.Condition.FLAG,
+                                        sequence(space(), child(ObservableProperty.ELSE_STMT)),
+                                        sequence(newline(), CsmElement.indent(), child(ObservableProperty.ELSE_STMT), unindent()))))
+        ));
+
+        concreteSyntaxModelByClass.put(LabeledStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.child(ObservableProperty.LABEL),
+                CsmElement.token(GeneratedJavaParserConstants.COLON),
+                CsmElement.space(),
+                child(ObservableProperty.STATEMENT)
+        ));
+
+        concreteSyntaxModelByClass.put(LocalClassDeclarationStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.child(ObservableProperty.CLASS_DECLARATION)
+        ));
+
+        concreteSyntaxModelByClass.put(ReturnStmt.class, sequence(comment(), token(GeneratedJavaParserConstants.RETURN),
+                conditional(ObservableProperty.EXPRESSION, IS_PRESENT, sequence(space(), child(ObservableProperty.EXPRESSION))),
+                semicolon()));
+
+        concreteSyntaxModelByClass.put(SwitchEntryStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.conditional(ObservableProperty.LABEL, IS_PRESENT,
+                        CsmElement.sequence(CsmElement.token(GeneratedJavaParserConstants.CASE), CsmElement.space(), CsmElement.child(ObservableProperty.LABEL), CsmElement.token(GeneratedJavaParserConstants.COLON)),
+                        CsmElement.sequence(CsmElement.token(GeneratedJavaParserConstants._DEFAULT), CsmElement.token(GeneratedJavaParserConstants.COLON))),
+                CsmElement.newline(),
+                CsmElement.indent(),
+                CsmElement.list(ObservableProperty.STATEMENTS, CsmElement.newline(), CsmElement.none(), CsmElement.newline()),
+                CsmElement.unindent()
+        ));
+
+        concreteSyntaxModelByClass.put(SwitchStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.SWITCH),
+                CsmElement.token(GeneratedJavaParserConstants.LPAREN),
+                CsmElement.child(ObservableProperty.SELECTOR),
+                CsmElement.token(GeneratedJavaParserConstants.RPAREN),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.LBRACE),
+                CsmElement.newline(),
+                CsmElement.list(ObservableProperty.ENTRIES, CsmElement.none(), CsmElement.indent(), CsmElement.unindent()),
+                CsmElement.token(GeneratedJavaParserConstants.RBRACE)
+        ));
+
+        concreteSyntaxModelByClass.put(SynchronizedStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.SYNCHRONIZED),
+                CsmElement.space(),
+                CsmElement.token(LPAREN),
+                CsmElement.child(EXPRESSION),
+                CsmElement.token(RPAREN),
+                CsmElement.space(),
+                CsmElement.child(BODY)
+        ));
+
+        concreteSyntaxModelByClass.put(ThrowStmt.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.THROW),
+                space(),
+                child(ObservableProperty.EXPRESSION),
+                semicolon()
+        ));
+
+        concreteSyntaxModelByClass.put(TryStmt.class, CsmElement.sequence(
+                CsmElement.comment(),
+                CsmElement.token(GeneratedJavaParserConstants.TRY),
+                CsmElement.space(),
+                CsmElement.conditional(ObservableProperty.RESOURCES, CsmConditional.Condition.IS_NOT_EMPTY, CsmElement.sequence(
+                        CsmElement.token(LPAREN),
+                        list(ObservableProperty.RESOURCES, CsmElement.sequence(CsmElement.semicolon(), CsmElement.newline()), CsmElement.indent(), CsmElement.unindent()),
+                        CsmElement.token(RPAREN),
+                        CsmElement.space())),
+                CsmElement.child(ObservableProperty.TRY_BLOCK),
+                CsmElement.list(ObservableProperty.CATCH_CLAUSES),
+                CsmElement.conditional(ObservableProperty.FINALLY_BLOCK, IS_PRESENT, CsmElement.sequence(CsmElement.space(), CsmElement.token(GeneratedJavaParserConstants.FINALLY), CsmElement.space(), CsmElement.child(ObservableProperty.FINALLY_BLOCK)))
+        ));
+
+        concreteSyntaxModelByClass.put(WhileStmt.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.WHILE),
+                space(),
+                token(GeneratedJavaParserConstants.LPAREN),
+                child(ObservableProperty.CONDITION),
+                token(GeneratedJavaParserConstants.RPAREN),
+                space(),
+                child(ObservableProperty.BODY)
+        ));
+
+        ///
+        /// Types
+        ///
+
+        concreteSyntaxModelByClass.put(ArrayType.class, sequence(
+                child(ObservableProperty.COMPONENT_TYPE),
+                list(ObservableProperty.ANNOTATIONS),
+                string(GeneratedJavaParserConstants.LBRACKET),
+                string(GeneratedJavaParserConstants.RBRACKET)));
+
+        concreteSyntaxModelByClass.put(ClassOrInterfaceType.class, sequence(comment(),
+                conditional(SCOPE, IS_PRESENT, sequence(child(SCOPE), string(GeneratedJavaParserConstants.DOT))),
+                list(ANNOTATIONS, space()),
+                child(NAME),
+                conditional(ObservableProperty.USING_DIAMOND_OPERATOR, FLAG,
+                        sequence(string(GeneratedJavaParserConstants.LT), string(GeneratedJavaParserConstants.GT)),
+                        list(TYPE_ARGUMENTS, sequence(comma(), space()), string(GeneratedJavaParserConstants.LT), string(GeneratedJavaParserConstants.GT)))));
+
+        concreteSyntaxModelByClass.put(IntersectionType.class, CsmElement.sequence(
+                CsmElement.comment(),
+                annotations(),
+                CsmElement.list(ObservableProperty.ELEMENTS, CsmElement.sequence(CsmElement.space(), CsmElement.token(GeneratedJavaParserConstants.BIT_AND), CsmElement.space()))));
+
+        concreteSyntaxModelByClass.put(PrimitiveType.class, sequence(
+                comment(),
+                list(ObservableProperty.ANNOTATIONS),
+                attribute(ObservableProperty.TYPE)));
+
+        concreteSyntaxModelByClass.put(TypeParameter.class, sequence(
+                comment(),
+                annotations(),
+                child(ObservableProperty.NAME),
+                list(ObservableProperty.TYPE_BOUND,
+                        sequence(
+                                space(),
+                                token(GeneratedJavaParserConstants.BIT_AND),
+                                space()),
+                        sequence(
+                                space(),
+                                token(GeneratedJavaParserConstants.EXTENDS),
+                                space()),
+                        none())
+        ));
+
+        concreteSyntaxModelByClass.put(UnionType.class, CsmElement.sequence(
+                CsmElement.comment(),
+                annotations(),
+                CsmElement.list(ObservableProperty.ELEMENTS, CsmElement.sequence(CsmElement.space(), CsmElement.token(GeneratedJavaParserConstants.BIT_OR), CsmElement.space()))
+        ));
+
+        concreteSyntaxModelByClass.put(UnknownType.class, none());
+
+        concreteSyntaxModelByClass.put(VoidType.class, sequence(comment(), annotations(), token(GeneratedJavaParserConstants.VOID)));
+
+        concreteSyntaxModelByClass.put(VarType.class, sequence(comment(), annotations(), string(GeneratedJavaParserConstants.IDENTIFIER, "var")));
+
+        concreteSyntaxModelByClass.put(WildcardType.class, sequence(comment(), annotations(), token(GeneratedJavaParserConstants.HOOK),
+                CsmElement.conditional(ObservableProperty.EXTENDED_TYPE, IS_PRESENT, CsmElement.sequence(space(), token(GeneratedJavaParserConstants.EXTENDS), space(), CsmElement.child(EXTENDED_TYPE))),
+                CsmElement.conditional(ObservableProperty.SUPER_TYPE, IS_PRESENT, CsmElement.sequence(space(), token(GeneratedJavaParserConstants.SUPER), space(), CsmElement.child(SUPER_TYPE)))));
+
+        ///
+        /// Top Level
+        ///
+
+        concreteSyntaxModelByClass.put(ArrayCreationLevel.class, sequence(
+                annotations(),
+                token(GeneratedJavaParserConstants.LBRACKET),
+                child(ObservableProperty.DIMENSION),
+                token(GeneratedJavaParserConstants.RBRACKET)
+        ));
+
+        concreteSyntaxModelByClass.put(CompilationUnit.class, sequence(
+                comment(),
+                child(ObservableProperty.PACKAGE_DECLARATION),
+                list(ObservableProperty.IMPORTS, none(), none(), newline()),
+                list(TYPES, newline(), CsmElement.newline(), CsmElement.none(), CsmElement.newline()),
+                child(ObservableProperty.MODULE),
+                orphanCommentsEnding()));
+
+        concreteSyntaxModelByClass.put(ImportDeclaration.class, sequence(
+                comment(),
+                token(GeneratedJavaParserConstants.IMPORT),
+                space(),
+                conditional(ObservableProperty.STATIC, FLAG, sequence(token(GeneratedJavaParserConstants.STATIC), space())),
+                child(ObservableProperty.NAME),
+                conditional(ASTERISK, FLAG, sequence(token(GeneratedJavaParserConstants.DOT), token(GeneratedJavaParserConstants.STAR))),
+                semicolon(),
+                newline(),
+                orphanCommentsEnding()
+        ));
+
+        concreteSyntaxModelByClass.put(PackageDeclaration.class, sequence(
+                comment(),
+                list(ObservableProperty.ANNOTATIONS),
+                token(GeneratedJavaParserConstants.PACKAGE),
+                space(),
+                child(ObservableProperty.NAME),
+                semicolon(),
+                newline(),
+                newline(),
+                orphanCommentsEnding()));
+
+        ///
+        /// Module info
+        ///
+
+        concreteSyntaxModelByClass.put(ModuleDeclaration.class, CsmElement.sequence(
+                annotations(),
+                CsmElement.conditional(ObservableProperty.OPEN, FLAG, CsmElement.sequence(CsmElement.token(GeneratedJavaParserConstants.OPEN), CsmElement.space())),
+                CsmElement.token(GeneratedJavaParserConstants.MODULE),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.space(),
+                CsmElement.token(GeneratedJavaParserConstants.LBRACE),
+                CsmElement.newline(),
+                CsmElement.indent(),
+                CsmElement.list(ObservableProperty.MODULE_STMTS),
+                CsmElement.unindent(),
+                CsmElement.token(GeneratedJavaParserConstants.RBRACE),
+                CsmElement.newline()
+        ));
+
+        concreteSyntaxModelByClass.put(ModuleExportsStmt.class, CsmElement.sequence(
+                CsmElement.token(GeneratedJavaParserConstants.EXPORTS),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.list(ObservableProperty.MODULE_NAMES,
+                        CsmElement.sequence(CsmElement.comma(), CsmElement.space()),
+                        CsmElement.sequence(CsmElement.space(), CsmElement.token(GeneratedJavaParserConstants.TO), CsmElement.space()),
+                        CsmElement.none()),
+                CsmElement.semicolon(),
+                CsmElement.newline()
+        ));
+
+        concreteSyntaxModelByClass.put(ModuleOpensStmt.class, CsmElement.sequence(
+                CsmElement.token(GeneratedJavaParserConstants.OPENS),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.list(ObservableProperty.MODULE_NAMES,
+                        CsmElement.sequence(CsmElement.comma(), CsmElement.space()),
+                        CsmElement.sequence(CsmElement.space(), CsmElement.token(GeneratedJavaParserConstants.TO), CsmElement.space()),
+                        CsmElement.none()),
+                CsmElement.semicolon(),
+                CsmElement.newline()
+        ));
+
+        concreteSyntaxModelByClass.put(ModuleProvidesStmt.class, CsmElement.sequence(
+                CsmElement.token(GeneratedJavaParserConstants.PROVIDES),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.TYPE),
+                CsmElement.list(ObservableProperty.WITH_TYPES,
+                        CsmElement.sequence(CsmElement.comma(), CsmElement.space()),
+                        CsmElement.sequence(CsmElement.space(), CsmElement.token(GeneratedJavaParserConstants.WITH), CsmElement.space()),
+                        CsmElement.none()),
+                CsmElement.semicolon(),
+                CsmElement.newline()
+        ));
+
+        concreteSyntaxModelByClass.put(ModuleRequiresStmt.class, CsmElement.sequence(
+                CsmElement.token(GeneratedJavaParserConstants.REQUIRES),
+                CsmElement.space(),
+                modifiers(),
+                CsmElement.child(ObservableProperty.NAME),
+                CsmElement.semicolon(),
+                CsmElement.newline()
+        ));
+
+        concreteSyntaxModelByClass.put(ModuleUsesStmt.class, CsmElement.sequence(
+                CsmElement.token(GeneratedJavaParserConstants.USES),
+                CsmElement.space(),
+                CsmElement.child(ObservableProperty.TYPE),
+                CsmElement.semicolon(),
+                CsmElement.newline()
+        ));
+
+        List<String> unsupportedNodeClassNames = JavaParserMetaModel.getNodeMetaModels().stream()
+                .filter(c -> !c.isAbstract() && !Comment.class.isAssignableFrom(c.getType()) && !concreteSyntaxModelByClass.containsKey(c.getType()))
+                .map(nm -> nm.getType().getSimpleName())
+                .collect(Collectors.toList());
+        if (unsupportedNodeClassNames.isEmpty()) {
+            initializationError = Optional.empty();
+        } else {
+            initializationError = Optional.of("The CSM should include support for these classes: " + String.join(", ", unsupportedNodeClassNames));
+        }
+    }
+
+    private ConcreteSyntaxModel() {
+
+    }
+
+    public static void genericPrettyPrint(Node node, SourcePrinter printer) {
+        forClass(node.getClass()).prettyPrint(node, printer);
+    }
+
+    public static String genericPrettyPrint(Node node) {
+        SourcePrinter sourcePrinter = new SourcePrinter("    ", EOL);
+        forClass(node.getClass()).prettyPrint(node, sourcePrinter);
+        return sourcePrinter.getSource();
+    }
+
+    public static CsmElement forClass(Class<? extends Node> nodeClazz) {
+        initializationError.ifPresent(s -> {
+            throw new IllegalStateException(s);
+        });
+        if (!concreteSyntaxModelByClass.containsKey(nodeClazz)) {
+            throw new UnsupportedOperationException(nodeClazz.getSimpleName());
+        }
+        return concreteSyntaxModelByClass.get(nodeClazz);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/DotPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/DotPrinter.java
new file mode 100644
index 0000000..2e190c9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/DotPrinter.java
@@ -0,0 +1,106 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.printer;

+

+import static com.github.javaparser.utils.Utils.assertNotNull;

+import static java.util.stream.Collectors.toList;

+

+import java.util.List;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.NodeList;

+import com.github.javaparser.metamodel.NodeMetaModel;

+import com.github.javaparser.metamodel.PropertyMetaModel;

+

+/**

+ * Outputs a Graphviz diagram of the AST.

+ */

+public class DotPrinter {

+

+    private int nodeCount;

+    private final boolean outputNodeType;

+

+    public DotPrinter(boolean outputNodeType) {

+        this.outputNodeType = outputNodeType;

+    }

+

+    public String output(Node node) {

+        nodeCount = 0;

+        StringBuilder output = new StringBuilder();

+        output.append("digraph {");

+        output(node, null, "root", output);

+        output.append(System.lineSeparator() + "}");

+        return output.toString();

+    }

+

+    public void output(Node node, String parentNodeName, String name, StringBuilder builder) {

+        assertNotNull(node);

+        NodeMetaModel metaModel = node.getMetaModel();

+        List<PropertyMetaModel> allPropertyMetaModels = metaModel.getAllPropertyMetaModels();

+        List<PropertyMetaModel> attributes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isAttribute)

+                .filter(PropertyMetaModel::isSingular).collect(toList());

+        List<PropertyMetaModel> subNodes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNode)

+                .filter(PropertyMetaModel::isSingular).collect(toList());

+        List<PropertyMetaModel> subLists = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNodeList)

+                .collect(toList());

+

+        String ndName = nextNodeName();

+        if (outputNodeType)

+            builder.append(System.lineSeparator() + ndName + " [label=\"" + name + " (" + metaModel.getTypeName()

+                    + ")\"];");

+        else

+            builder.append(System.lineSeparator() + ndName + " [label=\"" + name + "\"];");

+

+        if (parentNodeName != null)

+            builder.append(System.lineSeparator() + parentNodeName + " -> " + ndName + ";");

+

+        for (PropertyMetaModel a : attributes) {

+            String attrName = nextNodeName();

+            builder.append(System.lineSeparator() + attrName + " [label=\"" + a.getName() + "='"

+                    + a.getValue(node).toString() + "'\"];");

+            builder.append(System.lineSeparator() + ndName + " -> " + attrName + ";");

+

+        }

+

+        for (PropertyMetaModel sn : subNodes) {

+            Node nd = (Node) sn.getValue(node);

+            if (nd != null)

+                output(nd, ndName, sn.getName(), builder);

+        }

+

+        for (PropertyMetaModel sl : subLists) {

+            NodeList<? extends Node> nl = (NodeList<? extends Node>) sl.getValue(node);

+            if (nl != null && nl.isNonEmpty()) {

+                String ndLstName = nextNodeName();

+                builder.append(System.lineSeparator() + ndLstName + " [label=\"" + sl.getName() + "\"];");

+                builder.append(System.lineSeparator() + ndName + " -> " + ndLstName + ";");

+                String slName = sl.getName().substring(0, sl.getName().length() - 1);

+                for (Node nd : nl)

+                    output(nd, ndLstName, slName, builder);

+            }

+        }

+    }

+

+    private String nextNodeName() {

+        return "n" + (nodeCount++);

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/JsonPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/JsonPrinter.java
new file mode 100644
index 0000000..2370512
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/JsonPrinter.java
@@ -0,0 +1,74 @@
+package com.github.javaparser.printer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.metamodel.NodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.toList;
+
+/**
+ * Outputs a JSON file containing the AST meant for inspecting it.
+ */
+public class JsonPrinter {
+    private final boolean outputNodeType;
+
+    public JsonPrinter(boolean outputNodeType) {
+        this.outputNodeType = outputNodeType;
+    }
+
+    public String output(Node node) {
+        return output(node, null, 0);
+    }
+
+    public String output(Node node, String name, int level) {
+        assertNotNull(node);
+        NodeMetaModel metaModel = node.getMetaModel();
+        List<PropertyMetaModel> allPropertyMetaModels = metaModel.getAllPropertyMetaModels();
+        List<PropertyMetaModel> attributes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isAttribute).filter(PropertyMetaModel::isSingular).collect(toList());
+        List<PropertyMetaModel> subNodes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNode).filter(PropertyMetaModel::isSingular).collect(toList());
+        List<PropertyMetaModel> subLists = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNodeList).collect(toList());
+
+        final List<String> content = new ArrayList<>();
+
+        if (outputNodeType) {
+            content.add(q("type") + ":" + q(metaModel.getTypeName()));
+        }
+
+        for (PropertyMetaModel attributeMetaModel : attributes) {
+            content.add(q(attributeMetaModel.getName()) + ":" + q(attributeMetaModel.getValue(node).toString()));
+        }
+
+        for (PropertyMetaModel subNodeMetaModel : subNodes) {
+            Node value = (Node) subNodeMetaModel.getValue(node);
+            if (value != null) {
+                content.add(output(value, subNodeMetaModel.getName(), level + 1));
+            }
+        }
+
+        for (PropertyMetaModel subListMetaModel : subLists) {
+            NodeList<? extends Node> subList = (NodeList<? extends Node>) subListMetaModel.getValue(node);
+            if (subList != null && !subList.isEmpty()) {
+                final List<String> listContent = new ArrayList<>();
+                for (Node subListNode : subList) {
+                    listContent.add(output(subListNode, null, level + 1));
+                }
+                content.add(listContent.stream().collect(Collectors.joining(",", q(subListMetaModel.getName()) + ":[", "]")));
+            }
+        }
+
+        if (name == null) {
+            return content.stream().collect(Collectors.joining(",", "{", "}"));
+        }
+        return content.stream().collect(Collectors.joining(",", q(name) + ":{", "}"));
+    }
+
+    private static String q(String value) {
+        return "\"" + value.replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r") + "\"";
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrintVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrintVisitor.java
new file mode 100644
index 0000000..8a1d6b5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrintVisitor.java
@@ -0,0 +1,1609 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.Position;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.visitor.Visitable;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.ast.Node.Parsedness.UNPARSABLE;
+import static com.github.javaparser.utils.PositionUtils.sortByBeginPosition;
+import static com.github.javaparser.utils.Utils.isNullOrEmpty;
+import static com.github.javaparser.utils.Utils.normalizeEolInTextBlock;
+import static com.github.javaparser.utils.Utils.trimTrailingSpaces;
+
+/**
+ * Outputs the AST as formatted Java source code.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public class PrettyPrintVisitor implements VoidVisitor<Void> {
+    protected final PrettyPrinterConfiguration configuration;
+    protected final SourcePrinter printer;
+    private Deque<Position> methodChainPositions = new LinkedList<>();
+
+    public PrettyPrintVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) {
+        configuration = prettyPrinterConfiguration;
+        printer = new SourcePrinter(configuration.getIndent(), configuration.getEndOfLineCharacter());
+        pushMethodChainPosition(printer.getCursor()); // initialize a default position for methodChainPositions, it is expected by method #resetMethodChainPosition()
+    }
+
+    public String getSource() {
+        return printer.getSource();
+    }
+
+    public void resetMethodChainPosition(Position position) {
+        this.methodChainPositions.pop();
+        this.methodChainPositions.push(position);
+    }
+
+    public void pushMethodChainPosition(Position position) {
+        this.methodChainPositions.push(position);
+    }
+
+    public Position peekMethodChainPosition() {
+        return this.methodChainPositions.peek();
+    }
+
+    public Position popMethodChainPosition() {
+        return this.methodChainPositions.pop();
+    }
+
+    private void printModifiers(final EnumSet<Modifier> modifiers) {
+        if (modifiers.size() > 0) {
+            printer.print(modifiers.stream().map(Modifier::asString).collect(Collectors.joining(" ")) + " ");
+        }
+    }
+
+    private void printMembers(final NodeList<BodyDeclaration<?>> members, final Void arg) {
+        for (final BodyDeclaration<?> member : members) {
+            printer.println();
+            member.accept(this, arg);
+            printer.println();
+        }
+    }
+
+    private void printMemberAnnotations(final NodeList<AnnotationExpr> annotations, final Void arg) {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        for (final AnnotationExpr a : annotations) {
+            a.accept(this, arg);
+            printer.println();
+        }
+    }
+
+    private void printAnnotations(final NodeList<AnnotationExpr> annotations, boolean prefixWithASpace,
+                                  final Void arg) {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        if (prefixWithASpace) {
+            printer.print(" ");
+        }
+        for (AnnotationExpr annotation : annotations) {
+            annotation.accept(this, arg);
+            printer.print(" ");
+        }
+    }
+
+    private void printTypeArgs(final NodeWithTypeArguments<?> nodeWithTypeArguments, final Void arg) {
+        NodeList<Type> typeArguments = nodeWithTypeArguments.getTypeArguments().orElse(null);
+        if (!isNullOrEmpty(typeArguments)) {
+            printer.print("<");
+            for (final Iterator<Type> i = typeArguments.iterator(); i.hasNext(); ) {
+                final Type t = i.next();
+                t.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(">");
+        }
+    }
+
+    private void printTypeParameters(final NodeList<TypeParameter> args, final Void arg) {
+        if (!isNullOrEmpty(args)) {
+            printer.print("<");
+            for (final Iterator<TypeParameter> i = args.iterator(); i.hasNext(); ) {
+                final TypeParameter t = i.next();
+                t.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(">");
+        }
+    }
+
+    private void printArguments(final NodeList<Expression> args, final Void arg) {
+        printer.print("(");
+        Position cursorRef = printer.getCursor();
+        if (!isNullOrEmpty(args)) {
+            for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(",");
+                    if (configuration.isColumnAlignParameters()) {
+                        printer.wrapToColumn(cursorRef.column);
+                    } else {
+                        printer.print(" ");
+                    }
+                }
+            }
+        }
+        printer.print(")");
+    }
+
+    private void printPrePostFixOptionalList(final NodeList<? extends Visitable> args, final Void arg, String prefix, String separator, String postfix) {
+        if (!args.isEmpty()) {
+            printer.print(prefix);
+            for (final Iterator<? extends Visitable> i = args.iterator(); i.hasNext(); ) {
+                final Visitable v = i.next();
+                v.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(separator);
+                }
+            }
+            printer.print(postfix);
+        }
+    }
+
+    private void printPrePostFixRequiredList(final NodeList<? extends Visitable> args, final Void arg, String prefix, String separator, String postfix) {
+        printer.print(prefix);
+        if (!args.isEmpty()) {
+            for (final Iterator<? extends Visitable> i = args.iterator(); i.hasNext(); ) {
+                final Visitable v = i.next();
+                v.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(separator);
+                }
+            }
+        }
+        printer.print(postfix);
+    }
+
+    private void printComment(final Optional<Comment> comment, final Void arg) {
+        comment.ifPresent(c -> c.accept(this, arg));
+    }
+
+    @Override
+    public void visit(final CompilationUnit n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getParsed() == UNPARSABLE) {
+            printer.println("???");
+            return;
+        }
+
+        if (n.getPackageDeclaration().isPresent()) {
+            n.getPackageDeclaration().get().accept(this, arg);
+        }
+
+        n.getImports().accept(this, arg);
+        if (!n.getImports().isEmpty()) {
+            printer.println();
+        }
+
+        for (final Iterator<TypeDeclaration<?>> i = n.getTypes().iterator(); i.hasNext(); ) {
+            i.next().accept(this, arg);
+            printer.println();
+            if (i.hasNext()) {
+                printer.println();
+            }
+        }
+
+        n.getModule().ifPresent(m -> m.accept(this, arg));
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final PackageDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("package ");
+        n.getName().accept(this, arg);
+        printer.println(";");
+        printer.println();
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final NameExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final Name n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getQualifier().isPresent()) {
+            n.getQualifier().get().accept(this, arg);
+            printer.print(".");
+        }
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print(n.getIdentifier());
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(SimpleName n, Void arg) {
+        printer.print(n.getIdentifier());
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        if (n.isInterface()) {
+            printer.print("interface ");
+        } else {
+            printer.print("class ");
+        }
+
+        n.getName().accept(this, arg);
+
+        printTypeParameters(n.getTypeParameters(), arg);
+
+        if (!n.getExtendedTypes().isEmpty()) {
+            printer.print(" extends ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getExtendedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+
+        if (!n.getImplementedTypes().isEmpty()) {
+            printer.print(" implements ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+
+        printer.println(" {");
+        printer.indent();
+        if (!isNullOrEmpty(n.getMembers())) {
+            printMembers(n.getMembers(), arg);
+        }
+
+        printOrphanCommentsEnding(n);
+
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final JavadocComment n, final Void arg) {
+        if (configuration.isPrintComments() && configuration.isPrintJavadoc()) {
+            printer.println("/**");
+            final String commentContent = normalizeEolInTextBlock(n.getContent(), configuration.getEndOfLineCharacter());
+            String[] lines = commentContent.split("\\R");
+            boolean skippingLeadingEmptyLines = true;
+            boolean prependEmptyLine = false;
+            for (String line : lines) {
+                final String trimmedLine = line.trim();
+                if (trimmedLine.startsWith("*")) {
+                    line = trimmedLine.substring(1);
+                }
+                line = trimTrailingSpaces(line);
+                if (line.isEmpty()) {
+                    if (!skippingLeadingEmptyLines) {
+                        prependEmptyLine = true;
+                    }
+                } else {
+                    skippingLeadingEmptyLines = false;
+                    if (prependEmptyLine) {
+                        printer.println(" *");
+                        prependEmptyLine = false;
+                    }
+                    printer.println(" *" + line);
+                }
+            }
+            printer.println(" */");
+        }
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceType n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+        for (AnnotationExpr ae : n.getAnnotations()) {
+            ae.accept(this, arg);
+            printer.print(" ");
+        }
+
+        n.getName().accept(this, arg);
+
+        if (n.isUsingDiamondOperator()) {
+            printer.print("<>");
+        } else {
+            printTypeArgs(n, arg);
+        }
+    }
+
+    @Override
+    public void visit(final TypeParameter n, final Void arg) {
+        printComment(n.getComment(), arg);
+        for (AnnotationExpr ann : n.getAnnotations()) {
+            ann.accept(this, arg);
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+        if (!isNullOrEmpty(n.getTypeBound())) {
+            printer.print(" extends ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getTypeBound().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(" & ");
+                }
+            }
+        }
+    }
+
+    @Override
+    public void visit(final PrimitiveType n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), true, arg);
+        printer.print(n.getType().asString());
+    }
+
+    @Override
+    public void visit(final ArrayType n, final Void arg) {
+        final List<ArrayType> arrayTypeBuffer = new LinkedList<>();
+        Type type = n;
+        while (type instanceof ArrayType) {
+            final ArrayType arrayType = (ArrayType) type;
+            arrayTypeBuffer.add(arrayType);
+            type = arrayType.getComponentType();
+        }
+
+        type.accept(this, arg);
+        for (ArrayType arrayType : arrayTypeBuffer) {
+            printAnnotations(arrayType.getAnnotations(), true, arg);
+            printer.print("[]");
+        }
+    }
+
+    @Override
+    public void visit(final ArrayCreationLevel n, final Void arg) {
+        printAnnotations(n.getAnnotations(), true, arg);
+        printer.print("[");
+        if (n.getDimension().isPresent()) {
+            n.getDimension().get().accept(this, arg);
+        }
+        printer.print("]");
+    }
+
+    @Override
+    public void visit(final IntersectionType n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" & ");
+            }
+            element.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final UnionType n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), true, arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" | ");
+            }
+            element.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final WildcardType n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("?");
+        if (n.getExtendedType().isPresent()) {
+            printer.print(" extends ");
+            n.getExtendedType().get().accept(this, arg);
+        }
+        if (n.getSuperType().isPresent()) {
+            printer.print(" super ");
+            n.getSuperType().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final UnknownType n, final Void arg) {
+        // Nothing to print
+    }
+
+    @Override
+    public void visit(final FieldDeclaration n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        if (!n.getVariables().isEmpty()) {
+            Optional<Type> maximumCommonType = n.getMaximumCommonType();
+            maximumCommonType.ifPresent(t -> t.accept(this, arg));
+            if (!maximumCommonType.isPresent()) {
+                printer.print("???");
+            }
+        }
+
+        printer.print(" ");
+        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+            final VariableDeclarator var = i.next();
+            var.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final VariableDeclarator n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+
+        n.getAncestorOfType(NodeWithVariables.class).ifPresent(ancestor -> {
+            ((NodeWithVariables<?>) ancestor).getMaximumCommonType().ifPresent(commonType -> {
+
+                final Type type = n.getType();
+
+                ArrayType arrayType = null;
+
+                for (int i = commonType.getArrayLevel(); i < type.getArrayLevel(); i++) {
+                    if (arrayType == null) {
+                        arrayType = (ArrayType) type;
+                    } else {
+                        arrayType = (ArrayType) arrayType.getComponentType();
+                    }
+                    printAnnotations(arrayType.getAnnotations(), true, arg);
+                    printer.print("[]");
+                }
+            });
+        });
+
+        if (n.getInitializer().isPresent()) {
+            printer.print(" = ");
+            n.getInitializer().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final ArrayInitializerExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("{");
+        if (!isNullOrEmpty(n.getValues())) {
+            printer.print(" ");
+            for (final Iterator<Expression> i = n.getValues().iterator(); i.hasNext(); ) {
+                final Expression expr = i.next();
+                expr.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(" ");
+        }
+        printOrphanCommentsEnding(n);
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final VoidType n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("void");
+    }
+
+    @Override
+    public void visit(final VarType n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("var");
+    }
+
+    @Override
+    public void visit(final ArrayAccessExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        printer.print("[");
+        n.getIndex().accept(this, arg);
+        printer.print("]");
+    }
+
+    @Override
+    public void visit(final ArrayCreationExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("new ");
+        n.getElementType().accept(this, arg);
+        for (ArrayCreationLevel level : n.getLevels()) {
+            level.accept(this, arg);
+        }
+        if (n.getInitializer().isPresent()) {
+            printer.print(" ");
+            n.getInitializer().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final AssignExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getTarget().accept(this, arg);
+        printer.print(" ");
+        printer.print(n.getOperator().asString());
+        printer.print(" ");
+        n.getValue().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final BinaryExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getLeft().accept(this, arg);
+        printer.print(" ");
+        printer.print(n.getOperator().asString());
+        printer.print(" ");
+        n.getRight().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final CastExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("(");
+        n.getType().accept(this, arg);
+        printer.print(") ");
+        n.getExpression().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ClassExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getType().accept(this, arg);
+        printer.print(".class");
+    }
+
+    @Override
+    public void visit(final ConditionalExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getCondition().accept(this, arg);
+        printer.print(" ? ");
+        n.getThenExpr().accept(this, arg);
+        printer.print(" : ");
+        n.getElseExpr().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final EnclosedExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("(");
+        n.getInner().accept(this, arg);
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final FieldAccessExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getScope().accept(this, arg);
+        printer.print(".");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final InstanceOfExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getExpression().accept(this, arg);
+        printer.print(" instanceof ");
+        n.getType().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final CharLiteralExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("'");
+        printer.print(n.getValue());
+        printer.print("'");
+    }
+
+    @Override
+    public void visit(final DoubleLiteralExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final IntegerLiteralExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final LongLiteralExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final StringLiteralExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("\"");
+        printer.print(n.getValue());
+        printer.print("\"");
+    }
+
+    @Override
+    public void visit(final BooleanLiteralExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print(String.valueOf(n.getValue()));
+    }
+
+    @Override
+    public void visit(final NullLiteralExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("null");
+    }
+
+    @Override
+    public void visit(final ThisExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getClassExpr().isPresent()) {
+            n.getClassExpr().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print("this");
+    }
+
+    @Override
+    public void visit(final SuperExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getClassExpr().isPresent()) {
+            n.getClassExpr().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print("super");
+    }
+
+    @Override
+    public void visit(final MethodCallExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            if (configuration.isColumnAlignFirstMethodChain()) {
+                if (!(n.getScope().get() instanceof MethodCallExpr) || (!((MethodCallExpr) n.getScope().get()).getScope().isPresent())) {
+                    resetMethodChainPosition(printer.getCursor());
+                } else {
+                    printer.wrapToColumn(peekMethodChainPosition().column);
+                }
+            }
+            printer.print(".");
+        }
+        printTypeArgs(n, arg);
+        n.getName().accept(this, arg);
+        pushMethodChainPosition(printer.getCursor());
+        printArguments(n.getArguments(), arg);
+        popMethodChainPosition();
+    }
+
+    @Override
+    public void visit(final ObjectCreationExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+
+        printer.print("new ");
+
+        printTypeArgs(n, arg);
+        if (!isNullOrEmpty(n.getTypeArguments().orElse(null))) {
+            printer.print(" ");
+        }
+
+        n.getType().accept(this, arg);
+
+        printArguments(n.getArguments(), arg);
+
+        if (n.getAnonymousClassBody().isPresent()) {
+            printer.println(" {");
+            printer.indent();
+            printMembers(n.getAnonymousClassBody().get(), arg);
+            printer.unindent();
+            printer.print("}");
+        }
+    }
+
+    @Override
+    public void visit(final UnaryExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getOperator().isPrefix()) {
+            printer.print(n.getOperator().asString());
+        }
+
+        n.getExpression().accept(this, arg);
+
+        if (n.getOperator().isPostfix()) {
+            printer.print(n.getOperator().asString());
+        }
+    }
+
+    @Override
+    public void visit(final ConstructorDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        printTypeParameters(n.getTypeParameters(), arg);
+        if (n.isGeneric()) {
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+
+        printer.print("(");
+        if (!n.getParameters().isEmpty()) {
+            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+                final Parameter p = i.next();
+                p.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+
+        if (!isNullOrEmpty(n.getThrownExceptions())) {
+            printer.print(" throws ");
+            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
+                final ReferenceType name = i.next();
+                name.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(" ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final MethodDeclaration n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        printTypeParameters(n.getTypeParameters(), arg);
+        if (!isNullOrEmpty(n.getTypeParameters())) {
+            printer.print(" ");
+        }
+
+        n.getType().accept(this, arg);
+        printer.print(" ");
+        n.getName().accept(this, arg);
+
+        printer.print("(");
+        n.getReceiverParameter().ifPresent(rp -> {
+            rp.accept(this, arg);
+            printer.print(", ");
+        });
+        if (!isNullOrEmpty(n.getParameters())) {
+            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+                final Parameter p = i.next();
+                p.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+
+        if (!isNullOrEmpty(n.getThrownExceptions())) {
+            printer.print(" throws ");
+            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
+                final ReferenceType name = i.next();
+                name.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        if (!n.getBody().isPresent()) {
+            printer.print(";");
+        } else {
+            printer.print(" ");
+            n.getBody().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final Parameter n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printModifiers(n.getModifiers());
+        n.getType().accept(this, arg);
+        if (n.isVarArgs()) {
+            printAnnotations(n.getVarArgsAnnotations(), false, arg);
+            printer.print("...");
+        }
+        if (!(n.getType() instanceof UnknownType)) {
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ReceiverParameter n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        n.getType().accept(this, arg);
+        printer.print(" ");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ExplicitConstructorInvocationStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.isThis()) {
+            printTypeArgs(n, arg);
+            printer.print("this");
+        } else {
+            if (n.getExpression().isPresent()) {
+                n.getExpression().get().accept(this, arg);
+                printer.print(".");
+            }
+            printTypeArgs(n, arg);
+            printer.print("super");
+        }
+        printArguments(n.getArguments(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final VariableDeclarationExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printModifiers(n.getModifiers());
+
+        if (!n.getVariables().isEmpty()) {
+            n.getMaximumCommonType().ifPresent(t -> t.accept(this, arg));
+        }
+        printer.print(" ");
+
+        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+            final VariableDeclarator v = i.next();
+            v.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+    }
+
+    @Override
+    public void visit(final LocalClassDeclarationStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getClassDeclaration().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final AssertStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("assert ");
+        n.getCheck().accept(this, arg);
+        if (n.getMessage().isPresent()) {
+            printer.print(" : ");
+            n.getMessage().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final BlockStmt n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printComment(n.getComment(), arg);
+        printer.println("{");
+        if (n.getStatements() != null) {
+            printer.indent();
+            for (final Statement s : n.getStatements()) {
+                s.accept(this, arg);
+                printer.println();
+            }
+            printer.unindent();
+        }
+        printOrphanCommentsEnding(n);
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final LabeledStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getLabel().accept(this, arg);
+        printer.print(": ");
+        n.getStatement().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final EmptyStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final ExpressionStmt n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printComment(n.getComment(), arg);
+        n.getExpression().accept(this, arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final SwitchStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("switch(");
+        n.getSelector().accept(this, arg);
+        printer.println(") {");
+        if (n.getEntries() != null) {
+            printer.indent();
+            for (final SwitchEntryStmt e : n.getEntries()) {
+                e.accept(this, arg);
+            }
+            printer.unindent();
+        }
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final SwitchEntryStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getLabel().isPresent()) {
+            printer.print("case ");
+            n.getLabel().get().accept(this, arg);
+            printer.print(":");
+        } else {
+            printer.print("default:");
+        }
+        printer.println();
+        printer.indent();
+        if (n.getStatements() != null) {
+            for (final Statement s : n.getStatements()) {
+                s.accept(this, arg);
+                printer.println();
+            }
+        }
+        printer.unindent();
+    }
+
+    @Override
+    public void visit(final BreakStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("break");
+        n.getLabel().ifPresent(l -> printer.print(" ").print(l.getIdentifier()));
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final ReturnStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("return");
+        if (n.getExpression().isPresent()) {
+            printer.print(" ");
+            n.getExpression().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final EnumDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        printer.print("enum ");
+        n.getName().accept(this, arg);
+
+        if (!n.getImplementedTypes().isEmpty()) {
+            printer.print(" implements ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+
+        printer.println(" {");
+        printer.indent();
+        if (n.getEntries().isNonEmpty()) {
+            final boolean alignVertically =
+                    // Either we hit the constant amount limit in the configurations, or...
+                    n.getEntries().size() > configuration.getMaxEnumConstantsToAlignHorizontally() ||
+                            // any of the constants has a comment.
+                            n.getEntries().stream().anyMatch(e -> e.getComment().isPresent());
+            printer.println();
+            for (final Iterator<EnumConstantDeclaration> i = n.getEntries().iterator(); i.hasNext(); ) {
+                final EnumConstantDeclaration e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    if (alignVertically) {
+                        printer.println(",");
+                    } else {
+                        printer.print(", ");
+                    }
+                }
+            }
+        }
+        if (!n.getMembers().isEmpty()) {
+            printer.println(";");
+            printMembers(n.getMembers(), arg);
+        } else {
+            if (!n.getEntries().isEmpty()) {
+                printer.println();
+            }
+        }
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final EnumConstantDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        n.getName().accept(this, arg);
+
+        if (!n.getArguments().isEmpty()) {
+            printArguments(n.getArguments(), arg);
+        }
+
+        if (!n.getClassBody().isEmpty()) {
+            printer.println(" {");
+            printer.indent();
+            printMembers(n.getClassBody(), arg);
+            printer.unindent();
+            printer.println("}");
+        }
+    }
+
+    @Override
+    public void visit(final InitializerDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.isStatic()) {
+            printer.print("static ");
+        }
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final IfStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("if (");
+        n.getCondition().accept(this, arg);
+        final boolean thenBlock = n.getThenStmt() instanceof BlockStmt;
+        if (thenBlock) // block statement should start on the same line
+            printer.print(") ");
+        else {
+            printer.println(")");
+            printer.indent();
+        }
+        n.getThenStmt().accept(this, arg);
+        if (!thenBlock)
+            printer.unindent();
+        if (n.getElseStmt().isPresent()) {
+            if (thenBlock)
+                printer.print(" ");
+            else
+                printer.println();
+            final boolean elseIf = n.getElseStmt().orElse(null) instanceof IfStmt;
+            final boolean elseBlock = n.getElseStmt().orElse(null) instanceof BlockStmt;
+            if (elseIf || elseBlock) // put chained if and start of block statement on a same level
+                printer.print("else ");
+            else {
+                printer.println("else");
+                printer.indent();
+            }
+            if (n.getElseStmt().isPresent())
+                n.getElseStmt().get().accept(this, arg);
+            if (!(elseIf || elseBlock))
+                printer.unindent();
+        }
+    }
+
+    @Override
+    public void visit(final WhileStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("while (");
+        n.getCondition().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ContinueStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("continue");
+        n.getLabel().ifPresent(l -> printer.print(" ").print(l.getIdentifier()));
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final DoStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("do ");
+        n.getBody().accept(this, arg);
+        printer.print(" while (");
+        n.getCondition().accept(this, arg);
+        printer.print(");");
+    }
+
+    @Override
+    public void visit(final ForeachStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("for (");
+        n.getVariable().accept(this, arg);
+        printer.print(" : ");
+        n.getIterable().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ForStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("for (");
+        if (n.getInitialization() != null) {
+            for (final Iterator<Expression> i = n.getInitialization().iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print("; ");
+        if (n.getCompare().isPresent()) {
+            n.getCompare().get().accept(this, arg);
+        }
+        printer.print("; ");
+        if (n.getUpdate() != null) {
+            for (final Iterator<Expression> i = n.getUpdate().iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ThrowStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("throw ");
+        n.getExpression().accept(this, arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final SynchronizedStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("synchronized (");
+        n.getExpression().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final TryStmt n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("try ");
+        if (!n.getResources().isEmpty()) {
+            printer.print("(");
+            Iterator<Expression> resources = n.getResources().iterator();
+            boolean first = true;
+            while (resources.hasNext()) {
+                resources.next().accept(this, arg);
+                if (resources.hasNext()) {
+                    printer.print(";");
+                    printer.println();
+                    if (first) {
+                        printer.indent();
+                    }
+                }
+                first = false;
+            }
+            if (n.getResources().size() > 1) {
+                printer.unindent();
+            }
+            printer.print(") ");
+        }
+        n.getTryBlock().accept(this, arg);
+        for (final CatchClause c : n.getCatchClauses()) {
+            c.accept(this, arg);
+        }
+        if (n.getFinallyBlock().isPresent()) {
+            printer.print(" finally ");
+            n.getFinallyBlock().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final CatchClause n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print(" catch (");
+        n.getParameter().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final AnnotationDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        printer.print("@interface ");
+        n.getName().accept(this, arg);
+        printer.println(" {");
+        printer.indent();
+        if (n.getMembers() != null) {
+            printMembers(n.getMembers(), arg);
+        }
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final AnnotationMemberDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        n.getType().accept(this, arg);
+        printer.print(" ");
+        n.getName().accept(this, arg);
+        printer.print("()");
+        if (n.getDefaultValue().isPresent()) {
+            printer.print(" default ");
+            n.getDefaultValue().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final MarkerAnnotationExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final SingleMemberAnnotationExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+        printer.print("(");
+        n.getMemberValue().accept(this, arg);
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final NormalAnnotationExpr n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+        printer.print("(");
+        if (n.getPairs() != null) {
+            for (final Iterator<MemberValuePair> i = n.getPairs().iterator(); i.hasNext(); ) {
+                final MemberValuePair m = i.next();
+                m.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final MemberValuePair n, final Void arg) {
+        printComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        printer.print(" = ");
+        n.getValue().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final LineComment n, final Void arg) {
+        if (configuration.isIgnoreComments()) {
+            return;
+        }
+        printer
+                .print("// ")
+                .println(normalizeEolInTextBlock(n.getContent(), "").trim());
+    }
+
+    @Override
+    public void visit(final BlockComment n, final Void arg) {
+        if (configuration.isIgnoreComments()) {
+            return;
+        }
+        final String commentContent = normalizeEolInTextBlock(n.getContent(), configuration.getEndOfLineCharacter());
+        String[] lines = commentContent.split("\\R", -1); // as BlockComment should not be formatted, -1 to preserve any trailing empty line if present
+        printer.print("/*");
+        for (int i = 0; i < (lines.length - 1); i++) {
+            printer.print(lines[i]);
+            printer.print(configuration.getEndOfLineCharacter()); // Avoids introducing indentation in blockcomments. ie: do not use println() as it would trigger indentation at the next print call.
+        }
+        printer.print(lines[lines.length - 1]); // last line is not followed by a newline, and simply terminated with `*/`
+        printer.println("*/");
+    }
+
+    @Override
+    public void visit(LambdaExpr n, Void arg) {
+        printComment(n.getComment(), arg);
+
+        final NodeList<Parameter> parameters = n.getParameters();
+        final boolean printPar = n.isEnclosingParameters();
+
+        if (printPar) {
+            printer.print("(");
+        }
+        for (Iterator<Parameter> i = parameters.iterator(); i.hasNext(); ) {
+            Parameter p = i.next();
+            p.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+        if (printPar) {
+            printer.print(")");
+        }
+
+        printer.print(" -> ");
+        final Statement body = n.getBody();
+        if (body instanceof ExpressionStmt) {
+            // Print the expression directly
+            ((ExpressionStmt) body).getExpression().accept(this, arg);
+        } else {
+            body.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(MethodReferenceExpr n, Void arg) {
+        printComment(n.getComment(), arg);
+        Expression scope = n.getScope();
+        String identifier = n.getIdentifier();
+        if (scope != null) {
+            n.getScope().accept(this, arg);
+        }
+
+        printer.print("::");
+        printTypeArgs(n, arg);
+        if (identifier != null) {
+            printer.print(identifier);
+        }
+    }
+
+    @Override
+    public void visit(TypeExpr n, Void arg) {
+        printComment(n.getComment(), arg);
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(NodeList n, Void arg) {
+        if (configuration.isOrderImports() && n.size() > 0 && n.get(0) instanceof ImportDeclaration) {
+            //noinspection unchecked
+            NodeList<ImportDeclaration> modifiableList = new NodeList<>(n);
+            modifiableList.sort((left, right) -> {
+                int sort = Integer.compare(left.isStatic() ? 0 : 1, right.isStatic() ? 0 : 1);
+                if (sort == 0) {
+                    sort = left.getNameAsString().compareTo(right.getNameAsString());
+                }
+                return sort;
+            });
+            for (Object node : modifiableList) {
+                ((Node) node).accept(this, arg);
+            }
+        } else {
+            for (Object node : n) {
+                ((Node) node).accept(this, arg);
+            }
+        }
+    }
+
+    @Override
+    public void visit(final ImportDeclaration n, final Void arg) {
+        printComment(n.getComment(), arg);
+        printer.print("import ");
+        if (n.isStatic()) {
+            printer.print("static ");
+        }
+        n.getName().accept(this, arg);
+        if (n.isAsterisk()) {
+            printer.print(".*");
+        }
+        printer.println(";");
+
+        printOrphanCommentsEnding(n);
+    }
+
+
+    @Override
+    public void visit(ModuleDeclaration n, Void arg) {
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.println();
+        if (n.isOpen()) {
+            printer.print("open ");
+        }
+        printer.print("module ");
+        n.getName().accept(this, arg);
+        printer.println(" {").indent();
+        n.getModuleStmts().accept(this, arg);
+        printer.unindent().println("}");
+    }
+
+    @Override
+    public void visit(ModuleRequiresStmt n, Void arg) {
+        printer.print("requires ");
+        printModifiers(n.getModifiers());
+        n.getName().accept(this, arg);
+        printer.println(";");
+    }
+
+    @Override
+    public void visit(ModuleExportsStmt n, Void arg) {
+        printer.print("exports ");
+        n.getName().accept(this, arg);
+        printPrePostFixOptionalList(n.getModuleNames(), arg, " to ", ", ", "");
+        printer.println(";");
+    }
+
+    @Override
+    public void visit(ModuleProvidesStmt n, Void arg) {
+        printer.print("provides ");
+        n.getType().accept(this, arg);
+        printPrePostFixRequiredList(n.getWithTypes(), arg, " with ", ", ", "");
+        printer.println(";");
+    }
+
+    @Override
+    public void visit(ModuleUsesStmt n, Void arg) {
+        printer.print("uses ");
+        n.getType().accept(this, arg);
+        printer.println(";");
+    }
+
+    @Override
+    public void visit(ModuleOpensStmt n, Void arg) {
+        printer.print("opens ");
+        n.getName().accept(this, arg);
+        printPrePostFixOptionalList(n.getModuleNames(), arg, " to ", ", ", "");
+        printer.println(";");
+    }
+
+    @Override
+    public void visit(UnparsableStmt n, Void arg) {
+        printer.print("???;");
+    }
+
+    private void printOrphanCommentsBeforeThisChildNode(final Node node) {
+        if (configuration.isIgnoreComments()) return;
+        if (node instanceof Comment) return;
+
+        Node parent = node.getParentNode().orElse(null);
+        if (parent == null) return;
+        List<Node> everything = new LinkedList<>();
+        everything.addAll(parent.getChildNodes());
+        sortByBeginPosition(everything);
+        int positionOfTheChild = -1;
+        for (int i = 0; i < everything.size(); i++) {
+            if (everything.get(i) == node) positionOfTheChild = i;
+        }
+        if (positionOfTheChild == -1) {
+            throw new AssertionError("I am not a child of my parent.");
+        }
+        int positionOfPreviousChild = -1;
+        for (int i = positionOfTheChild - 1; i >= 0 && positionOfPreviousChild == -1; i--) {
+            if (!(everything.get(i) instanceof Comment)) positionOfPreviousChild = i;
+        }
+        for (int i = positionOfPreviousChild + 1; i < positionOfTheChild; i++) {
+            Node nodeToPrint = everything.get(i);
+            if (!(nodeToPrint instanceof Comment))
+                throw new RuntimeException(
+                        "Expected comment, instead " + nodeToPrint.getClass() + ". Position of previous child: "
+                                + positionOfPreviousChild + ", position of child " + positionOfTheChild);
+            nodeToPrint.accept(this, null);
+        }
+    }
+
+    private void printOrphanCommentsEnding(final Node node) {
+        if (configuration.isIgnoreComments()) return;
+
+        List<Node> everything = new LinkedList<>();
+        everything.addAll(node.getChildNodes());
+        sortByBeginPosition(everything);
+        if (everything.isEmpty()) {
+            return;
+        }
+
+        int commentsAtEnd = 0;
+        boolean findingComments = true;
+        while (findingComments && commentsAtEnd < everything.size()) {
+            Node last = everything.get(everything.size() - 1 - commentsAtEnd);
+            findingComments = (last instanceof Comment);
+            if (findingComments) {
+                commentsAtEnd++;
+            }
+        }
+        for (int i = 0; i < commentsAtEnd; i++) {
+            everything.get(everything.size() - commentsAtEnd + i).accept(this, null);
+        }
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrinter.java
new file mode 100644
index 0000000..510457c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrinter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * Pretty printer for AST nodes.
+ */
+public class PrettyPrinter {
+    private final PrettyPrinterConfiguration configuration;
+
+    public PrettyPrinter() {
+        this(new PrettyPrinterConfiguration());
+    }
+
+    public PrettyPrinter(PrettyPrinterConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public String print(Node node) {
+        final PrettyPrintVisitor visitor = configuration.getVisitorFactory().apply(configuration);
+        node.accept(visitor, null);
+        return visitor.getSource();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrinterConfiguration.java b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrinterConfiguration.java
new file mode 100644
index 0000000..1c650d2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/PrettyPrinterConfiguration.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import java.util.function.Function;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Configuration options for the {@link PrettyPrinter}.
+ */
+public class PrettyPrinterConfiguration {
+    public static final int DEFAULT_MAX_ENUM_CONSTANTS_TO_ALIGN_HORIZONTALLY = 5;
+    
+    private boolean orderImports = false;
+    private boolean printComments = true;
+    private boolean printJavadoc = true;
+    private boolean columnAlignParameters = false;
+    private boolean columnAlignFirstMethodChain = false;
+    private String indent = "    ";
+    private String endOfLineCharacter = EOL;
+    private Function<PrettyPrinterConfiguration, PrettyPrintVisitor> visitorFactory = PrettyPrintVisitor::new;
+    private int maxEnumConstantsToAlignHorizontally = DEFAULT_MAX_ENUM_CONSTANTS_TO_ALIGN_HORIZONTALLY;
+
+    public String getIndent() {
+        return indent;
+    }
+
+    /**
+     * Set the string to use for indenting. For example: "\t", "    ", "".
+     */
+    public PrettyPrinterConfiguration setIndent(String indent) {
+        this.indent = assertNotNull(indent);
+        return this;
+    }
+
+    public boolean isOrderImports() {
+        return orderImports;
+    }
+
+    /**
+     * @deprecated this is always on.
+     */
+    @Deprecated
+    public boolean isNormalizeEolInComment() {
+        return true;
+    }
+
+    /**
+     * @deprecated this is always on.
+     */
+    @Deprecated
+    public PrettyPrinterConfiguration setNormalizeEolInComment(boolean normalizeEolInComment) {
+        return this;
+    }
+
+    public boolean isPrintComments() {
+        return printComments;
+    }
+
+    public boolean isIgnoreComments() {
+        return !printComments;
+    }
+
+    public boolean isPrintJavadoc() {
+        return printJavadoc;
+    }
+
+    public boolean isColumnAlignParameters() {
+        return columnAlignParameters;
+    }
+
+    public boolean isColumnAlignFirstMethodChain() {
+        return columnAlignFirstMethodChain;
+    }
+
+    /**
+     * When true, all comments will be printed, unless printJavadoc is false, then only line and block comments will be
+     * printed.
+     */
+    public PrettyPrinterConfiguration setPrintComments(boolean printComments) {
+        this.printComments = printComments;
+        return this;
+    }
+
+    /**
+     * When true, Javadoc will be printed.
+     */
+    public PrettyPrinterConfiguration setPrintJavadoc(boolean printJavadoc) {
+        this.printJavadoc = printJavadoc;
+        return this;
+    }
+
+    public PrettyPrinterConfiguration setColumnAlignParameters(boolean columnAlignParameters) {
+        this.columnAlignParameters = columnAlignParameters;
+        return this;
+    }
+
+    public PrettyPrinterConfiguration setColumnAlignFirstMethodChain(boolean columnAlignFirstMethodChain) {
+        this.columnAlignFirstMethodChain = columnAlignFirstMethodChain;
+        return this;
+    }
+
+    public Function<PrettyPrinterConfiguration, PrettyPrintVisitor> getVisitorFactory() {
+        return visitorFactory;
+    }
+
+    /**
+     * Set the factory that creates the PrettyPrintVisitor. By changing this you can make the PrettyPrinter use a custom
+     * PrettyPrinterVisitor.
+     */
+    public PrettyPrinterConfiguration setVisitorFactory(Function<PrettyPrinterConfiguration, PrettyPrintVisitor> visitorFactory) {
+        this.visitorFactory = assertNotNull(visitorFactory);
+        return this;
+    }
+
+    public String getEndOfLineCharacter() {
+        return endOfLineCharacter;
+    }
+
+    /**
+     * Set the character to append when a line should end. Example values: "\n", "\r\n", "".
+     */
+    public PrettyPrinterConfiguration setEndOfLineCharacter(String endOfLineCharacter) {
+        this.endOfLineCharacter = assertNotNull(endOfLineCharacter);
+        return this;
+    }
+
+    /**
+     * When true, orders imports by alphabetically.
+     */
+    public PrettyPrinterConfiguration setOrderImports(boolean orderImports) {
+        this.orderImports = orderImports;
+        return this;
+    }
+
+    public int getMaxEnumConstantsToAlignHorizontally() {
+        return maxEnumConstantsToAlignHorizontally;
+    }
+
+    /**
+     * By default enum constants get aligned like this:
+     * <pre>
+     *     enum X {
+     *        A, B, C, D
+     *     }
+     * </pre>
+     * until the amount of constants passes this value (5 by default).
+     * Then they get aligned like this:
+     * <pre>
+     *     enum X {
+     *        A,
+     *        B,
+     *        C,
+     *        D,
+     *        E,
+     *        F,
+     *        G
+     *     }
+     * </pre>
+     * Set it to a large number to always align horizontally.
+     * Set it to 1 or less to always align vertically.
+     */
+    public PrettyPrinterConfiguration setMaxEnumConstantsToAlignHorizontally(int maxEnumConstantsToAlignHorizontally) {
+        this.maxEnumConstantsToAlignHorizontally = maxEnumConstantsToAlignHorizontally;
+        return this;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/Printable.java b/javaparser-core/src/main/java/com/github/javaparser/printer/Printable.java
new file mode 100644
index 0000000..390baa7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/Printable.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.printer;
+
+/**
+ * Something that has a printable form. I.e., it can be converted to a user-facing String.
+ */
+public interface Printable {
+    String asString();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/SourcePrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/SourcePrinter.java
new file mode 100644
index 0000000..a53d907
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/SourcePrinter.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.Position;
+import com.github.javaparser.utils.Utils;
+
+public class SourcePrinter {
+
+    private final String indentation;
+    private final int indentationLength;
+    private final String endOfLineCharacter;
+    private int level = 0;
+    private boolean indented = false;
+    private final StringBuilder buf = new StringBuilder();
+    private Position cursor = new Position(1, 0);
+
+    SourcePrinter(final String indentation, final String endOfLineCharacter) {
+        this.indentation = indentation;
+        this.indentationLength = indentation.length();
+        this.endOfLineCharacter = endOfLineCharacter;
+    }
+
+    public SourcePrinter indent() {
+        level++;
+        return this;
+    }
+
+    public SourcePrinter unindent() {
+        level--;
+        return this;
+    }
+
+    private void makeIndent() {
+        for (int i = 0; i < level; i++) {
+            buf.append(indentation);
+            cursor = Position.pos(cursor.line, cursor.column + indentationLength);
+        }
+    }
+
+    /**
+     * Append the source string passed as argument to the buffer.
+     * If this is being appended at the beginning of a line, performs indentation first.
+     * <p> 
+     * The source line to be printed should not contain newline/carriage-return characters;
+     * use {@link #println(String)} to automatically append a newline at the end of the source string.
+     * If the source line passed as argument contains newline/carriage-return characters would
+     * impredictably affect a correct computation of the current {@link #getCursor()} position. 
+     * 
+     * @see SourcePrinter#println(String) 
+     * @param arg source line to be printed (should not contain newline/carriage-return characters)
+     * @return this instance, for nesting calls to method as fluent interface
+     */
+    public SourcePrinter print(final String arg) {
+        if (!indented) {
+            makeIndent();
+            indented = true;
+        }
+        buf.append(arg);
+        cursor = Position.pos(cursor.line, cursor.column + arg.length());
+        return this;
+    }
+
+    /**
+     * Append the source string passed as argument to the buffer, then append a newline.
+     * If this is being appended at the beginning of a line, performs indentation first.
+     * <p>  
+     * The source line to be printed should not contain newline/carriage-return characters.
+     * If the source line passed as argument contains newline/carriage-return characters would
+     * impredictably affect a correct computation of the current {@link #getCursor()} position. 
+     * 
+     * @param arg source line to be printed (should not contain newline/carriage-return characters)
+     * @return this instance, for nesting calls to method as fluent interface
+     */
+    public SourcePrinter println(final String arg) {
+        print(arg);
+        println();
+        return this;
+    }
+
+    /**
+     * Append a newline to the buffer.
+     * 
+     * @return this instance, for nesting calls to method as fluent interface
+     */
+    public SourcePrinter println() {
+        buf.append(endOfLineCharacter);
+        cursor = Position.pos(cursor.line + 1, 0);
+        indented = false;
+        return this;
+    }
+
+    /**
+     * Return the current cursor position (line, column) in the source printer buffer.
+     * <p> 
+     * Please notice in order to guarantee a correct computation of the cursor position,
+     * this printer expect the contracts of the methods {@link #print(String)} and {@link #println(String)}
+     * has been respected through all method calls, meaning the source string passed as argument to those method
+     * calls did not contain newline/carriage-return characters.
+     * 
+     * @return the current cursor position (line, column).
+     */
+    public Position getCursor() {
+        return cursor;
+    }
+
+    /**
+     * Performs a new line and indent, then prints enough space characters until aligned to the specified column.
+     * @param column the column to align to
+     */
+    public void wrapToColumn(int column) {
+        println();
+        if (!indented) {
+            makeIndent();
+            indented = true;
+        }
+        while ( cursor.column < column ) {
+            print(" ");
+        }
+    }
+
+    public String getSource() {
+        return buf.toString();
+    }
+
+    @Override
+    public String toString() {
+        return getSource();
+    }
+
+    public String normalizeEolInTextBlock(String content) {
+        return Utils.normalizeEolInTextBlock(content, endOfLineCharacter);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/XmlPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/XmlPrinter.java
new file mode 100644
index 0000000..ea69c9e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/XmlPrinter.java
@@ -0,0 +1,77 @@
+package com.github.javaparser.printer;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.metamodel.NodeMetaModel;
+import com.github.javaparser.metamodel.PropertyMetaModel;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.stream.Collectors.toList;
+
+/**
+ * Outputs an XML file containing the AST meant for inspecting it.
+ */
+public class XmlPrinter {
+    private final boolean outputNodeType;
+
+    public XmlPrinter(boolean outputNodeType) {
+        this.outputNodeType = outputNodeType;
+    }
+
+    public String output(Node node) {
+        StringBuilder output = new StringBuilder();
+        output(node, "root", 0, output);
+        return output.toString();
+    }
+
+    public void output(Node node, String name, int level, StringBuilder builder) {
+        assertNotNull(node);
+        NodeMetaModel metaModel = node.getMetaModel();
+        List<PropertyMetaModel> allPropertyMetaModels = metaModel.getAllPropertyMetaModels();
+        List<PropertyMetaModel> attributes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isAttribute).filter(PropertyMetaModel::isSingular).collect(toList());
+        List<PropertyMetaModel> subNodes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNode).filter(PropertyMetaModel::isSingular).collect(toList());
+        List<PropertyMetaModel> subLists = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNodeList).collect(toList());
+
+        builder.append("<").append(name);
+        if (outputNodeType) {
+            builder.append(attribute("type", metaModel.getTypeName()));
+        }
+
+        for (PropertyMetaModel attributeMetaModel : attributes) {
+            builder.append(attribute(attributeMetaModel.getName(), attributeMetaModel.getValue(node).toString()));
+        }
+        builder.append(">");
+
+        for (PropertyMetaModel subNodeMetaModel : subNodes) {
+            Node value = (Node) subNodeMetaModel.getValue(node);
+            if (value != null) {
+                output(value, subNodeMetaModel.getName(), level + 1, builder);
+            }
+        }
+
+        for (PropertyMetaModel subListMetaModel : subLists) {
+            NodeList<? extends Node> subList = (NodeList<? extends Node>) subListMetaModel.getValue(node);
+            if (subList != null && !subList.isEmpty()) {
+                String listName = subListMetaModel.getName();
+                builder.append("<").append(listName).append(">");
+                String singular = listName.substring(0, listName.length() - 1);
+                for (Node subListNode : subList) {
+                    output(subListNode, singular, level + 1, builder);
+                }
+                builder.append(close(listName));
+            }
+        }
+        builder.append(close(name));
+    }
+
+    private static String close(String name) {
+        return "</" + name + ">";
+    }
+
+    private static String attribute(String name, String value) {
+        return " " + name + "='" + value + "'";
+    }
+}
+
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/YamlPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/YamlPrinter.java
new file mode 100644
index 0000000..1e418f5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/YamlPrinter.java
@@ -0,0 +1,101 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.printer;

+

+import static com.github.javaparser.utils.Utils.assertNotNull;

+import static java.util.stream.Collectors.toList;

+

+import java.util.List;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.NodeList;

+import com.github.javaparser.metamodel.NodeMetaModel;

+import com.github.javaparser.metamodel.PropertyMetaModel;

+

+/**

+ * Outputs a YAML file containing the AST meant for inspecting it.

+ */

+public class YamlPrinter {

+

+    private static final int NUM_SPACES_FOR_INDENT = 4;

+    private final boolean outputNodeType;

+

+    public YamlPrinter(boolean outputNodeType) {

+        this.outputNodeType = outputNodeType;

+    }

+

+    public String output(Node node) {

+        StringBuilder output = new StringBuilder();

+        output.append("---");

+        output(node, "root", 0, output);

+        output.append(System.lineSeparator() + "...");

+        return output.toString();

+    }

+

+    public void output(Node node, String name, int level, StringBuilder builder) {

+        assertNotNull(node);

+        NodeMetaModel metaModel = node.getMetaModel();

+        List<PropertyMetaModel> allPropertyMetaModels = metaModel.getAllPropertyMetaModels();

+        List<PropertyMetaModel> attributes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isAttribute)

+                .filter(PropertyMetaModel::isSingular).collect(toList());

+        List<PropertyMetaModel> subNodes = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNode)

+                .filter(PropertyMetaModel::isSingular).collect(toList());

+        List<PropertyMetaModel> subLists = allPropertyMetaModels.stream().filter(PropertyMetaModel::isNodeList)

+                .collect(toList());

+

+        if (outputNodeType)

+            builder.append(System.lineSeparator() + indent(level) + name + "(Type=" + metaModel.getTypeName() + "): ");

+        else

+            builder.append(System.lineSeparator() + indent(level) + name + ": ");

+

+        level++;

+        for (PropertyMetaModel a : attributes) {

+            builder.append(System.lineSeparator() + indent(level) + a.getName() + ": \""

+                    + a.getValue(node).toString() + "\"");

+        }

+

+        for (PropertyMetaModel sn : subNodes) {

+            Node nd = (Node) sn.getValue(node);

+            if (nd != null)

+                output(nd, sn.getName(), level, builder);

+        }

+

+        for (PropertyMetaModel sl : subLists) {

+            NodeList<? extends Node> nl = (NodeList<? extends Node>) sl.getValue(node);

+            if (nl != null && nl.isNonEmpty()) {

+                builder.append(System.lineSeparator() + indent(level) + sl.getName() + ": ");

+                String slName = sl.getName();

+                slName = slName.endsWith("s") ? slName.substring(0, sl.getName().length() - 1) : slName;

+                for (Node nd : nl)

+                    output(nd, "- " + slName, level + 1, builder);

+            }

+        }

+    }

+

+    private String indent(int level) {

+        StringBuilder sb = new StringBuilder();

+        for (int i = 0; i < level; i++)

+            for (int j = 0; j < NUM_SPACES_FOR_INDENT; j++)

+                sb.append(" ");

+        return sb.toString();

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmAttribute.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmAttribute.java
new file mode 100644
index 0000000..b44672d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmAttribute.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmAttribute implements CsmElement {
+    public ObservableProperty getProperty() {
+        return property;
+    }
+
+    private final ObservableProperty property;
+
+    public CsmAttribute(ObservableProperty property) {
+        this.property = property;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        Object value = property.getRawValue(node);
+        printer.print(PrintingHelper.printToString(value));
+    }
+
+    /**
+     * Obtain the token type corresponding to the specific value of the attribute.
+     * For example, to the attribute "Operator" different token could correspond like PLUS or MINUS.
+     */
+    public int getTokenType(Node node, String text) {
+        switch (property) {
+            case IDENTIFIER:
+                return GeneratedJavaParserConstants.IDENTIFIER;
+            case TYPE:
+                String expectedImage = "\"" + text.toLowerCase() + "\"";
+                for (int i=0;i<GeneratedJavaParserConstants.tokenImage.length;i++) {
+                    if (GeneratedJavaParserConstants.tokenImage[i].equals(expectedImage)) {
+                        return i;
+                    }
+                }
+                throw new RuntimeException("Attribute 'type' does not corresponding to any expected value. Text: " + text);
+            case OPERATOR:
+                try {
+                    return (Integer)(GeneratedJavaParserConstants.class.getDeclaredField(text).get(null));
+                } catch (IllegalAccessException|NoSuchFieldException e) {
+                    throw new RuntimeException("Attribute 'operator' does not corresponding to any expected value. Text: " + text, e);
+                }
+            case VALUE:
+                if (node instanceof IntegerLiteralExpr) {
+                    return GeneratedJavaParserConstants.INTEGER_LITERAL;
+                }
+            case NAME:
+                return GeneratedJavaParserConstants.IDENTIFIER;
+        }
+        throw new UnsupportedOperationException("getTokenType does not know how to handle property "
+                + property + " with text: " + text);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmChar.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmChar.java
new file mode 100644
index 0000000..2f22899
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmChar.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmChar implements CsmElement {
+    private final ObservableProperty property;
+
+    public CsmChar(ObservableProperty property) {
+        this.property = property;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        printer.print("'");
+        printer.print(property.getValueAsStringAttribute(node));
+        printer.print("'");
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmComment.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmComment.java
new file mode 100644
index 0000000..8e684c4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmComment.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmComment implements CsmElement {
+
+    static void process(Comment comment, SourcePrinter printer) {
+        String content = printer.normalizeEolInTextBlock(comment.getContent());
+        if (comment instanceof BlockComment) {
+            printer.print("/*");
+            printer.print(content);
+            printer.println("*/");
+        } else if (comment instanceof JavadocComment) {
+            printer.print("/**");
+            printer.print(content);
+            printer.println("*/");
+        } else if (comment instanceof LineComment) {
+            printer.print("//");
+            printer.print(content);
+            printer.println();
+        } else {
+            throw new UnsupportedOperationException(comment.getClass().getSimpleName());
+        }
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        node.getComment().ifPresent(c -> process(c, printer));
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmConditional.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmConditional.java
new file mode 100644
index 0000000..a2ca7cd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmConditional.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.SourcePrinter;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class CsmConditional implements CsmElement {
+    private final Condition condition;
+    private final List<ObservableProperty> properties;
+    private final CsmElement thenElement;
+    private final CsmElement elseElement;
+
+    public Condition getCondition() {
+        return condition;
+    }
+
+    public ObservableProperty getProperty() {
+        if (properties.size() > 1) {
+            throw new IllegalStateException();
+        }
+        return properties.get(0);
+    }
+
+    public CsmElement getThenElement() {
+        return thenElement;
+    }
+
+    public CsmElement getElseElement() {
+        return elseElement;
+    }
+
+    public enum Condition {
+        IS_EMPTY,
+        IS_NOT_EMPTY,
+        IS_PRESENT,
+        FLAG;
+
+        boolean evaluate(Node node, ObservableProperty property){
+            if (this == IS_PRESENT) {
+                return !property.isNullOrNotPresent(node);
+            }
+            if (this == FLAG) {
+                return property.getValueAsBooleanAttribute(node);
+            }
+            if (this == IS_EMPTY) {
+                NodeList value = property.getValueAsMultipleReference(node);
+                return value == null || value.isEmpty();
+            }
+            if (this == IS_NOT_EMPTY) {
+                NodeList value = property.getValueAsMultipleReference(node);
+                return value != null && !value.isEmpty();
+            }
+            throw new UnsupportedOperationException(name());
+        }
+    }
+
+    public CsmConditional(ObservableProperty property, Condition condition, CsmElement thenElement, CsmElement elseElement) {
+        this.properties = Arrays.asList(property);
+        this.condition = condition;
+        this.thenElement = thenElement;
+        this.elseElement = elseElement;
+    }
+
+    public CsmConditional(List<ObservableProperty> properties, Condition condition, CsmElement thenElement, CsmElement elseElement) {
+        if (properties.size() < 1) {
+            throw new IllegalArgumentException();
+        }
+        this.properties = properties;
+        this.condition = condition;
+        this.thenElement = thenElement;
+        this.elseElement = elseElement;
+    }
+
+    public CsmConditional(ObservableProperty property, Condition condition, CsmElement thenElement) {
+        this(property, condition, thenElement, new CsmNone());
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        boolean test = false;
+        for (ObservableProperty prop : properties) {
+            test = test || condition.evaluate(node, prop);
+        }
+        if (test) {
+            thenElement.prettyPrint(node, printer);
+        } else {
+            elseElement.prettyPrint(node, printer);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmElement.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmElement.java
new file mode 100644
index 0000000..61566d1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmElement.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.SourcePrinter;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.github.javaparser.TokenTypes.*;
+import static com.github.javaparser.utils.Utils.EOL;
+
+public interface CsmElement {
+
+    void prettyPrint(Node node, SourcePrinter printer);
+
+    static CsmElement child(ObservableProperty property) {
+        return new CsmSingleReference(property);
+    }
+
+    static CsmElement attribute(ObservableProperty property) {
+        return new CsmAttribute(property);
+    }
+
+    static CsmElement sequence(CsmElement... elements) {
+        return new CsmSequence(Arrays.asList(elements));
+    }
+
+    static CsmElement string(int tokenType, String content) {
+        return new CsmToken(tokenType, content);
+    }
+
+    static CsmElement string(int tokenType) {
+        return new CsmToken(tokenType);
+    }
+
+    static CsmElement stringToken(ObservableProperty property) {
+        return new CsmString(property);
+    }
+
+    static CsmElement charToken(ObservableProperty property) {
+        return new CsmChar(property);
+    }
+
+    static CsmElement token(int tokenType) {
+        return new CsmToken(tokenType);
+    }
+
+    static CsmElement token(int tokenType, CsmToken.TokenContentCalculator tokenContentCalculator) {
+        return new CsmToken(tokenType, tokenContentCalculator);
+    }
+
+    static CsmElement conditional(ObservableProperty property, CsmConditional.Condition condition, CsmElement thenElement) {
+        return new CsmConditional(property, condition, thenElement);
+    }
+
+    static CsmElement conditional(ObservableProperty property, CsmConditional.Condition condition, CsmElement thenElement, CsmElement elseElement) {
+        return new CsmConditional(property, condition, thenElement, elseElement);
+    }
+
+    static CsmElement conditional(List<ObservableProperty> properties, CsmConditional.Condition condition, CsmElement thenElement, CsmElement elseElement) {
+        return new CsmConditional(properties, condition, thenElement, elseElement);
+    }
+
+    static CsmElement space() {
+        return new CsmToken(spaceTokenKind(), " ");
+    }
+
+    static CsmElement semicolon() {
+        return new CsmToken(GeneratedJavaParserConstants.SEMICOLON);
+    }
+
+    static CsmElement comment() { return new CsmComment(); }
+
+    static CsmElement newline() {
+        return new CsmToken(eolTokenKind(), EOL);
+    }
+
+    static CsmElement none() {
+        return new CsmNone();
+    }
+
+    static CsmElement comma() {
+        return new CsmToken(GeneratedJavaParserConstants.COMMA);
+    }
+
+    static CsmElement list(ObservableProperty property) {
+        return new CsmList(property);
+    }
+
+    static CsmElement list(ObservableProperty property, CsmElement separator) {
+        return new CsmList(property, CsmElement.none(), separator, new CsmNone(), new CsmNone());
+    }
+
+    static CsmElement list(ObservableProperty property, CsmElement separator, CsmElement preceeding, CsmElement following) {
+        return new CsmList(property, none(), separator, preceeding, following);
+    }
+
+    static CsmElement list(ObservableProperty property, CsmElement separatorPre, CsmElement separatorPost, CsmElement preceeding, CsmElement following) {
+        return new CsmList(property, separatorPre, separatorPost, preceeding, following);
+    }
+
+    static CsmElement orphanCommentsEnding() {
+        return new CsmOrphanCommentsEnding();
+    }
+
+    static CsmElement orphanCommentsBeforeThis() {
+        // FIXME
+        return new CsmNone();
+    }
+
+    static CsmElement indent() {
+        return new CsmIndent();
+    }
+
+    static CsmElement unindent() {
+        return new CsmUnindent();
+    }
+
+    static CsmElement block(CsmElement content) {
+        return sequence(token(GeneratedJavaParserConstants.LBRACE), indent(), content, unindent(), token(GeneratedJavaParserConstants.RBRACE));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmIndent.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmIndent.java
new file mode 100644
index 0000000..69be97f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmIndent.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmIndent implements CsmElement {
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        printer.indent();
+    }
+
+    @Override
+    public int hashCode() {
+        return 1;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof CsmIndent;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmList.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmList.java
new file mode 100644
index 0000000..30fae7e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmList.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import com.github.javaparser.printer.SourcePrinter;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+public class CsmList implements CsmElement {
+    private final ObservableProperty property;
+    private final CsmElement separatorPost;
+    private final CsmElement separatorPre;
+    private final CsmElement preceeding;
+    private final CsmElement following;
+
+    public ObservableProperty getProperty() {
+        return property;
+    }
+
+    public CsmElement getSeparatorPost() {
+        return separatorPost;
+    }
+
+    public CsmElement getSeparatorPre() {
+        return separatorPre;
+    }
+
+    public CsmElement getPreceeding() {
+        return preceeding;
+    }
+
+    public CsmElement getFollowing() {
+        return following;
+    }
+
+    public CsmList(ObservableProperty property, CsmElement separator) {
+        this(property, new CsmNone(), separator, new CsmNone(), new CsmNone());
+    }
+
+    public CsmList(ObservableProperty property) {
+        this(property, new CsmNone(), new CsmNone(), new CsmNone(), new CsmNone());
+    }
+
+    public CsmList(ObservableProperty property, CsmElement separatorPre, CsmElement separatorPost, CsmElement preceeding, CsmElement following) {
+        this.property = property;
+        this.separatorPre = separatorPre;
+        this.separatorPost = separatorPost;
+        this.preceeding = preceeding;
+        this.following = following;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        if (property.isAboutNodes()) {
+            NodeList nodeList = property.getValueAsMultipleReference(node);
+            if (nodeList == null) {
+                return;
+            }
+            if (!nodeList.isEmpty() && preceeding != null) {
+                preceeding.prettyPrint(node, printer);
+            }
+            for (int i = 0; i < nodeList.size(); i++) {
+                if (separatorPre != null && i != 0) {
+                    separatorPre.prettyPrint(node, printer);
+                }
+                ConcreteSyntaxModel.genericPrettyPrint(nodeList.get(i), printer);
+                if (separatorPost != null && i != (nodeList.size() - 1)) {
+                    separatorPost.prettyPrint(node, printer);
+                }
+            }
+            if (!nodeList.isEmpty() && following != null) {
+                following.prettyPrint(node, printer);
+            }
+        } else {
+            Collection<?> values = property.getValueAsCollection(node);
+            if (values == null) {
+                return;
+            }
+            if (!values.isEmpty() && preceeding != null) {
+                preceeding.prettyPrint(node, printer);
+            }
+            for (Iterator it = values.iterator(); it.hasNext(); ) {
+                if (separatorPre != null && it.hasNext()) {
+                    separatorPre.prettyPrint(node, printer);
+                }
+                printer.print(PrintingHelper.printToString(it.next()));
+                if (separatorPost != null && it.hasNext()) {
+                    separatorPost.prettyPrint(node, printer);
+                }
+            }
+            if (!values.isEmpty() && following != null) {
+                following.prettyPrint(node, printer);
+            }
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmMix.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmMix.java
new file mode 100644
index 0000000..9ce5461
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmMix.java
@@ -0,0 +1,54 @@
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.printer.SourcePrinter;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * A group of elements that could be in any order.
+ */
+public class CsmMix implements CsmElement {
+    private List<CsmElement> elements;
+
+    public CsmMix(List<CsmElement> elements) {
+        if (elements == null) {
+            throw new NullPointerException();
+        }
+        if (elements.stream().anyMatch(Objects::isNull)) {
+            throw new IllegalArgumentException("Null element in the mix");
+        }
+        this.elements = elements;
+    }
+
+    public List<CsmElement> getElements() {
+        return elements;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        elements.forEach(e -> e.prettyPrint(node, printer));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        CsmMix csmMix = (CsmMix) o;
+
+        return elements != null ? elements.equals(csmMix.elements) : csmMix.elements == null;
+    }
+
+    @Override
+    public int hashCode() {
+        return elements != null ? elements.hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return "CsmMix[" + String.join(", ", elements.stream().map(e -> elements.toString()).collect(Collectors.toList())) + "]";
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmNone.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmNone.java
new file mode 100644
index 0000000..372bf8f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmNone.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmNone implements CsmElement {
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmOrphanCommentsEnding.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmOrphanCommentsEnding.java
new file mode 100644
index 0000000..dc04e16
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmOrphanCommentsEnding.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.printer.SourcePrinter;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.github.javaparser.utils.PositionUtils.sortByBeginPosition;
+
+public class CsmOrphanCommentsEnding implements CsmElement {
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        List<Node> everything = new LinkedList<>();
+        everything.addAll(node.getChildNodes());
+        sortByBeginPosition(everything);
+        if (everything.isEmpty()) {
+            return;
+        }
+
+        int commentsAtEnd = 0;
+        boolean findingComments = true;
+        while (findingComments && commentsAtEnd < everything.size()) {
+            Node last = everything.get(everything.size() - 1 - commentsAtEnd);
+            findingComments = (last instanceof Comment);
+            if (findingComments) {
+                commentsAtEnd++;
+            }
+        }
+        for (int i = 0; i < commentsAtEnd; i++) {
+            Comment c = (Comment)everything.get(everything.size() - commentsAtEnd + i);
+            CsmComment.process(c, printer);
+        }
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmSequence.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmSequence.java
new file mode 100644
index 0000000..fcfd9ad
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmSequence.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.printer.SourcePrinter;
+
+import java.util.List;
+import java.util.Objects;
+
+public class CsmSequence implements CsmElement {
+    private List<CsmElement> elements;
+
+    public CsmSequence(List<CsmElement> elements) {
+        if (elements == null) {
+            throw new NullPointerException();
+        }
+        if (elements.stream().anyMatch(Objects::isNull)) {
+            throw new IllegalArgumentException("Null element in the sequence");
+        }
+        this.elements = elements;
+    }
+
+    public List<CsmElement> getElements() {
+        return elements;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        elements.forEach(e -> e.prettyPrint(node, printer));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmSingleReference.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmSingleReference.java
new file mode 100644
index 0000000..36211a1
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmSingleReference.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmSingleReference implements CsmElement {
+    private final ObservableProperty property;
+
+    public ObservableProperty getProperty() {
+        return property;
+    }
+
+    public CsmSingleReference(ObservableProperty property) {
+        this.property = property;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        Node child = property.getValueAsSingleReference(node);
+        if (child != null) {
+            ConcreteSyntaxModel.genericPrettyPrint(child, printer);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmString.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmString.java
new file mode 100644
index 0000000..2fa0178
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmString.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmString implements CsmElement {
+    private final ObservableProperty property;
+
+    public CsmString(ObservableProperty property) {
+        this.property = property;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        printer.print("\"");
+        printer.print(property.getValueAsStringAttribute(node));
+        printer.print("\"");
+    }
+
+    @Override
+    public String toString() {
+        return String.format("CsmString(property:%s)", property);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmToken.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmToken.java
new file mode 100644
index 0000000..d0745f7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmToken.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.printer.SourcePrinter;
+import com.github.javaparser.TokenTypes;
+import com.github.javaparser.utils.Utils;
+
+import static com.github.javaparser.TokenTypes.isEndOfLineToken;
+import static com.github.javaparser.TokenTypes.isSpaceOrTab;
+
+public class CsmToken implements CsmElement {
+    private final int tokenType;
+    private String content;
+    private TokenContentCalculator tokenContentCalculator;
+
+    public interface TokenContentCalculator {
+        String calculate(Node node);
+    }
+
+    public int getTokenType() {
+        return tokenType;
+    }
+
+    public String getContent(Node node) {
+        if (tokenContentCalculator != null) {
+            return tokenContentCalculator.calculate(node);
+        }
+        return content;
+    }
+
+    public CsmToken(int tokenType) {
+        this.tokenType = tokenType;
+        this.content = GeneratedJavaParserConstants.tokenImage[tokenType];
+        if (content.startsWith("\"")) {
+            content = content.substring(1, content.length() - 1);
+        }
+        if (isEndOfLineToken(tokenType)) {
+            content = Utils.EOL;
+        } else if (isSpaceOrTab(tokenType)) {
+            content = " ";
+        }
+    }
+
+    public CsmToken(int tokenType, String content) {
+        this.tokenType = tokenType;
+        this.content = content;
+    }
+
+    public CsmToken(int tokenType, TokenContentCalculator tokenContentCalculator) {
+        this.tokenType = tokenType;
+        this.tokenContentCalculator = tokenContentCalculator;
+    }
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        if (isEndOfLineToken(tokenType)) {
+            printer.println();
+        } else {
+            printer.print(getContent(node));
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "token(" + content + ")";
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        CsmToken csmToken = (CsmToken) o;
+
+        if (tokenType != csmToken.tokenType) return false;
+        if (content != null ? !content.equals(csmToken.content) : csmToken.content != null) return false;
+        return tokenContentCalculator != null ? tokenContentCalculator.equals(csmToken.tokenContentCalculator) : csmToken.tokenContentCalculator == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = tokenType;
+        result = 31 * result + (content != null ? content.hashCode() : 0);
+        result = 31 * result + (tokenContentCalculator != null ? tokenContentCalculator.hashCode() : 0);
+        return result;
+    }
+
+    public boolean isWhiteSpace() {
+        return TokenTypes.isWhitespace(tokenType);
+    }
+
+    public boolean isNewLine() {
+        return TokenTypes.isEndOfLineToken(tokenType);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmUnindent.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmUnindent.java
new file mode 100644
index 0000000..bc4a001
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/CsmUnindent.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.printer.SourcePrinter;
+
+public class CsmUnindent implements CsmElement {
+
+    @Override
+    public void prettyPrint(Node node, SourcePrinter printer) {
+        printer.unindent();
+    }
+
+    @Override
+    public int hashCode() {
+        return 2;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof CsmUnindent;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/PrintingHelper.java b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/PrintingHelper.java
new file mode 100644
index 0000000..626b0b8
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/concretesyntaxmodel/PrintingHelper.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.concretesyntaxmodel;
+
+import com.github.javaparser.printer.Printable;
+
+class PrintingHelper {
+
+    static String printToString(Object value) {
+        if (value instanceof Printable) {
+            return ((Printable)value).asString();
+        }
+        if (value instanceof Enum) {
+            return ((Enum) value).name().toLowerCase();
+        } else {
+            if (value != null) {
+                return value.toString();
+            }
+        }
+        return "";
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/ChildTextElement.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/ChildTextElement.java
new file mode 100644
index 0000000..ad890c4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/ChildTextElement.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.Comment;
+
+/**
+ * Represent the position of a child node in the NodeText of its parent.
+ */
+class ChildTextElement extends TextElement {
+    private final Node child;
+
+    ChildTextElement(Node child) {
+        this.child = child;
+    }
+
+    String expand() {
+        return LexicalPreservingPrinter.print(child);
+    }
+
+    Node getChild() {
+        return child;
+    }
+
+    @Override
+    boolean isToken(int tokenKind) {
+        return false;
+    }
+
+    @Override
+    boolean isNode(Node node) {
+        return node == child;
+    }
+
+    NodeText getNodeTextForWrappedNode() {
+        return LexicalPreservingPrinter.getOrCreateNodeText(child);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ChildTextElement that = (ChildTextElement) o;
+
+        return child.equals(that.child);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return child.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "ChildTextElement{" + child + '}';
+    }
+
+    @Override
+    public boolean isWhiteSpace() {
+        return false;
+    }
+
+    @Override
+    public boolean isSpaceOrTab() {
+        return false;
+    }
+
+    @Override
+    public boolean isNewline() {
+        return false;
+    }
+
+    @Override
+    public boolean isComment() {
+        return child instanceof Comment;
+    }
+
+    @Override
+    public boolean isChildOfClass(Class<? extends Node> nodeClass) {
+        return nodeClass.isInstance(child);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/Difference.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/Difference.java
new file mode 100644
index 0000000..610f916
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/Difference.java
@@ -0,0 +1,885 @@
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.TokenTypes;
+import com.github.javaparser.printer.concretesyntaxmodel.*;
+import com.github.javaparser.printer.lexicalpreservation.LexicalDifferenceCalculator.CsmChild;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.*;
+
+/**
+ * A Difference should give me a sequence of elements I should find (to indicate the context) followed by a list of elements
+ * to remove or to add and follow by another sequence of elements.
+ *
+ * I should later be able to apply such difference to a nodeText.
+ */
+public class Difference {
+
+    private static final int STANDARD_INDENTATION_SIZE = 4;
+
+    private final List<DifferenceElement> elements;
+
+    private Difference(List<DifferenceElement> elements) {
+        this.elements = elements;
+    }
+
+    interface DifferenceElement {
+        static DifferenceElement added(CsmElement element) {
+            return new Added(element);
+        }
+
+        static DifferenceElement removed(CsmElement element) {
+            return new Removed(element);
+        }
+
+        static DifferenceElement kept(CsmElement element) {
+            return new Kept(element);
+        }
+
+        /**
+         * Return the CsmElement considered in this DifferenceElement.
+         */
+        CsmElement getElement();
+
+        boolean isAdded();
+    }
+
+    private static class Added implements DifferenceElement {
+        final CsmElement element;
+
+        public Added(CsmElement element) {
+            this.element = element;
+        }
+
+        @Override
+        public String toString() {
+            return "Added{" + element + '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Added added = (Added) o;
+
+            return element.equals(added.element);
+        }
+
+        @Override
+        public int hashCode() {
+            return element.hashCode();
+        }
+
+        @Override
+        public CsmElement getElement() {
+            return element;
+        }
+
+        @Override
+        public boolean isAdded() {
+            return true;
+        }
+    }
+
+    /**
+     * Elements in a CsmMix have been reshuffled. It could also mean that
+     * some new elements have been added or removed to the mix.
+     */
+    private static class Reshuffled implements DifferenceElement {
+        final CsmMix previousOrder;
+        final CsmMix element;
+
+        public Reshuffled(CsmMix previousOrder, CsmMix element) {
+            this.previousOrder = previousOrder;
+            this.element = element;
+        }
+
+        @Override
+        public String toString() {
+            return "Reshuffled{" + element + ", previous="+ previousOrder+ '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Reshuffled that = (Reshuffled) o;
+
+            if (!previousOrder.equals(that.previousOrder)) return false;
+            return element.equals(that.element);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = previousOrder.hashCode();
+            result = 31 * result + element.hashCode();
+            return result;
+        }
+
+        @Override
+        public CsmMix getElement() {
+            return element;
+        }
+
+        @Override
+        public boolean isAdded() {
+            return false;
+        }
+    }
+
+    private static class Kept implements DifferenceElement {
+        final CsmElement element;
+
+        public Kept(CsmElement element) {
+            this.element = element;
+        }
+
+        @Override
+        public String toString() {
+            return "Kept{" + element + '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Kept kept = (Kept) o;
+
+            return element.equals(kept.element);
+        }
+
+        @Override
+        public int hashCode() {
+            return element.hashCode();
+        }
+
+        @Override
+        public CsmElement getElement() {
+            return element;
+        }
+
+        @Override
+        public boolean isAdded() {
+            return false;
+        }
+    }
+
+    private static class Removed implements DifferenceElement {
+        final CsmElement element;
+
+        public Removed(CsmElement element) {
+            this.element = element;
+        }
+
+        @Override
+        public String toString() {
+            return "Removed{" + element + '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Removed removed = (Removed) o;
+
+            return element.equals(removed.element);
+        }
+
+        @Override
+        public int hashCode() {
+            return element.hashCode();
+        }
+
+        @Override
+        public CsmElement getElement() {
+            return element;
+        }
+
+        @Override
+        public boolean isAdded() {
+            return false;
+        }
+    }
+
+    private static boolean matching(CsmElement a, CsmElement b) {
+        if (a instanceof CsmChild) {
+            if (b instanceof CsmChild) {
+                CsmChild childA = (CsmChild) a;
+                CsmChild childB = (CsmChild) b;
+                return childA.getChild().equals(childB.getChild());
+            } else if (b instanceof CsmToken) {
+                return false;
+            } else if (b instanceof CsmIndent) {
+                return false;
+            } else if (b instanceof CsmUnindent) {
+                return false;
+            } else {
+                throw new UnsupportedOperationException(a.getClass().getSimpleName()+ " "+b.getClass().getSimpleName());
+            }
+        } else if (a instanceof CsmToken) {
+            if (b instanceof CsmToken) {
+                CsmToken childA = (CsmToken)a;
+                CsmToken childB = (CsmToken)b;
+                return childA.getTokenType() == childB.getTokenType();
+            } else if (b instanceof CsmChild) {
+                return false;
+            } else if (b instanceof CsmIndent) {
+                return false;
+            } else if (b instanceof CsmUnindent) {
+                return false;
+            } else {
+                throw new UnsupportedOperationException(a.getClass().getSimpleName()+ " "+b.getClass().getSimpleName());
+            }
+        } else if (a instanceof CsmIndent) {
+            return b instanceof CsmIndent;
+        } else if (a instanceof CsmUnindent) {
+            return b instanceof CsmUnindent;
+        }
+        throw new UnsupportedOperationException(a.getClass().getSimpleName()+ " "+b.getClass().getSimpleName());
+    }
+
+    private static boolean replacement(CsmElement a, CsmElement b) {
+        if (a instanceof CsmIndent || b instanceof CsmIndent || a instanceof CsmUnindent || b instanceof CsmUnindent) {
+            return false;
+        }
+        if (a instanceof CsmChild) {
+            if (b instanceof CsmChild) {
+                CsmChild childA = (CsmChild) a;
+                CsmChild childB = (CsmChild) b;
+                return childA.getChild().getClass().equals(childB.getChild().getClass());
+            } else if (b instanceof CsmToken) {
+                return false;
+            } else {
+                throw new UnsupportedOperationException(a.getClass().getSimpleName()+ " "+b.getClass().getSimpleName());
+            }
+        } else if (a instanceof CsmToken) {
+            if (b instanceof CsmToken) {
+                CsmToken childA = (CsmToken)a;
+                CsmToken childB = (CsmToken)b;
+                return childA.getTokenType() == childB.getTokenType();
+            } else if (b instanceof CsmChild) {
+                return false;
+            }
+        }
+        throw new UnsupportedOperationException(a.getClass().getSimpleName()+ " "+b.getClass().getSimpleName());
+    }
+
+    /**
+     * Find the positions of all the given children.
+     */
+    private static Map<Node, Integer> findChildrenPositions(LexicalDifferenceCalculator.CalculatedSyntaxModel calculatedSyntaxModel) {
+        Map<Node, Integer> positions = new HashMap<>();
+        for (int i=0;i<calculatedSyntaxModel.elements.size();i++) {
+            CsmElement element = calculatedSyntaxModel.elements.get(i);
+            if (element instanceof CsmChild) {
+                positions.put(((CsmChild)element).getChild(), i);
+            }
+        }
+        return positions;
+    }
+
+    /**
+     * Calculate the Difference between two CalculatedSyntaxModel elements, determining which elements were kept,
+     * which were added and which were removed.
+     */
+    static Difference calculate(LexicalDifferenceCalculator.CalculatedSyntaxModel original, LexicalDifferenceCalculator.CalculatedSyntaxModel after) {
+        // For performance reasons we use the positions of matching children
+        // to guide the calculation of the difference
+        //
+        // Suppose we have:
+        //   qwerty[A]uiop
+        //   qwer[A]uiop
+        //
+        // with [A] being a child and lowercase letters being tokens
+        //
+        // We would calculate the Difference between "qwerty" and "qwer" then we know the A is kep, and then we
+        // would calculate the difference between "uiop" and "uiop"
+
+        Map<Node, Integer> childrenInOriginal = findChildrenPositions(original);
+        Map<Node, Integer> childrenInAfter = findChildrenPositions(after);
+
+        List<Node> commonChildren = new LinkedList<>(childrenInOriginal.keySet());
+        commonChildren.retainAll(childrenInAfter.keySet());
+        commonChildren.sort(Comparator.comparingInt(childrenInOriginal::get));
+
+        List<DifferenceElement> elements = new LinkedList<>();
+
+        int originalIndex = 0;
+        int afterIndex = 0;
+        int commonChildrenIndex = 0;
+        while (commonChildrenIndex < commonChildren.size()) {
+            Node child = commonChildren.get(commonChildrenIndex++);
+            int posOfNextChildInOriginal = childrenInOriginal.get(child);
+            int posOfNextChildInAfter    = childrenInAfter.get(child);
+            if (originalIndex < posOfNextChildInOriginal || afterIndex < posOfNextChildInAfter) {
+                elements.addAll(calculateImpl(original.sub(originalIndex, posOfNextChildInOriginal), after.sub(afterIndex, posOfNextChildInAfter)).elements);
+            }
+            elements.add(new Kept(new CsmChild(child)));
+            originalIndex = posOfNextChildInOriginal + 1;
+            afterIndex = posOfNextChildInAfter + 1;
+        }
+
+        if (originalIndex < original.elements.size() || afterIndex < after.elements.size()) {
+            elements.addAll(calculateImpl(original.sub(originalIndex, original.elements.size()), after.sub(afterIndex, after.elements.size())).elements);
+        }
+        return new Difference(elements);
+    }
+
+    private static Difference calculateImpl(LexicalDifferenceCalculator.CalculatedSyntaxModel original, LexicalDifferenceCalculator.CalculatedSyntaxModel after) {
+        List<DifferenceElement> elements = new LinkedList<>();
+
+        int originalIndex = 0;
+        int afterIndex = 0;
+
+        // We move through the two CalculatedSyntaxModel, moving both forward when we have a match
+        // and moving just one side forward when we have an element kept or removed
+
+        do {
+            if (originalIndex < original.elements.size() && afterIndex >= after.elements.size()) {
+                elements.add(new Removed(original.elements.get(originalIndex)));
+                originalIndex++;
+            } else if (originalIndex >= original.elements.size() && afterIndex < after.elements.size()) {
+                elements.add(new Added(after.elements.get(afterIndex)));
+                afterIndex++;
+            } else {
+                CsmElement nextOriginal = original.elements.get(originalIndex);
+                CsmElement nextAfter = after.elements.get(afterIndex);
+
+                if ((nextOriginal instanceof CsmMix) && (nextAfter instanceof CsmMix)) {
+                    if (((CsmMix) nextAfter).getElements().equals(((CsmMix) nextOriginal).getElements())) {
+                        // No reason to deal with a reshuffled, we are just going to keep everything as it is
+                        ((CsmMix) nextAfter).getElements().forEach(el -> elements.add(new Kept(el)));
+                    } else {
+                        elements.add(new Reshuffled((CsmMix)nextOriginal, (CsmMix)nextAfter));
+                    }
+                    originalIndex++;
+                    afterIndex++;
+                } else if (matching(nextOriginal, nextAfter)) {
+                    elements.add(new Kept(nextOriginal));
+                    originalIndex++;
+                    afterIndex++;
+                } else if (replacement(nextOriginal, nextAfter)) {
+                    elements.add(new Removed(nextOriginal));
+                    elements.add(new Added(nextAfter));
+                    originalIndex++;
+                    afterIndex++;
+                } else {
+                    // We can try to remove the element or add it and look which one leads to the lower difference
+                    Difference adding = calculate(original.from(originalIndex), after.from(afterIndex + 1));
+                    Difference removing = null;
+                    if (adding.cost() > 0) {
+                        removing = calculate(original.from(originalIndex + 1), after.from(afterIndex));
+                    }
+
+                    if (removing == null || removing.cost() > adding.cost()) {
+                        elements.add(new Added(nextAfter));
+                        afterIndex++;
+                    } else {
+                        elements.add(new Removed(nextOriginal));
+                        originalIndex++;
+                    }
+                }
+            }
+        } while (originalIndex < original.elements.size() || afterIndex < after.elements.size());
+
+        return new Difference(elements);
+    }
+
+    private TextElement toTextElement(CsmElement csmElement) {
+        if (csmElement instanceof CsmChild) {
+            return new ChildTextElement(((CsmChild) csmElement).getChild());
+        } else if (csmElement instanceof CsmToken) {
+            return new TokenTextElement(((CsmToken) csmElement).getTokenType(), ((CsmToken) csmElement).getContent(null));
+        } else {
+            throw new UnsupportedOperationException(csmElement.getClass().getSimpleName());
+        }
+    }
+
+    private List<TextElement> processIndentation(List<TokenTextElement> indentation, List<TextElement> prevElements) {
+        List<TextElement> res = new LinkedList<>();
+        res.addAll(indentation);
+        boolean afterNl = false;
+        for (TextElement e : prevElements) {
+            if (e.isNewline() || e.isToken(SINGLE_LINE_COMMENT)) {
+                res.clear();
+                afterNl = true;
+            } else {
+                if (afterNl && e instanceof TokenTextElement && TokenTypes.isWhitespace(((TokenTextElement)e).getTokenKind())) {
+                    res.add(e);
+                } else {
+                    afterNl = false;
+                }
+            }
+        }
+        return res;
+    }
+
+    private List<TextElement> indentationBlock() {
+        List<TextElement> res = new LinkedList<>();
+        res.add(new TokenTextElement(SPACE));
+        res.add(new TokenTextElement(SPACE));
+        res.add(new TokenTextElement(SPACE));
+        res.add(new TokenTextElement(SPACE));
+        return res;
+    }
+
+    private int considerCleaningTheLine(NodeText nodeText, int nodeTextIndex) {
+        while (nodeTextIndex >=1 && nodeText.getElements().get(nodeTextIndex - 1).isWhiteSpace() && !nodeText.getElements().get(nodeTextIndex - 1).isNewline()) {
+            nodeText.removeElement(nodeTextIndex - 1);
+            nodeTextIndex--;
+        }
+        return nodeTextIndex;
+    }
+
+    private boolean isAfterLBrace(NodeText nodeText, int nodeTextIndex) {
+        if (nodeTextIndex > 0 && nodeText.getElements().get(nodeTextIndex - 1).isToken(LBRACE)) {
+            return true;
+        }
+        if (nodeTextIndex > 0 && nodeText.getElements().get(nodeTextIndex - 1).isWhiteSpace() && !nodeText.getElements().get(nodeTextIndex - 1).isNewline()) {
+            return isAfterLBrace(nodeText, nodeTextIndex - 1);
+        }
+        return false;
+    }
+
+    /**
+     * If we are at the beginning of a line, with just spaces or tabs before us we should force the space to be
+     * the same as the indentation.
+     */
+    private int considerEnforcingIndentation(NodeText nodeText, int nodeTextIndex) {
+        boolean hasOnlyWsBefore = true;
+        for (int i=nodeTextIndex; i >= 0 && hasOnlyWsBefore && i < nodeText.getElements().size(); i--) {
+            if (nodeText.getElements().get(i).isNewline()) {
+                break;
+            }
+            if (!nodeText.getElements().get(i).isSpaceOrTab()) {
+                hasOnlyWsBefore = false;
+            }
+        }
+        if (hasOnlyWsBefore) {
+            for (int i=nodeTextIndex; i >= 0 && i < nodeText.getElements().size(); i--) {
+                if (nodeText.getElements().get(i).isNewline()) {
+                    break;
+                }
+                nodeText.removeElement(i);
+            }
+        }
+        return nodeTextIndex;
+    }
+
+    /**
+     * Node that we have calculate the Difference we can apply to a concrete NodeText, modifying it according
+     * to the difference (adding and removing the elements provided).
+     */
+    void apply(NodeText nodeText, Node node) {
+        if (nodeText == null) {
+            throw new NullPointerException();
+        }
+        boolean addedIndentation = false;
+        List<TokenTextElement> indentation = LexicalPreservingPrinter.findIndentation(node);
+        int diffIndex = 0;
+        int nodeTextIndex = 0;
+        do {
+            if (diffIndex < this.elements.size() && nodeTextIndex >= nodeText.getElements().size()) {
+                DifferenceElement diffEl = elements.get(diffIndex);
+                if (diffEl instanceof Kept) {
+                    Kept kept = (Kept) diffEl;
+                    if (kept.element instanceof CsmToken) {
+                        CsmToken csmToken = (CsmToken) kept.element;
+                        if (TokenTypes.isWhitespaceOrComment(csmToken.getTokenType())) {
+                            diffIndex++;
+                        } else {
+                            throw new IllegalStateException("Cannot keep element because we reached the end of nodetext: "
+                                    + nodeText + ". Difference: " + this);
+                        }
+                    } else {
+                        throw new IllegalStateException("Cannot keep element because we reached the end of nodetext: "
+                                + nodeText + ". Difference: " + this);
+                    }
+                } else if (diffEl instanceof Added) {
+                    nodeText.addElement(nodeTextIndex, toTextElement(((Added) diffEl).element));
+                    nodeTextIndex++;
+                    diffIndex++;
+                } else {
+                    throw new UnsupportedOperationException(diffEl.getClass().getSimpleName());
+                }
+            } else if (diffIndex >= this.elements.size() && nodeTextIndex < nodeText.getElements().size()) {
+                TextElement nodeTextEl = nodeText.getElements().get(nodeTextIndex);
+                if (nodeTextEl.isWhiteSpaceOrComment()) {
+                    nodeTextIndex++;
+                } else {
+                    throw new UnsupportedOperationException("NodeText: " + nodeText + ". Difference: "
+                            + this + " " + nodeTextEl);
+                }
+            } else {
+                DifferenceElement diffEl = elements.get(diffIndex);
+                TextElement nodeTextEl = nodeText.getElements().get(nodeTextIndex);
+                if (diffEl instanceof Added) {
+                    CsmElement addedElement = ((Added) diffEl).element;
+                    if (addedElement instanceof CsmIndent) {
+                        for (int i=0;i<STANDARD_INDENTATION_SIZE;i++){
+                            indentation.add(new TokenTextElement(GeneratedJavaParserConstants.SPACE));
+                        }
+                        addedIndentation = true;
+                        diffIndex++;
+                        continue;
+                    }
+                    if (addedElement instanceof CsmUnindent) {
+                        for (int i=0;i<STANDARD_INDENTATION_SIZE && !indentation.isEmpty();i++){
+                            indentation.remove(indentation.size() - 1);
+                        }
+                        addedIndentation = false;
+                        diffIndex++;
+                        continue;
+                    }
+                    TextElement textElement = toTextElement(addedElement);
+                    boolean used = false;
+                    if (nodeTextIndex > 0 && nodeText.getElements().get(nodeTextIndex - 1).isNewline()) {
+                        for (TextElement e : processIndentation(indentation, nodeText.getElements().subList(0, nodeTextIndex - 1))) {
+                            nodeText.addElement(nodeTextIndex++, e);
+                        }
+                    } else if (isAfterLBrace(nodeText, nodeTextIndex) && !isAReplacement(diffIndex)) {
+                        if (textElement.isNewline()) {
+                            used = true;
+                        }
+                        nodeText.addElement(nodeTextIndex++, new TokenTextElement(TokenTypes.eolTokenKind()));
+                        // This remove the space in "{ }" when adding a new line
+                        while (nodeText.getElements().get(nodeTextIndex).isSpaceOrTab()) {
+                            nodeText.getElements().remove(nodeTextIndex);
+                        }
+                        for (TextElement e : processIndentation(indentation, nodeText.getElements().subList(0, nodeTextIndex - 1))) {
+                            nodeText.addElement(nodeTextIndex++, e);
+                        }
+                        // Indentation is painful...
+                        // Sometimes we want to force indentation: this is the case when indentation was expected but
+                        // was actually not there. For example if we have "{ }" we would expect indentation but it is
+                        // not there, so when adding new elements we force it. However if the indentation has been
+                        // inserted by us in this transformation we do not want to insert it again
+                        if (!addedIndentation) {
+                            for (TextElement e : indentationBlock()) {
+                                nodeText.addElement(nodeTextIndex++, e);
+                            }
+                        }
+                    }
+                    if (!used) {
+                        nodeText.addElement(nodeTextIndex, textElement);
+                        nodeTextIndex++;
+                    }
+                    if (textElement.isNewline()) {
+                        boolean followedByUnindent = (diffIndex + 1) < elements.size()
+                                && elements.get(diffIndex + 1).isAdded()
+                                && elements.get(diffIndex + 1).getElement() instanceof CsmUnindent;
+                        nodeTextIndex = adjustIndentation(indentation, nodeText, nodeTextIndex, followedByUnindent/* && !addedIndentation*/);
+                    }
+                    diffIndex++;
+                } else if (diffEl instanceof Kept) {
+                    Kept kept = (Kept)diffEl;
+                    if (nodeTextEl.isComment()) {
+                        nodeTextIndex++;
+                    } else if ((kept.element instanceof CsmChild) && nodeTextEl instanceof ChildTextElement) {
+                        diffIndex++;
+                        nodeTextIndex++;
+                    } else if ((kept.element instanceof CsmChild) && nodeTextEl instanceof TokenTextElement) {
+                        if (nodeTextEl.isWhiteSpaceOrComment()) {
+                            nodeTextIndex++;
+                        } else {
+                            if (kept.element instanceof CsmChild) {
+                                CsmChild keptChild = (CsmChild)kept.element;
+                                if (keptChild.getChild() instanceof PrimitiveType) {
+                                    nodeTextIndex++;
+                                    diffIndex++;
+                                } else {
+                                    throw new UnsupportedOperationException("kept " + kept.element + " vs " + nodeTextEl);
+                                }
+                            } else {
+                                throw new UnsupportedOperationException("kept " + kept.element + " vs " + nodeTextEl);
+                            }
+                        }
+                    } else if ((kept.element instanceof CsmToken) && nodeTextEl instanceof TokenTextElement) {
+                        CsmToken csmToken = (CsmToken) kept.element;
+                        TokenTextElement nodeTextToken = (TokenTextElement) nodeTextEl;
+                        if (csmToken.getTokenType() == nodeTextToken.getTokenKind()) {
+                            nodeTextIndex++;
+                            diffIndex++;
+                        } else if (TokenTypes.isWhitespaceOrComment(csmToken.getTokenType())) {
+                            diffIndex++;
+                        } else if (nodeTextToken.isWhiteSpaceOrComment()) {
+                            nodeTextIndex++;
+                        } else {
+                            throw new UnsupportedOperationException("Csm token " + csmToken + " NodeText TOKEN " + nodeTextToken);
+                        }
+                    } else if ((kept.element instanceof CsmToken) && ((CsmToken) kept.element).isWhiteSpace()) {
+                        diffIndex++;
+                    } else if (kept.element instanceof CsmIndent) {
+                        // Nothing to do
+                        diffIndex++;
+                    } else if (kept.element instanceof CsmUnindent) {
+                        // Nothing to do, beside considering indentation
+                        diffIndex++;
+                        for (int i = 0; i < STANDARD_INDENTATION_SIZE && nodeTextIndex >= 1 && nodeText.getTextElement(nodeTextIndex - 1).isSpaceOrTab(); i++) {
+                            nodeText.removeElement(--nodeTextIndex);
+                        }
+                    } else {
+                        throw new UnsupportedOperationException("kept " + kept.element + " vs " + nodeTextEl);
+                    }
+                } else if (diffEl instanceof Removed) {
+                    Removed removed = (Removed)diffEl;
+                    if ((removed.element instanceof CsmChild) && nodeTextEl instanceof ChildTextElement) {
+                        ChildTextElement actualChild = (ChildTextElement)nodeTextEl;
+                        if (actualChild.isComment()) {
+                            CsmChild csmChild = (CsmChild)removed.element;
+                            // We expected to remove a proper node but we found a comment in between.
+                            // If the comment is associated to the node we want to remove we remove it as well, otherwise we keep it
+                            Comment comment = (Comment)actualChild.getChild();
+                            if (!comment.isOrphan() && comment.getCommentedNode().isPresent() && comment.getCommentedNode().get().equals(csmChild.getChild())) {
+                                nodeText.removeElement(nodeTextIndex);
+                            } else {
+                                nodeTextIndex++;
+                            }
+                        } else {
+                            nodeText.removeElement(nodeTextIndex);
+                            if (nodeTextIndex < nodeText.getElements().size() && nodeText.getElements().get(nodeTextIndex).isNewline()) {
+                                nodeTextIndex = considerCleaningTheLine(nodeText, nodeTextIndex);
+                            } else {
+                                if (diffIndex + 1 >= this.getElements().size() || !(this.getElements().get(diffIndex + 1) instanceof Added)) {
+                                    nodeTextIndex = considerEnforcingIndentation(nodeText, nodeTextIndex);
+                                }
+                                // If in front we have one space and before also we had space let's drop one space
+                                if (nodeText.getElements().size() > nodeTextIndex && nodeTextIndex > 0) {
+                                    if (nodeText.getElements().get(nodeTextIndex).isWhiteSpace()
+                                            && nodeText.getElements().get(nodeTextIndex - 1).isWhiteSpace()) {
+                                        // However we do not want to do that when we are about to adding or removing elements
+                                        if ((diffIndex + 1) == this.elements.size() || (elements.get(diffIndex + 1) instanceof Kept)) {
+                                            nodeText.getElements().remove(nodeTextIndex--);
+                                        }
+                                    }
+                                }
+                            }
+                            diffIndex++;
+                        }
+                    } else if ((removed.element instanceof CsmToken) && nodeTextEl instanceof TokenTextElement
+                            && ((CsmToken)removed.element).getTokenType() == ((TokenTextElement)nodeTextEl).getTokenKind()) {
+                        nodeText.removeElement(nodeTextIndex);
+                        diffIndex++;
+                    } else if (nodeTextEl instanceof TokenTextElement
+                            && nodeTextEl.isWhiteSpaceOrComment()) {
+                        nodeTextIndex++;
+                    } else if (removed.element instanceof CsmChild
+                            && ((CsmChild)removed.element).getChild() instanceof PrimitiveType) {
+                        if (isPrimitiveType(nodeTextEl)) {
+                            nodeText.removeElement(nodeTextIndex);
+                            diffIndex++;
+                        } else {
+                            throw new UnsupportedOperationException("removed " + removed.element + " vs " + nodeTextEl);
+                        }
+                    } else if (removed.element instanceof CsmToken && ((CsmToken)removed.element).isWhiteSpace()) {
+                        diffIndex++;
+                    } else if (nodeTextEl.isWhiteSpace()) {
+                        nodeTextIndex++;
+                    } else {
+                        throw new UnsupportedOperationException("removed " + removed.element + " vs " + nodeTextEl);
+                    }
+                } else if (diffEl instanceof Reshuffled) {
+
+                    // First, let's see how many tokens we need to attribute to the previous version of the of the CsmMix
+                    Reshuffled reshuffled = (Reshuffled)diffEl;
+                    CsmMix elementsFromPreviousOrder = reshuffled.previousOrder;
+                    CsmMix elementsFromNextOrder = reshuffled.element;
+
+                    // This contains indexes from elementsFromNextOrder to indexes from elementsFromPreviousOrder
+                    Map<Integer, Integer> correspondanceBetweenNextOrderAndPreviousOrder = new HashMap<>();
+                    for (int ni=0;ni<elementsFromNextOrder.getElements().size();ni++) {
+                        boolean found = false;
+                        CsmElement ne = elementsFromNextOrder.getElements().get(ni);
+                        for (int pi=0;pi<elementsFromPreviousOrder.getElements().size() && !found;pi++) {
+                            CsmElement pe = elementsFromPreviousOrder.getElements().get(pi);
+                            if (!correspondanceBetweenNextOrderAndPreviousOrder.values().contains(pi)
+                                    && matching(ne, pe)) {
+                                found = true;
+                                correspondanceBetweenNextOrderAndPreviousOrder.put(ni, pi);
+                            }
+                        }
+                    }
+
+                    // We now find out which Node Text elements corresponds to the elements in the original CSM
+                    final int startNodeTextIndex = nodeTextIndex;
+                    final Set<Integer> usedIndexes = new HashSet<>();
+                    List<Integer> nodeTextIndexOfPreviousElements = elementsFromPreviousOrder.getElements().stream()
+                            .map(it -> findIndexOfCorrespondingNodeTextElement(it, nodeText, startNodeTextIndex, usedIndexes, node))
+                            .collect(Collectors.toList());
+                    Map<Integer, Integer> nodeTextIndexToPreviousCSMIndex = new HashMap<>();
+                    for (int i=0;i<nodeTextIndexOfPreviousElements.size();i++) {
+                        int value = nodeTextIndexOfPreviousElements.get(i);
+                        if (value != -1) {
+                            nodeTextIndexToPreviousCSMIndex.put(value, i);
+                        }
+                    }
+                    int lastNodeTextIndex = nodeTextIndexOfPreviousElements.stream().max(Integer::compareTo).orElse(-1);
+
+                    // Elements to be added at the end
+                    List<CsmElement> elementsToBeAddedAtTheEnd = new LinkedList<>();
+                    Map<Integer, List<CsmElement>> elementsToAddBeforeGivenOriginalCSMElement = new HashMap<>();
+                    for (int ni=0;ni<elementsFromNextOrder.getElements().size();ni++) {
+                        // If it has a mapping, then it is kept
+                        if (!correspondanceBetweenNextOrderAndPreviousOrder.containsKey(ni)) {
+                            // Ok, it is something new. Where to put it? Let's see what is the first following
+                            // element that has a mapping
+                            int originalCsmIndex = -1;
+                            for (int nj=ni + 1;nj<elementsFromNextOrder.getElements().size() && originalCsmIndex==-1;nj++) {
+                                if (correspondanceBetweenNextOrderAndPreviousOrder.containsKey(nj)) {
+                                    originalCsmIndex = correspondanceBetweenNextOrderAndPreviousOrder.get(nj);
+                                    if (!elementsToAddBeforeGivenOriginalCSMElement.containsKey(originalCsmIndex)){
+                                        elementsToAddBeforeGivenOriginalCSMElement.put(originalCsmIndex, new LinkedList<>());
+                                    }
+                                    elementsToAddBeforeGivenOriginalCSMElement.get(originalCsmIndex).add(elementsFromNextOrder.getElements().get(ni));
+                                }
+                            }
+                            // it does not preceed anything, so it goes at the end
+                            if (originalCsmIndex == -1) {
+                                elementsToBeAddedAtTheEnd.add(elementsFromNextOrder.getElements().get(ni));
+                            }
+                        }
+                    }
+
+                    // We go over the original node text elements, in the order they appear in the NodeText.
+                    // Considering an original node text element (ONE)
+                    // * we verify if it corresponds to a CSM element. If it does not we just move on, otherwise
+                    //   we find the correspond OCE (Original CSM Element)
+                    // * we first add new elements that are marked to be added before OCE
+                    // * if OCE is marked to be present also in the "after" CSM we add a kept element,
+                    //   otherwise we add a removed element
+
+                    this.getElements().remove(diffIndex);
+                    int diffElIterator = diffIndex;
+                    if (lastNodeTextIndex != -1) {
+                        for (int ntIndex = startNodeTextIndex; ntIndex<=lastNodeTextIndex; ntIndex++) {
+
+                            if (nodeTextIndexToPreviousCSMIndex.containsKey(ntIndex)) {
+                                int indexOfOriginalCSMElement = nodeTextIndexToPreviousCSMIndex.get(ntIndex);
+                                if (elementsToAddBeforeGivenOriginalCSMElement.containsKey(indexOfOriginalCSMElement)) {
+                                    for (CsmElement elementToAdd : elementsToAddBeforeGivenOriginalCSMElement.get(indexOfOriginalCSMElement)) {
+                                        elements.add(diffElIterator++, new Added(elementToAdd));
+                                    }
+                                }
+
+                                CsmElement originalCSMElement = elementsFromPreviousOrder.getElements().get(indexOfOriginalCSMElement);
+                                boolean toBeKept = correspondanceBetweenNextOrderAndPreviousOrder.containsValue(indexOfOriginalCSMElement);
+                                if (toBeKept) {
+                                    elements.add(diffElIterator++, new Kept(originalCSMElement));
+                                } else {
+                                    elements.add(diffElIterator++, new Removed(originalCSMElement));
+                                }
+                            }
+                            // else we have a simple node text element, without associated csm element, just keep ignore it
+                        }
+                    }
+
+                    // Finally we look for the remaining new elements that were not yet added and
+                    // add all of them
+                    for (CsmElement elementToAdd : elementsToBeAddedAtTheEnd) {
+                        elements.add(diffElIterator++, new Added(elementToAdd));
+                    }
+                } else {
+                    throw new UnsupportedOperationException("" + diffEl + " vs " + nodeTextEl);
+                }
+            }
+        } while (diffIndex < this.elements.size() || nodeTextIndex < nodeText.getElements().size());
+    }
+
+    private int findIndexOfCorrespondingNodeTextElement(CsmElement csmElement, NodeText nodeText, int startIndex, Set<Integer> usedIndexes, Node node) {
+        for (int i=startIndex;i<nodeText.getElements().size();i++){
+            if (!usedIndexes.contains(i)) {
+                TextElement textElement = nodeText.getTextElement(i);
+                if (csmElement instanceof CsmToken) {
+                    CsmToken csmToken = (CsmToken)csmElement;
+                    if (textElement instanceof TokenTextElement) {
+                        TokenTextElement tokenTextElement = (TokenTextElement)textElement;
+                        if (tokenTextElement.getTokenKind() == csmToken.getTokenType() && tokenTextElement.getText().equals(csmToken.getContent(node))) {
+                            usedIndexes.add(i);
+                            return i;
+                        }
+                    }
+                } else if (csmElement instanceof CsmChild) {
+                    CsmChild csmChild = (CsmChild)csmElement;
+                    if (textElement instanceof ChildTextElement) {
+                        ChildTextElement childTextElement = (ChildTextElement)textElement;
+                        if (childTextElement.getChild() == csmChild.getChild()) {
+                            usedIndexes.add(i);
+                            return i;
+                        }
+                    }
+                } else {
+                    throw new UnsupportedOperationException();
+                }
+            }
+        }
+        return -1;
+    }
+
+    private int adjustIndentation(List<TokenTextElement> indentation, NodeText nodeText, int nodeTextIndex, boolean followedByUnindent) {
+        List<TextElement> indentationAdj = processIndentation(indentation, nodeText.getElements().subList(0, nodeTextIndex - 1));
+        if (nodeTextIndex < nodeText.getElements().size() && nodeText.getElements().get(nodeTextIndex).isToken(RBRACE)) {
+            indentationAdj = indentationAdj.subList(0, indentationAdj.size() - Math.min(STANDARD_INDENTATION_SIZE, indentationAdj.size()));
+        } else if (followedByUnindent) {
+            indentationAdj = indentationAdj.subList(0, Math.max(0, indentationAdj.size() - STANDARD_INDENTATION_SIZE));
+        }
+        for (TextElement e : indentationAdj) {
+            if ((nodeTextIndex<nodeText.getElements().size()) && nodeText.getElements().get(nodeTextIndex).isSpaceOrTab()) {
+                nodeTextIndex++;
+            } else {
+                nodeText.getElements().add(nodeTextIndex++, e);
+            }
+        }
+        return nodeTextIndex;
+    }
+
+    private boolean isAReplacement(int diffIndex) {
+        return (diffIndex > 0) && getElements().get(diffIndex) instanceof Added && getElements().get(diffIndex - 1) instanceof Removed;
+    }
+
+    private boolean isPrimitiveType(TextElement textElement) {
+        if (textElement instanceof TokenTextElement) {
+            TokenTextElement tokenTextElement = (TokenTextElement)textElement;
+            int tokenKind = tokenTextElement.getTokenKind();
+            return tokenKind == BYTE
+                || tokenKind == CHAR
+                || tokenKind == SHORT
+                || tokenKind == INT
+                || tokenKind == LONG
+                || tokenKind == FLOAT
+                || tokenKind == DOUBLE;
+        } else {
+            return false;
+        }
+    }
+
+    private long cost() {
+        return elements.stream().filter(e -> !(e instanceof Kept)).count();
+    }
+
+    @Override
+    public String toString() {
+        return "Difference{" + elements + '}';
+    }
+
+    public List<DifferenceElement> getElements() {
+        return elements;
+    }
+
+    /**
+     * Remove from the difference all the elements related to indentation.
+     * This is mainly intended for test purposes.
+     */
+    void removeIndentationElements() {
+        elements.removeIf(el -> el.getElement() instanceof CsmIndent || el.getElement() instanceof CsmUnindent);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalDifferenceCalculator.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalDifferenceCalculator.java
new file mode 100644
index 0000000..9263dfd
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalDifferenceCalculator.java
@@ -0,0 +1,332 @@
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import com.github.javaparser.printer.Printable;
+import com.github.javaparser.printer.SourcePrinter;
+import com.github.javaparser.printer.concretesyntaxmodel.*;
+import com.github.javaparser.printer.lexicalpreservation.changes.*;
+
+import java.util.*;
+
+class LexicalDifferenceCalculator {
+
+    /**
+     * The ConcreteSyntaxModel represents the general format. This model is a calculated version of the ConcreteSyntaxModel,
+     * with no condition, no lists, just tokens and node children.
+     */
+    static class CalculatedSyntaxModel {
+        final List<CsmElement> elements;
+
+        CalculatedSyntaxModel(List<CsmElement> elements) {
+            this.elements = elements;
+        }
+
+        public CalculatedSyntaxModel from(int index) {
+            List<CsmElement> newList = new LinkedList<>();
+            newList.addAll(elements.subList(index, elements.size()));
+            return new CalculatedSyntaxModel(newList);
+        }
+
+        @Override
+        public String toString() {
+            return "CalculatedSyntaxModel{" +
+                    "elements=" + elements +
+                    '}';
+        }
+
+        CalculatedSyntaxModel sub(int start, int end) {
+            return new CalculatedSyntaxModel(elements.subList(start, end));
+        }
+
+        void removeIndentationElements() {
+            elements.removeIf(el -> el instanceof CsmIndent || el instanceof CsmUnindent);
+        }
+    }
+
+    static class CsmChild implements CsmElement {
+        private final Node child;
+
+        public Node getChild() {
+            return child;
+        }
+
+        CsmChild(Node child) {
+            this.child = child;
+        }
+
+        @Override
+        public void prettyPrint(Node node, SourcePrinter printer) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String toString() {
+            return "child(" + child.getClass().getSimpleName()+")";
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            CsmChild csmChild = (CsmChild) o;
+
+            return child.equals(csmChild.child);
+        }
+
+        @Override
+        public int hashCode() {
+            return child.hashCode();
+        }
+    }
+
+    Difference calculateListRemovalDifference(ObservableProperty observableProperty, NodeList nodeList, int index) {
+        Node container = nodeList.getParentNodeForChildren();
+        CsmElement element = ConcreteSyntaxModel.forClass(container.getClass());
+        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(element, container);
+        CalculatedSyntaxModel after = calculatedSyntaxModelAfterListRemoval(element, observableProperty, nodeList, index);
+        return Difference.calculate(original, after);
+    }
+
+    Difference calculateListAdditionDifference(ObservableProperty observableProperty, NodeList nodeList, int index, Node nodeAdded) {
+        Node container = nodeList.getParentNodeForChildren();
+        CsmElement element = ConcreteSyntaxModel.forClass(container.getClass());
+        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(element, container);
+        CalculatedSyntaxModel after = calculatedSyntaxModelAfterListAddition(element, observableProperty, nodeList, index, nodeAdded);
+        return Difference.calculate(original, after);
+    }
+
+    Difference calculateListReplacementDifference(ObservableProperty observableProperty, NodeList nodeList, int index, Node newValue) {
+        Node container = nodeList.getParentNodeForChildren();
+        CsmElement element = ConcreteSyntaxModel.forClass(container.getClass());
+        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(element, container);
+        CalculatedSyntaxModel after = calculatedSyntaxModelAfterListReplacement(element, observableProperty, nodeList, index, newValue);
+        return Difference.calculate(original, after);
+    }
+
+    public void calculatePropertyChange(NodeText nodeText, Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+        if (nodeText == null) {
+            throw new NullPointerException();
+        }
+        CsmElement element = ConcreteSyntaxModel.forClass(observedNode.getClass());
+        CalculatedSyntaxModel original = calculatedSyntaxModelForNode(element, observedNode);
+        CalculatedSyntaxModel after = calculatedSyntaxModelAfterPropertyChange(element, observedNode, property, oldValue, newValue);
+        Difference difference = Difference.calculate(original, after);
+        difference.apply(nodeText, observedNode);
+    }
+
+    // Visible for testing
+    CalculatedSyntaxModel calculatedSyntaxModelForNode(CsmElement csm, Node node) {
+        List<CsmElement> elements = new LinkedList<>();
+        calculatedSyntaxModelForNode(csm, node, elements, new NoChange());
+        return new CalculatedSyntaxModel(elements);
+    }
+
+    CalculatedSyntaxModel calculatedSyntaxModelForNode(Node node) {
+        return calculatedSyntaxModelForNode(ConcreteSyntaxModel.forClass(node.getClass()), node);
+    }
+
+    private void calculatedSyntaxModelForNode(CsmElement csm, Node node, List<CsmElement> elements, Change change) {
+        if (csm instanceof CsmSequence) {
+            CsmSequence csmSequence = (CsmSequence) csm;
+            csmSequence.getElements().forEach(e -> calculatedSyntaxModelForNode(e, node, elements, change));
+        } else if (csm instanceof CsmComment) {
+            // nothing to do
+        } else if (csm instanceof CsmSingleReference) {
+            CsmSingleReference csmSingleReference = (CsmSingleReference)csm;
+            Node child;
+            if (change instanceof PropertyChange && ((PropertyChange)change).getProperty() == csmSingleReference.getProperty()) {
+                child = (Node)((PropertyChange)change).getNewValue();
+            } else {
+                child = csmSingleReference.getProperty().getValueAsSingleReference(node);
+            }
+            if (child != null) {
+                elements.add(new CsmChild(child));
+            }
+        } else if (csm instanceof CsmNone) {
+            // nothing to do
+        } else if (csm instanceof CsmToken) {
+            elements.add(csm);
+        } else if (csm instanceof CsmOrphanCommentsEnding) {
+            // nothing to do
+        } else if (csm instanceof CsmList) {
+            CsmList csmList = (CsmList) csm;
+            if (csmList.getProperty().isAboutNodes()) {
+                Object rawValue = change.getValue(csmList.getProperty(), node);
+                NodeList nodeList;
+                if (rawValue instanceof Optional) {
+                    Optional optional = (Optional)rawValue;
+                    if (optional.isPresent()) {
+                        if (!(optional.get() instanceof NodeList)) {
+                            throw new IllegalStateException("Expected NodeList, found " + optional.get().getClass().getCanonicalName());
+                        }
+                        nodeList = (NodeList) optional.get();
+                    } else {
+                        nodeList = new NodeList();
+                    }
+                } else {
+                    if (!(rawValue instanceof NodeList)) {
+                        throw new IllegalStateException("Expected NodeList, found " + rawValue.getClass().getCanonicalName());
+                    }
+                    nodeList = (NodeList) rawValue;
+                }
+                if (!nodeList.isEmpty()) {
+                    calculatedSyntaxModelForNode(csmList.getPreceeding(), node, elements, change);
+                    for (int i = 0; i < nodeList.size(); i++) {
+                        if (i != 0) {
+                            calculatedSyntaxModelForNode(csmList.getSeparatorPre(), node, elements, change);
+                        }
+                        elements.add(new CsmChild(nodeList.get(i)));
+                        if (i != (nodeList.size() - 1)) {
+                            calculatedSyntaxModelForNode(csmList.getSeparatorPost(), node, elements, change);
+                        }
+
+                    }
+                    calculatedSyntaxModelForNode(csmList.getFollowing(), node, elements, change);
+                }
+            } else {
+                Collection collection = (Collection) change.getValue(csmList.getProperty(), node);
+                if (!collection.isEmpty()) {
+                    calculatedSyntaxModelForNode(csmList.getPreceeding(), node, elements, change);
+
+                    boolean first = true;
+                    for (Iterator it = collection.iterator(); it.hasNext(); ) {
+                        if (!first) {
+                            calculatedSyntaxModelForNode(csmList.getSeparatorPre(), node, elements, change);
+                        }
+                        Object value = it.next();
+                        if (value instanceof Modifier) {
+                            Modifier modifier = (Modifier)value;
+                            elements.add(new CsmToken(toToken(modifier)));
+                        } else {
+                            throw new UnsupportedOperationException(it.next().getClass().getSimpleName());
+                        }
+                        if (it.hasNext()) {
+                            calculatedSyntaxModelForNode(csmList.getSeparatorPost(), node, elements, change);
+                        }
+                        first = false;
+                    }
+                    calculatedSyntaxModelForNode(csmList.getFollowing(), node, elements, change);
+                }
+            }
+        } else if (csm instanceof CsmConditional) {
+            CsmConditional csmConditional = (CsmConditional) csm;
+            boolean satisfied = change.evaluate(csmConditional, node);
+            if (satisfied) {
+                calculatedSyntaxModelForNode(csmConditional.getThenElement(), node, elements, change);
+            } else {
+                calculatedSyntaxModelForNode(csmConditional.getElseElement(), node, elements, change);
+            }
+        } else if (csm instanceof CsmIndent) {
+            elements.add(csm);
+        } else if (csm instanceof CsmUnindent) {
+            elements.add(csm);
+        } else if (csm instanceof CsmAttribute) {
+            CsmAttribute csmAttribute = (CsmAttribute) csm;
+            Object value = change.getValue(csmAttribute.getProperty(), node);
+            String text = value.toString();
+            if (value instanceof Printable) {
+                text = ((Printable) value).asString();
+            }
+            elements.add(new CsmToken(csmAttribute.getTokenType(node, value.toString()), text));
+        } else if ((csm instanceof CsmString) && (node instanceof StringLiteralExpr)) {
+            elements.add(new CsmToken(GeneratedJavaParserConstants.STRING_LITERAL,
+                    "\"" + ((StringLiteralExpr) node).getValue() + "\""));
+        } else if (csm instanceof CsmMix) {
+            CsmMix csmMix = (CsmMix)csm;
+            List<CsmElement> mixElements = new LinkedList<>();
+            csmMix.getElements().forEach(e -> calculatedSyntaxModelForNode(e, node, mixElements, change));
+            elements.add(new CsmMix(mixElements));
+        } else {
+            throw new UnsupportedOperationException(csm.getClass().getSimpleName()+ " " + csm);
+        }
+    }
+
+    private int toToken(Modifier modifier) {
+        switch (modifier) {
+            case PUBLIC:
+                return GeneratedJavaParserConstants.PUBLIC;
+            case PRIVATE:
+                return GeneratedJavaParserConstants.PRIVATE;
+            case PROTECTED:
+                return GeneratedJavaParserConstants.PROTECTED;
+            case STATIC:
+                return GeneratedJavaParserConstants.STATIC;
+            case FINAL:
+                return GeneratedJavaParserConstants.FINAL;
+            case ABSTRACT:
+                return GeneratedJavaParserConstants.ABSTRACT;
+            default:
+                throw new UnsupportedOperationException(modifier.name());
+        }
+    }
+
+    ///
+    /// Methods that calculate CalculatedSyntaxModel
+    ///
+
+    // Visible for testing
+    CalculatedSyntaxModel calculatedSyntaxModelAfterPropertyChange(Node node, ObservableProperty property, Object oldValue, Object newValue) {
+        return calculatedSyntaxModelAfterPropertyChange(ConcreteSyntaxModel.forClass(node.getClass()), node, property, oldValue, newValue);
+    }
+
+    // Visible for testing
+    CalculatedSyntaxModel calculatedSyntaxModelAfterPropertyChange(CsmElement csm, Node node, ObservableProperty property, Object oldValue, Object newValue) {
+        List<CsmElement> elements = new LinkedList<>();
+        calculatedSyntaxModelForNode(csm, node, elements, new PropertyChange(property, oldValue, newValue));
+        return new CalculatedSyntaxModel(elements);
+    }
+
+    // Visible for testing
+    CalculatedSyntaxModel calculatedSyntaxModelAfterListRemoval(CsmElement csm, ObservableProperty observableProperty, NodeList nodeList, int index) {
+        List<CsmElement> elements = new LinkedList<>();
+        Node container = nodeList.getParentNodeForChildren();
+        calculatedSyntaxModelForNode(csm, container, elements, new ListRemovalChange(observableProperty, index));
+        return new CalculatedSyntaxModel(elements);
+    }
+
+    // Visible for testing
+    CalculatedSyntaxModel calculatedSyntaxModelAfterListAddition(CsmElement csm, ObservableProperty observableProperty, NodeList nodeList, int index, Node nodeAdded) {
+        List<CsmElement> elements = new LinkedList<>();
+        Node container = nodeList.getParentNodeForChildren();
+        calculatedSyntaxModelForNode(csm, container, elements, new ListAdditionChange(observableProperty, index, nodeAdded));
+        return new CalculatedSyntaxModel(elements);
+    }
+
+    // Visible for testing
+    CalculatedSyntaxModel calculatedSyntaxModelAfterListAddition(Node container, ObservableProperty observableProperty, int index, Node nodeAdded) {
+        CsmElement csm = ConcreteSyntaxModel.forClass(container.getClass());
+        Object rawValue = observableProperty.getRawValue(container);
+        if (!(rawValue instanceof NodeList)) {
+            throw new IllegalStateException("Expected NodeList, found " + rawValue.getClass().getCanonicalName());
+        }
+        NodeList nodeList = (NodeList)rawValue;
+        return calculatedSyntaxModelAfterListAddition(csm, observableProperty, nodeList, index, nodeAdded);
+    }
+
+    // Visible for testing
+    CalculatedSyntaxModel calculatedSyntaxModelAfterListRemoval(Node container, ObservableProperty observableProperty, int index) {
+        CsmElement csm = ConcreteSyntaxModel.forClass(container.getClass());
+        Object rawValue = observableProperty.getRawValue(container);
+        if (!(rawValue instanceof NodeList)) {
+            throw new IllegalStateException("Expected NodeList, found " + rawValue.getClass().getCanonicalName());
+        }
+        NodeList nodeList = (NodeList)rawValue;
+        return calculatedSyntaxModelAfterListRemoval(csm, observableProperty, nodeList, index);
+    }
+
+    // Visible for testing
+    private CalculatedSyntaxModel calculatedSyntaxModelAfterListReplacement(CsmElement csm, ObservableProperty observableProperty, NodeList nodeList, int index, Node newValue) {
+        List<CsmElement> elements = new LinkedList<>();
+        Node container = nodeList.getParentNodeForChildren();
+        calculatedSyntaxModelForNode(csm, container, elements, new ListReplacementChange(observableProperty, index, newValue));
+        return new CalculatedSyntaxModel(elements);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java
new file mode 100644
index 0000000..ef647fb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinter.java
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.*;
+import com.github.javaparser.ast.DataKey;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.observer.AstObserver;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.observer.PropagatingAstObserver;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.ast.visitor.TreeVisitor;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmElement;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmMix;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmToken;
+import com.github.javaparser.utils.Pair;
+import com.github.javaparser.utils.Utils;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.*;
+import static com.github.javaparser.TokenTypes.eolTokenKind;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static com.github.javaparser.utils.Utils.decapitalize;
+import static java.util.Comparator.*;
+
+/**
+ * A Lexical Preserving Printer is used to capture all the lexical information while parsing, update them when
+ * operating on the AST and then used them to reproduce the source code
+ * in its original formatting including the AST changes.
+ */
+public class LexicalPreservingPrinter {
+
+    /**
+     * The nodetext for a node is stored in the node's data field. This is the key to set and retrieve it.
+     */
+    public static final DataKey<NodeText> NODE_TEXT_DATA = new DataKey<NodeText>() {
+    };
+
+    //
+    // Factory methods
+    //
+
+    /**
+     * Parse the code and setup the LexicalPreservingPrinter.
+     *
+     * @deprecated use setup(Node) and the static methods on this class.
+     */
+    public static <N extends Node> Pair<ParseResult<N>, LexicalPreservingPrinter> setup(ParseStart<N> parseStart,
+                                                                                        Provider provider) {
+        ParseResult<N> parseResult = new JavaParser().parse(parseStart, provider);
+        if (!parseResult.isSuccessful()) {
+            throw new RuntimeException("Parsing failed, unable to setup the lexical preservation printer: "
+                    + parseResult.getProblems());
+        }
+        LexicalPreservingPrinter lexicalPreservingPrinter = new LexicalPreservingPrinter(parseResult.getResult().get());
+        return new Pair<>(parseResult, lexicalPreservingPrinter);
+    }
+
+    /**
+     * Prepares the node so it can be used in the print methods.
+     * The correct order is:
+     * <ol>
+     * <li>Parse some code</li>
+     * <li>Call this setup method on the result</li>
+     * <li>Make changes to the AST as desired</li>
+     * <li>Use one of the print methods on this class to print out the original source code with your changes added</li>
+     * </ol>
+     *
+     * @return the node passed as a parameter for your convenience.
+     */
+    public static <N extends Node> N setup(N node) {
+        assertNotNull(node);
+
+        node.getTokenRange().ifPresent(r -> {
+            storeInitialText(node);
+
+            // Setup observer
+            AstObserver observer = createObserver();
+
+            node.registerForSubtree(observer);
+        });
+        return node;
+    }
+
+    //
+    // Constructor and setup
+    //
+
+    /**
+     * @deprecated use setup(Node) to prepare a node for lexical preservation,
+     * then use the static methods on this class to print it.
+     */
+    @Deprecated
+    public LexicalPreservingPrinter(Node node) {
+        setup(node);
+    }
+
+    private static AstObserver createObserver() {
+        return new PropagatingAstObserver() {
+            @Override
+            public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                // Not really a change, ignoring
+                if ((oldValue != null && oldValue.equals(newValue)) || (oldValue == null && newValue == null)) {
+                    return;
+                }
+                if (property == ObservableProperty.RANGE || property == ObservableProperty.COMMENTED_NODE) {
+                    return;
+                }
+                if (property == ObservableProperty.COMMENT) {
+                    if (!observedNode.getParentNode().isPresent()) {
+                        throw new IllegalStateException();
+                    }
+                    NodeText nodeText = getOrCreateNodeText(observedNode.getParentNode().get());
+                    if (oldValue == null) {
+                        // Find the position of the comment node and put in front of it the comment and a newline
+                        int index = nodeText.findChild(observedNode);
+                        nodeText.addChild(index, (Comment) newValue);
+                        nodeText.addToken(index + 1, eolTokenKind(), Utils.EOL);
+                    } else if (newValue == null) {
+                        if (oldValue instanceof JavadocComment) {
+                            JavadocComment javadocComment = (JavadocComment) oldValue;
+                            List<TokenTextElement> matchingTokens = nodeText.getElements().stream().filter(e -> e.isToken(JAVADOC_COMMENT)
+                                    && ((TokenTextElement) e).getText().equals("/**" + javadocComment.getContent() + "*/")).map(e -> (TokenTextElement) e).collect(Collectors.toList());
+                            if (matchingTokens.size() != 1) {
+                                throw new IllegalStateException();
+                            }
+                            int index = nodeText.findElement(matchingTokens.get(0));
+                            nodeText.removeElement(index);
+                            if (nodeText.getElements().get(index).isNewline()) {
+                                nodeText.removeElement(index);
+                            }
+                        } else {
+                            throw new UnsupportedOperationException();
+                        }
+                    } else {
+                        if (oldValue instanceof JavadocComment) {
+                            JavadocComment oldJavadocComment = (JavadocComment) oldValue;
+                            List<TokenTextElement> matchingTokens = nodeText.getElements().stream().filter(e -> e.isToken(JAVADOC_COMMENT)
+                                    && ((TokenTextElement) e).getText().equals("/**" + oldJavadocComment.getContent() + "*/")).map(e -> (TokenTextElement) e).collect(Collectors.toList());
+                            if (matchingTokens.size() != 1) {
+                                throw new IllegalStateException();
+                            }
+                            JavadocComment newJavadocComment = (JavadocComment) newValue;
+                            nodeText.replace(matchingTokens.get(0), new TokenTextElement(JAVADOC_COMMENT, "/**" + newJavadocComment.getContent() + "*/"));
+                        } else {
+                            throw new UnsupportedOperationException();
+                        }
+                    }
+                }
+                NodeText nodeText = getOrCreateNodeText(observedNode);
+
+                if (nodeText == null) {
+                    throw new NullPointerException(observedNode.getClass().getSimpleName());
+                }
+
+                new LexicalDifferenceCalculator().calculatePropertyChange(nodeText, observedNode, property, oldValue, newValue);
+            }
+
+            @Override
+            public void concreteListChange(NodeList changedList, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+                NodeText nodeText = getOrCreateNodeText(changedList.getParentNodeForChildren());
+                if (type == ListChangeType.REMOVAL) {
+                    new LexicalDifferenceCalculator().calculateListRemovalDifference(findNodeListName(changedList), changedList, index).apply(nodeText, changedList.getParentNodeForChildren());
+                } else if (type == ListChangeType.ADDITION) {
+                    new LexicalDifferenceCalculator().calculateListAdditionDifference(findNodeListName(changedList), changedList, index, nodeAddedOrRemoved).apply(nodeText, changedList.getParentNodeForChildren());
+                } else {
+                    throw new UnsupportedOperationException();
+                }
+            }
+
+            @Override
+            public void concreteListReplacement(NodeList changedList, int index, Node oldValue, Node newValue) {
+                NodeText nodeText = getOrCreateNodeText(changedList.getParentNodeForChildren());
+                new LexicalDifferenceCalculator().calculateListReplacementDifference(findNodeListName(changedList), changedList, index, newValue).apply(nodeText, changedList.getParentNodeForChildren());
+            }
+        };
+    }
+
+    private static void storeInitialText(Node root) {
+        Map<Node, List<JavaToken>> tokensByNode = new IdentityHashMap<>();
+
+        // We go over tokens and find to which nodes they belong. Note that we do not traverse the tokens as they were
+        // on a list but as they were organized in a tree. At each time we select only the branch corresponding to the
+        // range of interest and ignore all other branches
+        for (JavaToken token : root.getTokenRange().get()) {
+            Range tokenRange = token.getRange().orElseThrow(() -> new RuntimeException("Token without range: " + token));
+            Node owner = findNodeForToken(root, tokenRange);
+            if (owner == null) {
+                throw new RuntimeException("Token without node owning it: " + token);
+            }
+            if (!tokensByNode.containsKey(owner)) {
+                tokensByNode.put(owner, new LinkedList<>());
+            }
+            tokensByNode.get(owner).add(token);
+        }
+
+        // Now that we know the tokens we use them to create the initial NodeText for each node
+        new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                if (!PhantomNodeLogic.isPhantomNode(node)) {
+                    LexicalPreservingPrinter.storeInitialTextForOneNode(node, tokensByNode.get(node));
+                }
+            }
+        }.visitBreadthFirst(root);
+    }
+
+    private static Node findNodeForToken(Node node, Range tokenRange) {
+        if (PhantomNodeLogic.isPhantomNode(node)) {
+            return null;
+        }
+        if (node.getRange().get().contains(tokenRange)) {
+            for (Node child : node.getChildNodes()) {
+                Node found = findNodeForToken(child, tokenRange);
+                if (found != null) {
+                    return found;
+                }
+            }
+            return node;
+        } else {
+            return null;
+        }
+    }
+
+    private static void storeInitialTextForOneNode(Node node, List<JavaToken> nodeTokens) {
+        if (nodeTokens == null) {
+            nodeTokens = Collections.emptyList();
+        }
+        List<Pair<Range, TextElement>> elements = new LinkedList<>();
+        for (Node child : node.getChildNodes()) {
+            if (!PhantomNodeLogic.isPhantomNode(child)) {
+                if (!child.getRange().isPresent()) {
+                    throw new RuntimeException("Range not present on node " + child);
+                }
+                elements.add(new Pair<>(child.getRange().get(), new ChildTextElement(child)));
+            }
+        }
+        for (JavaToken token : nodeTokens) {
+            elements.add(new Pair<>(token.getRange().get(), new TokenTextElement(token)));
+        }
+        elements.sort(comparing(e -> e.a.begin));
+        node.setData(NODE_TEXT_DATA, new NodeText(elements.stream().map(p -> p.b).collect(Collectors.toList())));
+    }
+
+    //
+    // Iterators
+    //
+
+    private static Iterator<TokenTextElement> tokensPreceeding(final Node node) {
+        if (!node.getParentNode().isPresent()) {
+            return new TextElementIteratorsFactory.EmptyIterator<>();
+        }
+        // There is the awfully painful case of the fake types involved in variable declarators and
+        // fields or variable declaration that are, of course, an exception...
+
+        NodeText parentNodeText = getOrCreateNodeText(node.getParentNode().get());
+        int index = parentNodeText.tryToFindChild(node);
+        if (index == NodeText.NOT_FOUND) {
+            if (node.getParentNode().get() instanceof VariableDeclarator) {
+                return tokensPreceeding(node.getParentNode().get());
+            } else {
+                throw new IllegalArgumentException(
+                        String.format("I could not find child '%s' in parent '%s'. parentNodeText: %s",
+                                node, node.getParentNode().get(), parentNodeText));
+            }
+        }
+
+        return new TextElementIteratorsFactory.CascadingIterator<>(
+                TextElementIteratorsFactory.partialReverseIterator(parentNodeText, index - 1),
+                () -> tokensPreceeding(node.getParentNode().get()));
+    }
+
+    //
+    // Printing methods
+    //
+
+    /**
+     * Print a Node into a String, preserving the lexical information.
+     */
+    public static String print(Node node) {
+        StringWriter writer = new StringWriter();
+        try {
+            print(node, writer);
+        } catch (IOException e) {
+            throw new RuntimeException("Unexpected IOException on a StringWriter", e);
+        }
+        return writer.toString();
+    }
+
+    /**
+     * Print a Node into a Writer, preserving the lexical information.
+     */
+    public static void print(Node node, Writer writer) throws IOException {
+        if (!node.containsData(NODE_TEXT_DATA)) {
+            getOrCreateNodeText(node);
+        }
+        final NodeText text = node.getData(NODE_TEXT_DATA);
+        writer.append(text.expand());
+    }
+
+    //
+    // Methods to handle transformations
+    //
+
+    private static void prettyPrintingTextNode(Node node, NodeText nodeText) {
+        if (node instanceof PrimitiveType) {
+            PrimitiveType primitiveType = (PrimitiveType) node;
+            switch (primitiveType.getType()) {
+                case BOOLEAN:
+                    nodeText.addToken(BOOLEAN, node.toString());
+                    break;
+                case CHAR:
+                    nodeText.addToken(CHAR, node.toString());
+                    break;
+                case BYTE:
+                    nodeText.addToken(BYTE, node.toString());
+                    break;
+                case SHORT:
+                    nodeText.addToken(SHORT, node.toString());
+                    break;
+                case INT:
+                    nodeText.addToken(INT, node.toString());
+                    break;
+                case LONG:
+                    nodeText.addToken(LONG, node.toString());
+                    break;
+                case FLOAT:
+                    nodeText.addToken(FLOAT, node.toString());
+                    break;
+                case DOUBLE:
+                    nodeText.addToken(DOUBLE, node.toString());
+                    break;
+                default:
+                    throw new IllegalArgumentException();
+            }
+            return;
+        }
+        if (node instanceof JavadocComment) {
+            nodeText.addToken(JAVADOC_COMMENT, "/**" + ((JavadocComment) node).getContent() + "*/");
+            return;
+        }
+
+        interpret(node, ConcreteSyntaxModel.forClass(node.getClass()), nodeText);
+    }
+
+    private static NodeText interpret(Node node, CsmElement csm, NodeText nodeText) {
+        LexicalDifferenceCalculator.CalculatedSyntaxModel calculatedSyntaxModel = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(csm, node);
+
+        List<TokenTextElement> indentation = findIndentation(node);
+
+        boolean pendingIndentation = false;
+        for (CsmElement element : calculatedSyntaxModel.elements) {
+            if (pendingIndentation && !(element instanceof CsmToken && ((CsmToken) element).isNewLine())) {
+                indentation.forEach(nodeText::addElement);
+            }
+            pendingIndentation = false;
+            if (element instanceof LexicalDifferenceCalculator.CsmChild) {
+                nodeText.addChild(((LexicalDifferenceCalculator.CsmChild) element).getChild());
+            } else if (element instanceof CsmToken) {
+                CsmToken csmToken = (CsmToken) element;
+                nodeText.addToken(csmToken.getTokenType(), csmToken.getContent(node));
+                if (csmToken.isNewLine()) {
+                    pendingIndentation = true;
+                }
+            } else if (element instanceof CsmMix) {
+                CsmMix csmMix = (CsmMix) element;
+                csmMix.getElements().forEach(e -> interpret(node, e, nodeText));
+            } else {
+                throw new UnsupportedOperationException(element.getClass().getSimpleName());
+            }
+        }
+        // Array brackets are a pain... we do not have a way to represent them explicitly in the AST
+        // so they have to be handled in a special way
+        if (node instanceof VariableDeclarator) {
+            VariableDeclarator variableDeclarator = (VariableDeclarator) node;
+            variableDeclarator.getParentNode().ifPresent(parent ->
+                    ((NodeWithVariables<?>) parent).getMaximumCommonType().ifPresent(mct -> {
+                        int extraArrayLevels = variableDeclarator.getType().getArrayLevel() - mct.getArrayLevel();
+                        for (int i = 0; i < extraArrayLevels; i++) {
+                            nodeText.addElement(new TokenTextElement(LBRACKET));
+                            nodeText.addElement(new TokenTextElement(RBRACKET));
+                        }
+                    })
+            );
+        }
+        return nodeText;
+    }
+
+    // Visible for testing
+    static NodeText getOrCreateNodeText(Node node) {
+        if (!node.containsData(NODE_TEXT_DATA)) {
+            NodeText nodeText = new NodeText();
+            node.setData(NODE_TEXT_DATA, nodeText);
+            prettyPrintingTextNode(node, nodeText);
+        }
+        return node.getData(NODE_TEXT_DATA);
+    }
+
+    // Visible for testing
+    static List<TokenTextElement> findIndentation(Node node) {
+        List<TokenTextElement> followingNewlines = new LinkedList<>();
+        Iterator<TokenTextElement> it = tokensPreceeding(node);
+        while (it.hasNext()) {
+            TokenTextElement tte = it.next();
+            if (tte.getTokenKind() == SINGLE_LINE_COMMENT
+                    || tte.isNewline()) {
+                break;
+            } else {
+                followingNewlines.add(tte);
+            }
+        }
+        Collections.reverse(followingNewlines);
+        for (int i = 0; i < followingNewlines.size(); i++) {
+            if (!followingNewlines.get(i).isSpaceOrTab()) {
+                return followingNewlines.subList(0, i);
+            }
+        }
+        return followingNewlines;
+    }
+
+    //
+    // Helper methods
+    //
+
+    private static boolean isReturningOptionalNodeList(Method m) {
+        if (!m.getReturnType().getCanonicalName().equals(Optional.class.getCanonicalName())) {
+            return false;
+        }
+        if (!(m.getGenericReturnType() instanceof ParameterizedType)) {
+            return false;
+        }
+        ParameterizedType parameterizedType = (ParameterizedType) m.getGenericReturnType();
+        java.lang.reflect.Type optionalArgument = parameterizedType.getActualTypeArguments()[0];
+        return (optionalArgument.getTypeName().startsWith(NodeList.class.getCanonicalName()));
+    }
+
+    private static ObservableProperty findNodeListName(NodeList nodeList) {
+        Node parent = nodeList.getParentNodeForChildren();
+        for (Method m : parent.getClass().getMethods()) {
+            if (m.getParameterCount() == 0 && m.getReturnType().getCanonicalName().equals(NodeList.class.getCanonicalName())) {
+                try {
+                    Object raw = m.invoke(parent);
+                    if (!(raw instanceof NodeList)) {
+                        throw new IllegalStateException("Expected NodeList, found " + raw.getClass().getCanonicalName());
+                    }
+                    NodeList result = (NodeList) raw;
+                    if (result == nodeList) {
+                        String name = m.getName();
+                        if (name.startsWith("get")) {
+                            name = name.substring("get".length());
+                        }
+                        return ObservableProperty.fromCamelCaseName(decapitalize(name));
+                    }
+                } catch (IllegalAccessException | InvocationTargetException e) {
+                    throw new RuntimeException(e);
+                }
+            } else if (m.getParameterCount() == 0 && isReturningOptionalNodeList(m)) {
+                try {
+                    Optional<NodeList<?>> raw = (Optional<NodeList<?>>) m.invoke(parent);
+                    if (raw.isPresent() && raw.get() == nodeList) {
+                        String name = m.getName();
+                        if (name.startsWith("get")) {
+                            name = name.substring("get".length());
+                        }
+                        return ObservableProperty.fromCamelCaseName(decapitalize(name));
+                    }
+                } catch (IllegalAccessException | InvocationTargetException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        throw new IllegalArgumentException("Cannot find list name of NodeList of size " + nodeList.size());
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/NodeText.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/NodeText.java
new file mode 100644
index 0000000..1be264e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/NodeText.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.ast.Node;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This contains the lexical information for a single node.
+ * It is basically a list of tokens and children.
+ */
+class NodeText {
+    private final List<TextElement> elements;
+
+    public static final int NOT_FOUND = -1;
+
+    enum Option {
+        REMOVE_SPACE_IMMEDIATELY_AFTER,
+        EXCLUDE_START,
+        EXCLUDE_END
+    }
+
+    //
+    // Constructors
+    //
+
+    NodeText(List<TextElement> elements) {
+        this.elements = elements;
+    }
+
+    /**
+     * Initialize with an empty list of elements.
+     */
+    NodeText() {
+        this(new LinkedList<>());
+    }
+
+    //
+    // Adding elements
+    //
+
+    /**
+     * Add an element at the end.
+     */
+    void addElement(TextElement nodeTextElement) {
+        this.elements.add(nodeTextElement);
+    }
+
+    /**
+     * Add an element at the given position.
+     */
+    void addElement(int index, TextElement nodeTextElement) {
+        this.elements.add(index, nodeTextElement);
+    }
+
+    void addChild(Node child) {
+        addElement(new ChildTextElement(child));
+    }
+
+    void addChild(int index, Node child) {
+        addElement(index, new ChildTextElement(child));
+    }
+
+    void addToken(int tokenKind, String text) {
+        elements.add(new TokenTextElement(tokenKind, text));
+    }
+
+    void addToken(int index, int tokenKind, String text) {
+        elements.add(index, new TokenTextElement(tokenKind, text));
+    }
+
+    //
+    // Finding elements
+    //
+
+    int findElement(TextElementMatcher matcher) {
+        return findElement(matcher, 0);
+    }
+
+    int findElement(TextElementMatcher matcher, int from) {
+        int res = tryToFindElement(matcher, from);
+        if (res == NOT_FOUND) {
+            throw new IllegalArgumentException(
+                    String.format("I could not find child '%s' from position %d. Elements: %s",
+                            matcher, from, elements));
+        } else {
+            return res;
+        }
+    }
+
+    int tryToFindElement(TextElementMatcher matcher, int from) {
+        for (int i=from; i<elements.size(); i++) {
+            TextElement element = elements.get(i);
+            if (matcher.match(element)) {
+                return i;
+            }
+        }
+        return NOT_FOUND;
+    }
+
+    int findChild(Node child) {
+        return findChild(child, 0);
+    }
+
+    int findChild(Node child, int from) {
+        return findElement(TextElementMatchers.byNode(child), from);
+    }
+
+    int tryToFindChild(Node child) {
+        return tryToFindChild(child, 0);
+    }
+
+    int tryToFindChild(Node child, int from) {
+        return tryToFindElement(TextElementMatchers.byNode(child), from);
+    }
+
+    //
+    // Removing single elements
+    //
+
+    void remove(TextElementMatcher matcher) {
+        elements.removeIf(matcher::match);
+    }
+
+    public void remove(TextElementMatcher matcher, boolean potentiallyFollowingWhitespace) {
+        int i=0;
+        for (TextElement e : elements) {
+            if (matcher.match(e)) {
+                elements.remove(e);
+                if (potentiallyFollowingWhitespace) {
+                    if (i < elements.size()) {
+                        if (elements.get(i).isWhiteSpace()) {
+                            elements.remove(i);
+                        }
+                    } else {
+                        throw new UnsupportedOperationException();
+                    }
+                }
+                return;
+            }
+        }
+        throw new IllegalArgumentException();
+    }
+
+    //
+    // Removing sequences
+    //
+
+    void removeElement(int index) {
+        elements.remove(index);
+    }
+
+    //
+    // Replacing elements
+    //
+
+    void replace(TextElementMatcher position, TextElement newElement) {
+        int index = findElement(position, 0);
+        elements.remove(index);
+        elements.add(index, newElement);
+    }
+
+    //
+    // Other methods
+    //
+
+    /**
+     * Generate the corresponding string.
+     */
+    String expand() {
+        StringBuffer sb = new StringBuffer();
+
+        elements.forEach(e -> sb.append(e.expand()));
+        return sb.toString();
+    }
+
+    // Visible for testing
+    int numberOfElements() {
+        return elements.size();
+    }
+
+    // Visible for testing
+    TextElement getTextElement(int index) {
+        return elements.get(index);
+    }
+
+    // Visible for testing
+    List<TextElement> getElements() {
+        return elements;
+    }
+
+    @Override
+    public String toString() {
+        return "NodeText{" + elements + '}';
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/PhantomNodeLogic.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/PhantomNodeLogic.java
new file mode 100644
index 0000000..d17f768
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/PhantomNodeLogic.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.AstObserver;
+import com.github.javaparser.ast.observer.AstObserverAdapter;
+import com.github.javaparser.ast.type.UnknownType;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import static java.util.Collections.synchronizedMap;
+
+/**
+ * We want to recognize and ignore "phantom" nodes, like the fake type of variable in FieldDeclaration
+ */
+class PhantomNodeLogic {
+
+    private static final int LEVELS_TO_EXPLORE = 3;
+
+    private static final Map<Node, Boolean> isPhantomNodeCache = synchronizedMap(new IdentityHashMap<>());
+
+    private static final AstObserver cacheCleaner = new AstObserverAdapter() {
+        @Override
+        public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+            isPhantomNodeCache.remove(observedNode);
+        }
+    };
+
+    static boolean isPhantomNode(Node node) {
+        if (isPhantomNodeCache.containsKey(node)) {
+            return isPhantomNodeCache.get(node);
+        } else {
+            if (node instanceof UnknownType) {
+                return true;
+            }
+            boolean res = (node.getParentNode().isPresent() &&
+                    !node.getParentNode().get().getRange().get().contains(node.getRange().get())
+                    || inPhantomNode(node, LEVELS_TO_EXPLORE));
+            isPhantomNodeCache.put(node, res);
+            node.register(cacheCleaner);
+            return res;
+        }
+    }
+
+    /**
+     * A node contained in a phantom node is also a phantom node. We limit how many levels up we check just for performance reasons.
+     */
+    private static boolean inPhantomNode(Node node, int levels) {
+        return node.getParentNode().isPresent() &&
+                (isPhantomNode(node.getParentNode().get())
+                        || inPhantomNode(node.getParentNode().get(), levels - 1));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElement.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElement.java
new file mode 100644
index 0000000..987b8f2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElement.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Node;
+
+public abstract class TextElement implements TextElementMatcher {
+
+    abstract String expand();
+
+    abstract boolean isToken(int tokenKind);
+
+    final boolean isCommentToken() {
+        return isToken(GeneratedJavaParserConstants.JAVADOC_COMMENT)
+                || isToken(GeneratedJavaParserConstants.SINGLE_LINE_COMMENT)
+                || isToken(GeneratedJavaParserConstants.MULTI_LINE_COMMENT);
+    }
+
+    @Override
+    public boolean match(TextElement textElement) {
+        return this.equals(textElement);
+    }
+
+    abstract boolean isNode(Node node);
+
+    public abstract boolean isWhiteSpace();
+
+    public abstract boolean isSpaceOrTab();
+
+    public abstract boolean isNewline();
+
+    public abstract boolean isComment();
+
+    public final boolean isWhiteSpaceOrComment() {
+        return isWhiteSpace() || isComment();
+    }
+
+    /**
+     * Is this TextElement representing a child of the given class?
+     */
+    public abstract boolean isChildOfClass(Class<? extends Node> nodeClass);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementIteratorsFactory.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementIteratorsFactory.java
new file mode 100644
index 0000000..b2e29b4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementIteratorsFactory.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+class TextElementIteratorsFactory {
+
+    static class CascadingIterator<E> implements Iterator<E> {
+        interface Provider<E> {
+            Iterator<E> provide();
+        }
+
+        private final Provider<E> nextProvider;
+        private Iterator<E> current;
+        private Iterator<E> next;
+        private boolean lastReturnedFromCurrent = false;
+        private boolean lastReturnedFromNext = false;
+
+        public CascadingIterator(Iterator<E> current, Provider<E> nextProvider) {
+            this.nextProvider = nextProvider;
+            this.current = current;
+        }
+
+
+        @Override
+        public boolean hasNext() {
+            if (current.hasNext()) {
+                return true;
+            }
+            if (next == null) {
+                next = nextProvider.provide();
+            }
+            return next.hasNext();
+        }
+
+        @Override
+        public E next() {
+            if (current.hasNext()) {
+                lastReturnedFromCurrent = true;
+                lastReturnedFromNext = false;
+                return current.next();
+            }
+            if (next == null) {
+                next = nextProvider.provide();
+            }
+            lastReturnedFromCurrent = false;
+            lastReturnedFromNext = true;
+            return next.next();
+        }
+
+        @Override
+        public void remove() {
+            if (lastReturnedFromCurrent) {
+                current.remove();
+                return;
+            }
+            if (lastReturnedFromNext) {
+                next.remove();
+                return;
+            }
+            throw new IllegalArgumentException();
+        }
+    }
+
+    static class EmptyIterator<E> implements Iterator<E> {
+        @Override
+        public boolean hasNext() {
+            return false;
+        }
+
+        @Override
+        public E next() {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    private static class SingleElementIterator<E> implements Iterator<E> {
+        private final E element;
+        private boolean returned;
+
+        SingleElementIterator(E element) {
+            this.element = element;
+        }
+
+        @Override
+        public boolean hasNext() {
+            return !returned;
+        }
+
+        @Override
+        public E next() {
+            returned = true;
+            return element;
+        }
+
+        @Override
+        public void remove() {
+
+        }
+    }
+
+    static class ComposedIterator<E> implements Iterator<E> {
+        private final List<Iterator<E>> elements;
+        private int currIndex;
+
+        ComposedIterator(List<Iterator<E>> elements) {
+            this.elements = elements;
+            currIndex = 0;
+        }
+
+        @Override
+        public boolean hasNext() {
+            if (currIndex >= elements.size()) {
+                return false;
+            }
+            if (elements.get(currIndex).hasNext()){
+                return true;
+            }
+            currIndex++;
+            return hasNext();
+        }
+
+        @Override
+        public E next() {
+            if (!hasNext()) {
+                throw new IllegalArgumentException();
+            }
+            return elements.get(currIndex).next();
+        }
+
+        @Override
+        public void remove() {
+            elements.get(currIndex).remove();
+        }
+    }
+
+    private static Iterator<TokenTextElement> reverseIterator(NodeText nodeText, int index) {
+        TextElement textElement = nodeText.getTextElement(index);
+        if (textElement instanceof TokenTextElement) {
+            return new SingleElementIterator<TokenTextElement>((TokenTextElement)textElement) {
+                @Override
+                public void remove() {
+                    nodeText.removeElement(index);
+                }
+            };
+        } else if (textElement instanceof ChildTextElement) {
+            ChildTextElement childTextElement = (ChildTextElement)textElement;
+            NodeText textForChild = childTextElement.getNodeTextForWrappedNode();
+            return reverseIterator(textForChild);
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    public static Iterator<TokenTextElement> reverseIterator(NodeText nodeText) {
+        return partialReverseIterator(nodeText, nodeText.numberOfElements() - 1);
+    }
+
+    public static Iterator<TokenTextElement> partialReverseIterator(NodeText nodeText, int fromIndex) {
+        List<Iterator<TokenTextElement>> elements = new LinkedList<>();
+        for (int i=fromIndex;i>=0;i--) {
+            elements.add(reverseIterator(nodeText, i));
+        }
+        return new ComposedIterator<>(elements);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementMatcher.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementMatcher.java
new file mode 100644
index 0000000..e522008
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementMatcher.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+public interface TextElementMatcher {
+
+    boolean match(TextElement textElement);
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementMatchers.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementMatchers.java
new file mode 100644
index 0000000..f3e95b7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TextElementMatchers.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.ast.Node;
+
+class TextElementMatchers {
+
+    static TextElementMatcher byTokenType(int tokenType) {
+        return textElement -> textElement.isToken(tokenType);
+    }
+
+    static TextElementMatcher byNode(final Node node) {
+        return new TextElementMatcher() {
+            @Override
+            public boolean match(TextElement textElement) {
+                return textElement.isNode(node);
+            }
+
+            @Override
+            public String toString() {
+                return "match node " + node;
+            }
+        };
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TokenTextElement.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TokenTextElement.java
new file mode 100644
index 0000000..e57b214
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/TokenTextElement.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.JavaToken;
+import com.github.javaparser.TokenTypes;
+import com.github.javaparser.ast.Node;
+
+class TokenTextElement extends TextElement {
+    private final JavaToken token;
+
+    TokenTextElement(JavaToken token) {
+        this.token = token;
+    }
+
+    TokenTextElement(int tokenKind, String text) {
+        this(new JavaToken(tokenKind, text));
+    }
+
+    TokenTextElement(int tokenKind) {
+        this(new JavaToken(tokenKind));
+    }
+
+    @Override
+    String expand() {
+        return token.getText();
+    }
+
+    // Visible for testing
+    String getText() {
+        return token.getText();
+    }
+
+    public int getTokenKind() {
+        return token.getKind();
+    }
+
+    public JavaToken getToken() {
+        return token;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        TokenTextElement that = (TokenTextElement) o;
+
+        return token.equals(that.token);
+    }
+
+    @Override
+    public int hashCode() {
+        return token.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return token.toString();
+    }
+
+    @Override
+    boolean isToken(int tokenKind) {
+        return token.getKind() == tokenKind;
+    }
+
+    @Override
+    boolean isNode(Node node) {
+        return false;
+    }
+
+    @Override
+    public boolean isWhiteSpace() {
+        return token.getCategory().isWhitespace();
+    }
+
+    @Override
+    public boolean isSpaceOrTab() {
+        return token.getCategory().isWhitespaceButNotEndOfLine();
+    }
+
+    @Override
+    public boolean isComment() {
+        return token.getCategory().isComment();
+    }
+
+    @Override
+    public boolean isNewline() {
+        return token.getCategory().isEndOfLine();
+    }
+
+    @Override
+    public boolean isChildOfClass(Class<? extends Node> nodeClass) {
+        return false;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/Change.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/Change.java
new file mode 100644
index 0000000..23fe09d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/Change.java
@@ -0,0 +1,29 @@
+package com.github.javaparser.printer.lexicalpreservation.changes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmConditional;
+import com.github.javaparser.utils.Utils;
+
+/**
+ * This represent a change happened to a specific Node.
+ */
+public interface Change {
+
+    default boolean evaluate(CsmConditional csmConditional, Node node) {
+        switch (csmConditional.getCondition()) {
+            case FLAG:
+                return (Boolean) getValue(csmConditional.getProperty(), node);
+            case IS_NOT_EMPTY:
+                return !Utils.valueIsNullOrEmpty(getValue(csmConditional.getProperty(), node));
+            case IS_EMPTY:
+                return Utils.valueIsNullOrEmpty(getValue(csmConditional.getProperty(), node));
+            case IS_PRESENT:
+                return !Utils.valueIsNullOrEmpty(getValue(csmConditional.getProperty(), node));
+            default:
+                throw new UnsupportedOperationException("" + csmConditional.getProperty() + " " + csmConditional.getCondition());
+        }
+    }
+
+    Object getValue(ObservableProperty property, Node node);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListAdditionChange.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListAdditionChange.java
new file mode 100644
index 0000000..ab15cc5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListAdditionChange.java
@@ -0,0 +1,37 @@
+package com.github.javaparser.printer.lexicalpreservation.changes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.observer.ObservableProperty;
+
+/**
+ * The Addition of an element to a list.
+ */
+public class ListAdditionChange implements Change {
+    private final ObservableProperty observableProperty;
+    private final int index;
+    private final Node nodeAdded;
+
+    public ListAdditionChange(ObservableProperty observableProperty, int index, Node nodeAdded) {
+        this.observableProperty = observableProperty;
+        this.index = index;
+        this.nodeAdded = nodeAdded;
+    }
+
+    @Override
+    public Object getValue(ObservableProperty property, Node node) {
+        if (property == observableProperty) {
+            NodeList<Node> nodeList = new NodeList<>();
+            Object currentRawValue = new NoChange().getValue(property, node);
+            if (!(currentRawValue instanceof NodeList)){
+                throw new IllegalStateException("Expected NodeList, found " + currentRawValue.getClass().getCanonicalName());
+            }
+            NodeList<?> currentNodeList = (NodeList<?>)(currentRawValue);
+            nodeList.addAll(currentNodeList);
+            nodeList.add(index, nodeAdded);
+            return nodeList;
+        } else {
+            return new NoChange().getValue(property, node);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListRemovalChange.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListRemovalChange.java
new file mode 100644
index 0000000..c99efd2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListRemovalChange.java
@@ -0,0 +1,35 @@
+package com.github.javaparser.printer.lexicalpreservation.changes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.observer.ObservableProperty;
+
+/**
+ * The removal of an element in a list.
+ */
+public class ListRemovalChange implements Change {
+    private final ObservableProperty observableProperty;
+    private final int index;
+
+    public ListRemovalChange(ObservableProperty observableProperty, int index) {
+        this.observableProperty = observableProperty;
+        this.index = index;
+    }
+
+    @Override
+    public Object getValue(ObservableProperty property, Node node) {
+        if (property == observableProperty) {
+            NodeList<Node> nodeList = new NodeList<>();
+            Object currentRawValue = new NoChange().getValue(property, node);
+            if (!(currentRawValue instanceof NodeList)){
+                throw new IllegalStateException("Expected NodeList, found " + currentRawValue.getClass().getCanonicalName());
+            }
+            NodeList<?> currentNodeList = (NodeList<?>)currentRawValue;
+            nodeList.addAll(currentNodeList);
+            nodeList.remove(index);
+            return nodeList;
+        } else {
+            return new NoChange().getValue(property, node);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListReplacementChange.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListReplacementChange.java
new file mode 100644
index 0000000..ccb0ead
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/ListReplacementChange.java
@@ -0,0 +1,44 @@
+package com.github.javaparser.printer.lexicalpreservation.changes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.utils.Pair;
+
+import java.util.Optional;
+
+/**
+ * The replacement of an element in a list.
+ */
+public class ListReplacementChange implements Change {
+    private final ObservableProperty observableProperty;
+    private final int index;
+    private final Node newValue;
+
+    public ListReplacementChange(ObservableProperty observableProperty, int index, Node newValue) {
+        this.observableProperty = observableProperty;
+        this.index = index;
+        this.newValue = newValue;
+    }
+
+    @Override
+    public Object getValue(ObservableProperty property, Node node) {
+        if (property == observableProperty) {
+            NodeList nodeList = new NodeList();
+            Object currentRawValue = new NoChange().getValue(property, node);
+            if (currentRawValue instanceof Optional) {
+                Optional optional = (Optional)currentRawValue;
+                currentRawValue = optional.orElseGet(null);
+            }
+            if (!(currentRawValue instanceof NodeList)){
+                throw new IllegalStateException("Expected NodeList, found " + currentRawValue.getClass().getCanonicalName());
+            }
+            NodeList currentNodeList = (NodeList)currentRawValue;
+            nodeList.addAll(currentNodeList);
+            nodeList.set(index, newValue);
+            return nodeList;
+        } else {
+            return new NoChange().getValue(property, node);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/NoChange.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/NoChange.java
new file mode 100644
index 0000000..6b29e3e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/NoChange.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.printer.lexicalpreservation.changes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+
+/**
+ * No change. The Node is not mutated.
+ */
+public class NoChange implements Change {
+
+    @Override
+    public Object getValue(ObservableProperty property, Node node) {
+        return property.getRawValue(node);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/PropertyChange.java b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/PropertyChange.java
new file mode 100644
index 0000000..37b3a6f
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/printer/lexicalpreservation/changes/PropertyChange.java
@@ -0,0 +1,40 @@
+package com.github.javaparser.printer.lexicalpreservation.changes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.observer.ObservableProperty;
+
+/**
+ * The change in value of a property.
+ */
+public class PropertyChange implements Change {
+    private final ObservableProperty property;
+    private final Object oldValue;
+    private final Object newValue;
+
+    public ObservableProperty getProperty() {
+        return property;
+    }
+
+    public Object getOldValue() {
+        return oldValue;
+    }
+
+    public Object getNewValue() {
+        return newValue;
+    }
+
+    public PropertyChange(ObservableProperty property, Object oldValue, Object newValue) {
+        this.property = property;
+        this.oldValue = oldValue;
+        this.newValue = newValue;
+    }
+
+    @Override
+    public Object getValue(ObservableProperty property, Node node) {
+        if (property == this.property) {
+            return newValue;
+        } else {
+            return property.getRawValue(node);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodAmbiguityException.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodAmbiguityException.java
new file mode 100644
index 0000000..76632c5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodAmbiguityException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+/**
+ * It is not possible to decide how to resolve a method invocation.
+ *
+ * @author Federico Tomassetti
+ */
+public class MethodAmbiguityException extends RuntimeException {
+
+    /**
+     * Create an instance from a description of the reason why there is ambiguity in this particular case.
+     */
+    public MethodAmbiguityException(String description) {
+        super(description);
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodUsage.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodUsage.java
new file mode 100644
index 0000000..ec3a06b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/MethodUsage.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametrized;
+
+
+import java.util.*;
+
+/**
+ * This is basically a MethodDeclaration with some TypeParameters defined.
+ * The defined TypeParameters can comes from the Method itself or from the surrounding types.
+ *
+ * @author Federico Tomassetti
+ */
+public class MethodUsage implements ResolvedTypeParametrized {
+    private ResolvedMethodDeclaration declaration;
+    private List<ResolvedType> paramTypes = new ArrayList<>();
+    private List<ResolvedType> exceptionTypes = new ArrayList<>();
+    private ResolvedType returnType;
+    private ResolvedTypeParametersMap typeParametersMap;
+
+    public MethodUsage(ResolvedMethodDeclaration declaration) {
+        this.typeParametersMap = ResolvedTypeParametersMap.empty();
+        this.declaration = declaration;
+        for (int i = 0; i < declaration.getNumberOfParams(); i++) {
+            paramTypes.add(declaration.getParam(i).getType());
+        }
+        for (int i = 0; i < declaration.getNumberOfSpecifiedExceptions(); i++) {
+            exceptionTypes.add(declaration.getSpecifiedException(i));
+        }
+        returnType = declaration.getReturnType();
+    }
+
+    public MethodUsage(ResolvedMethodDeclaration declaration,
+                       List<ResolvedType> paramTypes, ResolvedType returnType) {
+        this(declaration, paramTypes, returnType, declaration.getSpecifiedExceptions(),
+                ResolvedTypeParametersMap.empty());
+    }
+
+    public MethodUsage(ResolvedMethodDeclaration declaration, List<ResolvedType> paramTypes, ResolvedType returnType,
+                       List<ResolvedType> exceptionTypes) {
+        this(declaration, paramTypes, returnType, exceptionTypes, ResolvedTypeParametersMap.empty());
+    }
+
+    private MethodUsage(ResolvedMethodDeclaration declaration, List<ResolvedType> paramTypes, ResolvedType returnType,
+                        List<ResolvedType> exceptionTypes, ResolvedTypeParametersMap typeParametersMap) {
+        this.declaration = declaration;
+        this.paramTypes = paramTypes;
+        this.returnType = returnType;
+        this.exceptionTypes = exceptionTypes;
+        this.typeParametersMap = typeParametersMap;
+    }
+
+    @Override
+    public String toString() {
+        return "MethodUsage{" +
+                "declaration=" + declaration +
+                ", paramTypes=" + paramTypes +
+                '}';
+    }
+
+    public ResolvedMethodDeclaration getDeclaration() {
+        return declaration;
+    }
+
+    public String getName() {
+        return declaration.getName();
+    }
+
+    public ResolvedReferenceTypeDeclaration declaringType() {
+        return declaration.declaringType();
+    }
+
+    public ResolvedType returnType() {
+        return returnType;
+    }
+
+    public List<ResolvedType> getParamTypes() {
+        return paramTypes;
+    }
+
+    public MethodUsage replaceParamType(int i, ResolvedType replaced) {
+        if (i < 0 || i >= getNoParams()) {
+            throw new IllegalArgumentException();
+        }
+        if (paramTypes.get(i) == replaced) {
+            return this;
+        }
+        List<ResolvedType> newParams = new LinkedList<>(paramTypes);
+        newParams.set(i, replaced);
+        return new MethodUsage(declaration, newParams, returnType, exceptionTypes, typeParametersMap);
+    }
+
+    public MethodUsage replaceExceptionType(int i, ResolvedType replaced) {
+        if (i < 0 || i >= exceptionTypes.size()) {
+            throw new IllegalArgumentException();
+        }
+        if (exceptionTypes.get(i) == replaced) {
+            return this;
+        }
+        List<ResolvedType> newTypes = new LinkedList<>(exceptionTypes);
+        newTypes.set(i, replaced);
+        return new MethodUsage(declaration, paramTypes, returnType, newTypes, typeParametersMap);
+    }
+
+    public MethodUsage replaceReturnType(ResolvedType returnType) {
+        if (returnType == this.returnType) {
+            return this;
+        } else {
+            return new MethodUsage(declaration, paramTypes, returnType, exceptionTypes, typeParametersMap);
+        }
+    }
+
+    /**
+     * Return the number of formal arguments accepted by this method.
+     */
+    public int getNoParams() {
+        return paramTypes.size();
+    }
+
+    /**
+     * Return the type of the formal argument at the given position.
+     */
+    public ResolvedType getParamType(int i) {
+        return paramTypes.get(i);
+    }
+
+    public MethodUsage replaceTypeParameter(ResolvedTypeParameterDeclaration typeParameter, ResolvedType type) {
+        if (type == null) {
+            throw new IllegalArgumentException();
+        }
+
+        // TODO if the method declaration has a type param with that name ignore this call
+        MethodUsage res = new MethodUsage(declaration, paramTypes, returnType, exceptionTypes,
+                typeParametersMap.toBuilder().setValue(typeParameter, type).build());
+
+        Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
+        for (int i = 0; i < paramTypes.size(); i++) {
+            ResolvedType originalParamType = paramTypes.get(i);
+            ResolvedType newParamType = originalParamType.replaceTypeVariables(typeParameter, type, inferredTypes);
+            res = res.replaceParamType(i, newParamType);
+        }
+        for (int i = 0; i < exceptionTypes.size(); i++) {
+            ResolvedType originalType = exceptionTypes.get(i);
+            ResolvedType newType = originalType.replaceTypeVariables(typeParameter, type, inferredTypes);
+            res = res.replaceExceptionType(i, newType);
+        }
+        ResolvedType oldReturnType = res.returnType;
+        ResolvedType newReturnType = oldReturnType.replaceTypeVariables(typeParameter, type, inferredTypes);
+        res = res.replaceReturnType(newReturnType);
+        return res;
+    }
+
+    @Override
+    public ResolvedTypeParametersMap typeParametersMap() {
+        return typeParametersMap;
+    }
+
+    public String getQualifiedSignature() {
+        // TODO use the type parameters
+        return this.getDeclaration().getQualifiedSignature();
+    }
+
+    public List<ResolvedType> exceptionTypes() {
+        return exceptionTypes;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/Resolvable.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/Resolvable.java
new file mode 100644
index 0000000..2b12a1b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/Resolvable.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+public interface Resolvable<T> {
+    T resolve();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/SymbolResolver.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/SymbolResolver.java
new file mode 100644
index 0000000..67f8a00
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/SymbolResolver.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+public interface SymbolResolver {
+    /**
+     * For a reference it would find the corresponding
+     * declaration.
+     */
+    <T> T resolveDeclaration(Node node, Class<T> resultClass);
+
+    /**
+     * For types it would find the corresponding resolved types.
+     */
+    <T> T toResolvedType(Type javaparserType, Class<T> resultClass);
+
+    ResolvedType calculateType(Expression expression);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/UnsolvedSymbolException.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/UnsolvedSymbolException.java
new file mode 100644
index 0000000..b915096
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/UnsolvedSymbolException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution;
+
+/**
+ * This exception is thrown when a symbol cannot be resolved.
+ *
+ * @author Federico Tomassetti
+ */
+public class UnsolvedSymbolException extends RuntimeException {
+
+    private String context;
+    private String name;
+
+    public UnsolvedSymbolException(String name, String context) {
+        super("Unsolved symbol in " + context + " : " + name);
+        this.context = context;
+        this.name = name;
+    }
+
+    public UnsolvedSymbolException(String name) {
+        super("Unsolved symbol : " + name);
+        this.context = "unknown";
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return "UnsolvedSymbolException{" +
+                "context='" + context + '\'' +
+                ", name='" + name + '\''+
+                '}';
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/HasAccessSpecifier.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/HasAccessSpecifier.java
new file mode 100644
index 0000000..5d7e5bb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/HasAccessSpecifier.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+
+/**
+ * Anything which can have an AccessSpecifier.
+ *
+ * @author Federico Tomassetti
+ */
+public interface HasAccessSpecifier {
+
+    /**
+     * The access specifier of this element.
+     */
+    AccessSpecifier accessSpecifier();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationDeclaration.java
new file mode 100644
index 0000000..c3124f2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationDeclaration.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedAnnotationDeclaration extends ResolvedReferenceTypeDeclaration {
+
+    List<ResolvedAnnotationMemberDeclaration> getAnnotationMembers();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationMemberDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationMemberDeclaration.java
new file mode 100644
index 0000000..0e6f856
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedAnnotationMemberDeclaration.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.ast.expr.Expression;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedAnnotationMemberDeclaration extends ResolvedValueDeclaration {
+
+    Expression getDefaultValue();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedClassDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedClassDeclaration.java
new file mode 100644
index 0000000..08a8d75
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedClassDeclaration.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
+import java.util.List;
+
+/**
+ * Declaration of a Class (not an interface or an enum).
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedClassDeclaration extends ResolvedReferenceTypeDeclaration,
+        ResolvedTypeParametrizable, HasAccessSpecifier {
+
+    /**
+     * This method should always return true.
+     */
+    @Override
+    default boolean isClass() {
+        return true;
+    }
+
+    /**
+     * This is a ReferenceTypeUsage because it could contain type typeParametersValues.
+     * For example: class A extends B<Integer, String>.
+     * <p>
+     * Note that only the Object class should not have a superclass and therefore
+     * return null.
+     */
+    ResolvedReferenceType getSuperClass();
+
+    /**
+     * Return all the interfaces implemented directly by this class.
+     * It does not include the interfaces implemented by superclasses or extended
+     * by the interfaces implemented.
+     */
+    List<ResolvedReferenceType> getInterfaces();
+
+    /**
+     * Get all superclasses, with all the type typeParametersValues expressed as functions of the type
+     * typeParametersValues of this declaration.
+     */
+    List<ResolvedReferenceType> getAllSuperClasses();
+
+    /**
+     * Return all the interfaces implemented by this class, either directly or indirectly, including the interfaces
+     * extended by interfaces it implements.
+     * <p>
+     * Get all interfaces, with all the type typeParametersValues expressed as functions of the type
+     * typeParametersValues of this declaration.
+     */
+    List<ResolvedReferenceType> getAllInterfaces();
+
+    ///
+    /// Constructors
+    ///
+
+    /**
+     * List of constructors available for the class.
+     * This list should also include the default constructor.
+     */
+    List<ResolvedConstructorDeclaration> getConstructors();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedConstructorDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedConstructorDeclaration.java
new file mode 100644
index 0000000..07f486c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedConstructorDeclaration.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * A declaration of a constructor.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedConstructorDeclaration extends ResolvedMethodLikeDeclaration {
+
+    /**
+     * A constructor can be declared in a class or an enum.
+     */
+    @Override
+    ResolvedReferenceTypeDeclaration declaringType();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedDeclaration.java
new file mode 100644
index 0000000..86bee80
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedDeclaration.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * A generic declaration.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedDeclaration {
+
+    /**
+     * Anonymous classes do not have a name, for example.
+     */
+    default boolean hasName() {
+        return true;
+    }
+
+    /**
+     * Should return the name or throw a RuntimeException if the name is not available.
+     */
+    String getName();
+
+    /**
+     * Does this declaration represents a class field?
+     */
+    default boolean isField() {
+        return false;
+    }
+
+    /**
+     * Does this declaration represents a method parameter?
+     */
+    default boolean isParameter() {
+        return false;
+    }
+
+    /**
+     * Does this declaration represents a type?
+     */
+    default boolean isType() {
+        return false;
+    }
+
+    /**
+     * Does this declaration represents a method?
+     */
+    default boolean isMethod() {
+        return false;
+    }
+
+    /**
+     * Return this as a FieldDeclaration or throw an UnsupportedOperationException
+     */
+    default ResolvedFieldDeclaration asField() {
+        throw new UnsupportedOperationException(String.format("%s is not a FieldDeclaration", this));
+    }
+
+    /**
+     * Return this as a ParameterDeclaration or throw an UnsupportedOperationException
+     */
+    default ResolvedParameterDeclaration asParameter() {
+        throw new UnsupportedOperationException(String.format("%s is not a ParameterDeclaration", this));
+    }
+
+    /**
+     * Return this as a TypeDeclaration or throw an UnsupportedOperationException
+     */
+    default ResolvedTypeDeclaration asType() {
+        throw new UnsupportedOperationException(String.format("%s is not a TypeDeclaration", this));
+    }
+
+    /**
+     * Return this as a MethodDeclaration or throw an UnsupportedOperationException
+     */
+    default ResolvedMethodDeclaration asMethod() {
+        throw new UnsupportedOperationException(String.format("%s is not a MethodDeclaration", this));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumConstantDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumConstantDeclaration.java
new file mode 100644
index 0000000..aeb0ded
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumConstantDeclaration.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedEnumConstantDeclaration extends ResolvedValueDeclaration {
+
+    String getName();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumDeclaration.java
new file mode 100644
index 0000000..e31a4fb
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedEnumDeclaration.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import java.util.List;
+
+/**
+ * Declaration of an Enum.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedEnumDeclaration extends ResolvedReferenceTypeDeclaration,
+        HasAccessSpecifier {
+
+    @Override
+    default boolean isEnum() {
+        return true;
+    }
+
+    @Override
+    default ResolvedEnumDeclaration asEnum() {
+        return this;
+    }
+
+    List<ResolvedEnumConstantDeclaration> getEnumConstants();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedFieldDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedFieldDeclaration.java
new file mode 100644
index 0000000..194c892
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedFieldDeclaration.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * Declaration of a field.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedFieldDeclaration extends ResolvedValueDeclaration, HasAccessSpecifier {
+
+    /**
+     * Is the field static?
+     */
+    boolean isStatic();
+
+    @Override
+    default boolean isField() {
+        return true;
+    }
+
+    @Override
+    default ResolvedFieldDeclaration asField() {
+        return this;
+    }
+
+    /**
+     * The type on which this field has been declared
+     */
+    ResolvedTypeDeclaration declaringType();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedInterfaceDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedInterfaceDeclaration.java
new file mode 100644
index 0000000..5ef53b2
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedInterfaceDeclaration.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An interface declaration.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedInterfaceDeclaration extends ResolvedReferenceTypeDeclaration,
+        ResolvedTypeParametrizable, HasAccessSpecifier {
+
+    @Override
+    default boolean isInterface() {
+        return true;
+    }
+
+    /**
+     * Return the list of interfaces extended directly by this one.
+     */
+    List<ResolvedReferenceType> getInterfacesExtended();
+
+    /**
+     * Return the list of interfaces extended directly or indirectly by this one.
+     */
+    default List<ResolvedReferenceType> getAllInterfacesExtended() {
+        List<ResolvedReferenceType> interfaces = new ArrayList<>();
+        for (ResolvedReferenceType interfaceDeclaration : getInterfacesExtended()) {
+            interfaces.add(interfaceDeclaration);
+            interfaces.addAll(interfaceDeclaration.getAllInterfacesAncestors());
+        }
+        return interfaces;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodDeclaration.java
new file mode 100644
index 0000000..9f2f64c
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodDeclaration.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * A declaration of a method (either in an interface, a class, an enum or an annotation).
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedMethodDeclaration extends ResolvedMethodLikeDeclaration {
+
+    /**
+     * The type of the value returned by the current method. This method can also be invoked
+     * for methods returning void.
+     */
+    ResolvedType getReturnType();
+
+    /**
+     * Is the method abstract? All interface methods not marked as default are abstract.
+     */
+    boolean isAbstract();
+
+    /**
+     * Is this a default method?
+     */
+    boolean isDefaultMethod();
+
+    /*
+     * Is this method static?
+     */
+    boolean isStatic();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodLikeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodLikeDeclaration.java
new file mode 100644
index 0000000..97f35f5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedMethodLikeDeclaration.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * This is a common interface for MethodDeclaration and ConstructorDeclaration.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedMethodLikeDeclaration extends ResolvedDeclaration,
+        ResolvedTypeParametrizable, HasAccessSpecifier {
+    /**
+     * The package name of the declaring type.
+     */
+    default String getPackageName() {
+        return declaringType().getPackageName();
+    }
+
+    /**
+     * The class(es) wrapping the declaring type.
+     */
+    default String getClassName() {
+        return declaringType().getClassName();
+    }
+
+    /**
+     * The qualified name of the method composed by the qualfied name of the declaring type
+     * followed by a dot and the name of the method.
+     */
+    default String getQualifiedName() {
+        return declaringType().getQualifiedName() + "." + this.getName();
+    }
+
+    /**
+     * The signature of the method.
+     */
+    default String getSignature() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getName());
+        sb.append("(");
+        for (int i = 0; i < getNumberOfParams(); i++) {
+            if (i != 0) {
+                sb.append(", ");
+            }
+            sb.append(getParam(i).describeType());
+        }
+        sb.append(")");
+        return sb.toString();
+    }
+
+    /**
+     * The qualified signature of the method. It is composed by the qualified name of the declaring type
+     * followed by the signature of the method.
+     */
+    default String getQualifiedSignature() {
+        return declaringType().getId() + "." + this.getSignature();
+    }
+
+    /**
+     * The type in which the method is declared.
+     */
+    ResolvedReferenceTypeDeclaration declaringType();
+
+    /**
+     * Number of params.
+     */
+    int getNumberOfParams();
+
+    /**
+     * Get the ParameterDeclaration at the corresponding position or throw IllegalArgumentException.
+     */
+    ResolvedParameterDeclaration getParam(int i);
+
+    /**
+     * Utility method to get the last ParameterDeclaration. It throws UnsupportedOperationException if the method
+     * has no parameters.
+     * The last parameter can be variadic and sometimes it needs to be handled in a special way.
+     */
+    default ResolvedParameterDeclaration getLastParam() {
+        if (getNumberOfParams() == 0) {
+            throw new UnsupportedOperationException("This method has no typeParametersValues, therefore it has no a last parameter");
+        }
+        return getParam(getNumberOfParams() - 1);
+    }
+
+    /**
+     * Has the method or construcor a variadic parameter?
+     * Note that when a method has a variadic parameter it should have an array type.
+     */
+    default boolean hasVariadicParameter() {
+        if (getNumberOfParams() == 0) {
+            return false;
+        } else {
+            return getParam(getNumberOfParams() - 1).isVariadic();
+        }
+    }
+
+    @Override
+    default Optional<ResolvedTypeParameterDeclaration> findTypeParameter(String name) {
+        for (ResolvedTypeParameterDeclaration tp : this.getTypeParameters()) {
+            if (tp.getName().equals(name)) {
+                return Optional.of(tp);
+            }
+        }
+        return declaringType().findTypeParameter(name);
+    }
+
+    /**
+     * Number of exceptions listed in the throws clause.
+     */
+    int getNumberOfSpecifiedExceptions();
+
+    /**
+     * Type of the corresponding entry in the throws clause.
+     *
+     * @throws IllegalArgumentException if the index is negative or it is equal or greater than the value returned by
+     *                                  getNumberOfSpecifiedExceptions
+     * @throws UnsupportedOperationException for those types of methods of constructor that do not declare exceptions
+     */
+    ResolvedType getSpecifiedException(int index);
+
+    default List<ResolvedType> getSpecifiedExceptions() {
+        if (getNumberOfSpecifiedExceptions() == 0) {
+            return Collections.emptyList();
+        } else {
+            List<ResolvedType> exceptions = new LinkedList<>();
+            for (int i=0;i<getNumberOfSpecifiedExceptions();i++) {
+                exceptions.add(getSpecifiedException(i));
+            }
+            return exceptions;
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedParameterDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedParameterDeclaration.java
new file mode 100644
index 0000000..6686522
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedParameterDeclaration.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+/**
+ * Declaration of a parameter.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedParameterDeclaration extends ResolvedValueDeclaration {
+
+    @Override
+    default boolean isParameter() {
+        return true;
+    }
+
+    @Override
+    default ResolvedParameterDeclaration asParameter() {
+        return this;
+    }
+
+    /**
+     * Is this parameter declared as variadic?
+     */
+    boolean isVariadic();
+
+    /**
+     * Describe the type of the parameter. In practice add three dots to the type name
+     * is the parameter is variadic.
+     */
+    default String describeType() {
+        if (isVariadic()) {
+            return getType().asArrayType().getComponentType().describe() + "...";
+        } else {
+            return getType().describe();
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java
new file mode 100644
index 0000000..b395210
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedReferenceTypeDeclaration.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedReferenceTypeDeclaration extends ResolvedTypeDeclaration,
+        ResolvedTypeParametrizable {
+
+    @Override
+    default ResolvedReferenceTypeDeclaration asReferenceType() {
+        return this;
+    }
+
+    ///
+    /// Ancestors
+    ///
+
+    /**
+     * The list of all the direct ancestors of the current declaration.
+     * Note that the ancestor can be parametrized types with values specified. For example:
+     * <p>
+     * class A implements Comparable&lt;String&gt; {}
+     * <p>
+     * In this case the ancestor is Comparable&lt;String&gt;
+     */
+    List<ResolvedReferenceType> getAncestors();
+
+    /**
+     * The list of all the ancestors of the current declaration, direct and indirect.
+     * This list does not contains duplicates with the exacting same type parameters.
+     */
+    default List<ResolvedReferenceType> getAllAncestors() {
+        List<ResolvedReferenceType> ancestors = new ArrayList<>();
+        // We want to avoid infinite recursion in case of Object having Object as ancestor
+        if (!(Object.class.getCanonicalName().equals(getQualifiedName()))) {       
+            for (ResolvedReferenceType ancestor : getAncestors()) {
+                ancestors.add(ancestor);    
+                for (ResolvedReferenceType inheritedAncestor : ancestor.getAllAncestors()) {
+                    if (!ancestors.contains(inheritedAncestor)) {
+                        ancestors.add(inheritedAncestor);
+                    }
+                }
+            }
+        }
+        return ancestors;
+    }
+
+    ///
+    /// Fields
+    ///
+
+    /**
+     * Note that the type of the field should be expressed using the type variables of this particular type.
+     * Consider for example:
+     * <p>
+     * class Foo<E> { E field; }
+     * <p>
+     * class Bar extends Foo<String> { }
+     * <p>
+     * When calling getField("field") on Foo I should get a FieldDeclaration with type E, while calling it on
+     * Bar I should get a FieldDeclaration with type String.
+     */
+    default ResolvedFieldDeclaration getField(String name) {
+        Optional<ResolvedFieldDeclaration> field = this.getAllFields().stream().filter(f -> f.getName().equals(name)).findFirst();
+        if (field.isPresent()) {
+            return field.get();
+        } else {
+            throw new UnsolvedSymbolException("Field not found: " + name);
+        }
+    }
+
+    /**
+     * Consider only field or inherited field which is not private.
+     */
+    default ResolvedFieldDeclaration getVisibleField(String name) {
+        Optional<ResolvedFieldDeclaration> field = getVisibleFields().stream().filter(f -> f.getName().equals(name)).findFirst();
+        if (field.isPresent()) {
+            return field.get();
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
+     * Has this type a field with the given name?
+     */
+    default boolean hasField(String name) {
+        return this.getAllFields().stream().filter(f -> f.getName().equals(name)).findFirst().isPresent();
+    }
+
+    /**
+     * Either a declared field or inherited field which is not private.
+     */
+    default boolean hasVisibleField(String name) {
+        return getVisibleFields().stream().filter(f -> f.getName().equals(name)).findFirst().isPresent();
+    }
+
+    /**
+     * Return a list of all fields, either declared in this declaration or inherited.
+     */
+    List<ResolvedFieldDeclaration> getAllFields();
+
+    /**
+     * Return a list of all fields declared and the inherited ones which are not private.
+     */
+    default List<ResolvedFieldDeclaration> getVisibleFields() {
+        return getAllFields().stream()
+                .filter(f -> f.declaringType().equals(this) || f.accessSpecifier() != AccessSpecifier.PRIVATE)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * Return a list of all the non static fields, either declared or inherited.
+     */
+    default List<ResolvedFieldDeclaration> getAllNonStaticFields() {
+        return getAllFields().stream().filter(it -> !it.isStatic()).collect(Collectors.toList());
+    }
+
+    /**
+     * Return a list of all the static fields, either declared or inherited.
+     */
+    default List<ResolvedFieldDeclaration> getAllStaticFields() {
+        return getAllFields().stream().filter(it -> it.isStatic()).collect(Collectors.toList());
+    }
+
+    /**
+     * Return a list of all the fields declared in this type.
+     */
+    default List<ResolvedFieldDeclaration> getDeclaredFields() {
+        return getAllFields().stream().filter(it -> it.declaringType().getQualifiedName().equals(getQualifiedName())).collect(Collectors.toList());
+    }
+
+    ///
+    /// Methods
+    ///
+
+    /**
+     * Return a list of all the methods declared in this type declaration.
+     */
+    Set<ResolvedMethodDeclaration> getDeclaredMethods();
+
+    /**
+     * Return a list of all the methods declared of this type declaration, either declared or inherited.
+     * Note that it should not include overridden methods.
+     */
+    Set<MethodUsage> getAllMethods();
+
+    ///
+    /// Assignability
+    ///
+
+    /**
+     * Can we assign instances of the given type to variables having the type defined
+     * by this declaration?
+     */
+    boolean isAssignableBy(ResolvedType type);
+
+    /**
+     * Can we assign instances of the type defined by this declaration to variables having the type defined
+     * by the given type?
+     */
+    default boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+        return other.isAssignableBy(this);
+    }
+
+    /**
+     * Can we assign instances of the given type to variables having the type defined
+     * by this declaration?
+     */
+    boolean isAssignableBy(ResolvedReferenceTypeDeclaration other);
+
+    ///
+    /// Annotations
+    ///
+
+    /**
+     * Has the type at least one annotation declared having the specified qualified name?
+     */
+    boolean hasDirectlyAnnotation(String qualifiedName);
+
+    /**
+     * Has the type at least one annotation declared or inherited having the specified qualified name?
+     */
+    default boolean hasAnnotation(String qualifiedName) {
+        if (hasDirectlyAnnotation(qualifiedName)) {
+            return true;
+        }
+        return getAllAncestors().stream().anyMatch(it -> it.asReferenceType().getTypeDeclaration().hasDirectlyAnnotation(qualifiedName));
+    }
+
+    /**
+     * This means that the type has a functional method. Conceptually, a functional interface has exactly one abstract method.
+     * Typically these classes has the FunctionInterface annotation but this is not mandatory.
+     */
+    boolean isFunctionalInterface();
+
+    ///
+    /// Type parameters
+    ///
+
+    @Override
+    default Optional<ResolvedTypeParameterDeclaration> findTypeParameter(String name) {
+        for (ResolvedTypeParameterDeclaration tp : this.getTypeParameters()) {
+            if (tp.getName().equals(name)) {
+                return Optional.of(tp);
+            }
+        }
+        if (this.containerType().isPresent()) {
+            return this.containerType().get().findTypeParameter(name);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeDeclaration.java
new file mode 100644
index 0000000..0b715fe
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeDeclaration.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * A declaration of a type. It could be a primitive type, an enum, a class, an interface
+ * or a type variable.
+ * It cannot be an annotation or an array.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeDeclaration extends ResolvedDeclaration {
+
+    ///
+    /// Containment
+    ///
+
+    /**
+     * Get the list of types defined inside the current type.
+     */
+    default Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        throw new UnsupportedOperationException("InternalTypes not available for " + this.getClass().getCanonicalName());
+    }
+
+    /**
+     * Returns a type declaration for the internal type based on name.
+     * (Does not include internal types inside internal types).
+     */
+    default ResolvedReferenceTypeDeclaration getInternalType(String name) {
+        Optional<ResolvedReferenceTypeDeclaration> type =
+                this.internalTypes().stream().filter(f -> f.getName().equals(name)).findFirst();
+        return type.orElseThrow(() ->
+                new UnsolvedSymbolException("Internal type not found: " + name));
+    }
+
+    /**
+     * Does this type contain an internal type with the given name?
+     * (Does not include internal types inside internal types).
+     */
+    default boolean hasInternalType(String name) {
+        return this.internalTypes().stream().anyMatch(f -> f.getName().equals(name));
+    }
+
+    /**
+     * Get the ReferenceTypeDeclaration enclosing this declaration.
+     *
+     * @return
+     */
+    Optional<ResolvedReferenceTypeDeclaration> containerType();
+
+    ///
+    /// Misc
+    ///
+
+    /**
+     * Is this the declaration of a class?
+     * Note that an Enum is not considered a Class in this case.
+     */
+    default boolean isClass() {
+        return false;
+    }
+
+    /**
+     * Is this the declaration of an interface?
+     */
+    default boolean isInterface() {
+        return false;
+    }
+
+    /**
+     * Is this the declaration of an enum?
+     */
+    default boolean isEnum() {
+        return false;
+    }
+
+    /**
+     * Is this the declaration of a type parameter?
+     */
+    default boolean isTypeParameter() {
+        return false;
+    }
+
+    @Override
+    default boolean isType() {
+        return true;
+    }
+
+    /**
+     * Is this type declaration corresponding to an anonymous class?
+     *
+     * This is an example of anonymous class:
+     * <pre>
+     * HelloWorld frenchGreeting = new HelloWorld() {
+     *     String name = "tout le monde";
+     *
+     *     public void greet() {
+     *         greetSomeone("tout le monde");
+     *     }
+     *
+     *     public void greetSomeone(String someone) {
+     *         name = someone;
+     *         System.out.println("Salut " + name);
+     *     }
+     * };
+     * </pre>
+     */
+    default boolean isAnonymousClass() {
+        return false;
+    }
+
+    @Override
+    default ResolvedTypeDeclaration asType() {
+        return this;
+    }
+
+    /**
+     * Return this as a ClassDeclaration or throw UnsupportedOperationException.
+     */
+    default ResolvedClassDeclaration asClass() {
+        throw new UnsupportedOperationException(String.format("%s is not a class", this));
+    }
+
+    /**
+     * Return this as a InterfaceDeclaration or throw UnsupportedOperationException.
+     */
+    default ResolvedInterfaceDeclaration asInterface() {
+        throw new UnsupportedOperationException(String.format("%s is not an interface", this));
+    }
+
+    /**
+     * Return this as a EnumDeclaration or throw UnsupportedOperationException.
+     */
+    default ResolvedEnumDeclaration asEnum() {
+        throw new UnsupportedOperationException(String.format("%s is not an enum", this));
+    }
+
+    /**
+     * Return this as a TypeParameterDeclaration or throw UnsupportedOperationException.
+     */
+    default ResolvedTypeParameterDeclaration asTypeParameter() {
+        throw new UnsupportedOperationException(String.format("%s is not a type parameter", this));
+    }
+
+    default ResolvedReferenceTypeDeclaration asReferenceType() {
+        throw new UnsupportedOperationException(String.format("%s is not a reference type", this));
+    }
+
+    /**
+     * The package name of the type.
+     */
+    String getPackageName();
+
+    /**
+     * The class(es) wrapping this type.
+     */
+    String getClassName();
+
+    /**
+     * The fully qualified name of the type declared.
+     */
+    String getQualifiedName();
+
+    /**
+     * The ID corresponds most of the type to the qualified name. It differs only for local
+     * classes which do not have a qualified name but have an ID.
+     */
+    default String getId() {
+        String qname = getQualifiedName();
+        if (qname == null) {
+            return String.format("<localClass>:%s", getName());
+        }
+        return qname;
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParameterDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParameterDeclaration.java
new file mode 100644
index 0000000..14326db
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParameterDeclaration.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Declaration of a type parameter.
+ * For example:
+ * <p>
+ * class A&lt;E extends String&gt;{}
+ * </p>
+ * <p>
+ * In this case <b>E</b> would be a type parameter.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParameterDeclaration extends ResolvedTypeDeclaration {
+
+    /**
+     * Instantiate a TypeParameter defined on a Type with the given data.
+     */
+    static ResolvedTypeParameterDeclaration onType(final String name, String classQName, List<Bound> bounds) {
+        return new ResolvedTypeParameterDeclaration() {
+            @Override
+            public String getName() {
+                return name;
+            }
+
+            @Override
+            public boolean declaredOnType() {
+                return true;
+            }
+
+            @Override
+            public boolean declaredOnMethod() {
+                return false;
+            }
+
+            @Override
+            public boolean declaredOnConstructor() {
+                return false;
+            }
+
+            @Override
+            public String getContainerQualifiedName() {
+                return classQName;
+            }
+
+            @Override
+            public String getContainerId() {
+                return classQName;
+            }
+            
+            @Override
+            public ResolvedTypeParametrizable getContainer() {
+                return null;
+            }
+
+            @Override
+            public List<Bound> getBounds() {
+                return bounds;
+            }
+
+            @Override
+            public String toString() {
+                return "TypeParameter onType " + name;
+            }
+
+            @Override
+            public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+                throw new UnsupportedOperationException();
+            }
+        };
+    }
+
+    /**
+     * Name of the type parameter.
+     */
+    String getName();
+
+    /**
+     * Is the type parameter been defined on a type?
+     */
+    default boolean declaredOnType() {
+        return (getContainer() instanceof ResolvedReferenceTypeDeclaration);
+    }
+
+    /**
+     * Is the type parameter been defined on a method?
+     */
+    default boolean declaredOnMethod() {
+        return (getContainer() instanceof ResolvedMethodDeclaration);
+    }
+
+    /**
+     * Is the type parameter been defined on a constructor?
+     */
+    default boolean declaredOnConstructor() {
+        return (getContainer() instanceof ResolvedConstructorDeclaration);
+    }
+
+    /**
+     * The package name of the type bound(s).
+     * This is unsupported because there is no package for a Type Parameter, only for its container.
+     */
+    default String getPackageName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * The class(es) wrapping the type bound(s).
+     * This is unsupported because there is no class for a Type Parameter, only for its container.
+     */
+    default String getClassName() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * The qualified name of the Type Parameter.
+     * It is composed by the qualified name of the container followed by a dot and the name of the Type Parameter.
+     * The qualified name of a method is its qualified signature.
+     */
+    default String getQualifiedName() {
+        return String.format("%s.%s", getContainerId(), getName());
+    }
+
+    /**
+     * The qualified name of the container.
+     */
+    String getContainerQualifiedName();
+
+    /**
+     * The ID of the container. See TypeContainer.getId
+     */
+    String getContainerId();
+    
+    /**
+     * The TypeParametrizable of the container. Can be either a ReferenceTypeDeclaration or a MethodLikeDeclaration
+     */
+    ResolvedTypeParametrizable getContainer();
+
+    /**
+     * The bounds specified for the type parameter.
+     * For example:
+     * "extends A" or "super B"
+     */
+    List<Bound> getBounds();
+
+    /**
+     * Has the type parameter a lower bound?
+     */
+    default boolean hasLowerBound() {
+        for (Bound b : getBounds()) {
+            if (b.isExtends()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Has the type parameter an upper bound?
+     */
+    default boolean hasUpperBound() {
+        for (Bound b : getBounds()) {
+            if (b.isSuper()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the type used as lower bound.
+     *
+     * @throws IllegalStateException if there is no lower bound
+     */
+    default ResolvedType getLowerBound() {
+        for (Bound b : getBounds()) {
+            if (b.isExtends()) {
+                return b.getType();
+            }
+        }
+        throw new IllegalStateException();
+    }
+
+    /**
+     * Get the type used as upper bound.
+     *
+     * @throws IllegalStateException if there is no upper bound
+     */
+    default ResolvedType getUpperBound() {
+        for (Bound b : getBounds()) {
+            if (b.isSuper()) {
+                return b.getType();
+            }
+        }
+        throw new IllegalStateException();
+    }
+
+    /**
+     * A Bound on a Type Parameter.
+     */
+    class Bound {
+        private boolean extendsBound;
+        private ResolvedType type;
+
+        private Bound(boolean extendsBound, ResolvedType type) {
+            this.extendsBound = extendsBound;
+            this.type = type;
+        }
+
+        /**
+         * Create an extends bound with the given type:
+         * <p>
+         * extends "given type"
+         * </p>
+         */
+        public static Bound extendsBound(ResolvedType type) {
+            return new Bound(true, type);
+        }
+
+        /**
+         * Create a super bound with the given type:
+         * <p>
+         * super "given type"
+         * </p>
+         */
+        public static Bound superBound(ResolvedType type) {
+            return new Bound(false, type);
+        }
+
+        /**
+         * Get the type used in the Bound.
+         */
+        public ResolvedType getType() {
+            return type;
+        }
+
+        /**
+         * Is this an extends bound?
+         */
+        public boolean isExtends() {
+            return extendsBound;
+        }
+
+        /**
+         * Is this a super bound?
+         */
+        public boolean isSuper() {
+            return !isExtends();
+        }
+
+        @Override
+        public String toString() {
+            return "Bound{" +
+                    "extendsBound=" + extendsBound +
+                    ", type=" + type +
+                    '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            Bound bound = (Bound) o;
+
+            if (extendsBound != bound.extendsBound) return false;
+            return type != null ? type.equals(bound.type) : bound.type == null;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = (extendsBound ? 1 : 0);
+            result = 31 * result + (type != null ? type.hashCode() : 0);
+            return result;
+        }
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParametrizable.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParametrizable.java
new file mode 100644
index 0000000..3d6b92e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedTypeParametrizable.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * An entity which has type parameter.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParametrizable {
+
+    /**
+     * The list of type parameters defined on this element.
+     */
+    List<ResolvedTypeParameterDeclaration> getTypeParameters();
+
+    /**
+     * Find the closest TypeParameterDeclaration with the given name.
+     * It first look on this element itself and then on the containers.
+     */
+    Optional<ResolvedTypeParameterDeclaration> findTypeParameter(String name);
+
+    default boolean isGeneric() {
+        return !getTypeParameters().isEmpty();
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedValueDeclaration.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedValueDeclaration.java
new file mode 100644
index 0000000..ee6230a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/declarations/ResolvedValueDeclaration.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.declarations;
+
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * Declaration of a value.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedValueDeclaration extends ResolvedDeclaration {
+
+    /**
+     * Type of the declaration.
+     */
+    ResolvedType getType();
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedArrayType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedArrayType.java
new file mode 100644
index 0000000..bc422f7
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedArrayType.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.Map;
+
+/**
+ * Array Type.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedArrayType implements ResolvedType {
+
+    private ResolvedType baseType;
+
+    public ResolvedArrayType(ResolvedType baseType) {
+        this.baseType = baseType;
+    }
+
+    ///
+    /// Object methods
+    ///
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ResolvedArrayType that = (ResolvedArrayType) o;
+
+        if (!baseType.equals(that.baseType)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return baseType.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "ResolvedArrayType{" + baseType + "}";
+    }
+
+    ///
+    /// Type methods
+    ///
+
+    @Override
+    public ResolvedArrayType asArrayType() {
+        return this;
+    }
+
+    @Override
+    public boolean isArray() {
+        return true;
+    }
+
+    @Override
+    public String describe() {
+        return baseType.describe() + "[]";
+    }
+
+    public ResolvedType getComponentType() {
+        return baseType;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        if (other.isArray()) {
+            if (baseType.isPrimitive() && other.asArrayType().getComponentType().isPrimitive()) {
+              return baseType.equals(other.asArrayType().getComponentType());
+            }
+            return baseType.isAssignableBy(other.asArrayType().getComponentType());
+        } else if (other.isNull()) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        ResolvedType baseTypeReplaced = baseType.replaceTypeVariables(tpToReplace, replaced, inferredTypes);
+        if (baseTypeReplaced == baseType) {
+            return this;
+        } else {
+            return new ResolvedArrayType(baseTypeReplaced);
+        }
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedIntersectionType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedIntersectionType.java
new file mode 100644
index 0000000..e308fea
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedIntersectionType.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * An intersection type is defined in java as list of types separates by ampersands.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedIntersectionType implements ResolvedType {
+    private List<ResolvedType> elements;
+
+    public ResolvedIntersectionType(Collection<ResolvedType> elements) {
+        if (elements.size() < 2) {
+            throw new IllegalArgumentException("An intersection type should have at least two elements. This has " + elements.size());
+        }
+        this.elements = new LinkedList<>(elements);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ResolvedIntersectionType that = (ResolvedIntersectionType) o;
+
+        return new HashSet<>(elements).equals(new HashSet<>(that.elements));
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashSet<>(elements).hashCode();
+    }
+
+    @Override
+    public String describe() {
+        return String.join(" & ", elements.stream().map(ResolvedType::describe).collect(Collectors.toList()));
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        return elements.stream().allMatch(e -> e.isAssignableBy(other));
+    }
+
+    @Override
+    public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        List<ResolvedType> elementsReplaced = elements.stream()
+                .map(e -> e.replaceTypeVariables(tp, replaced, inferredTypes))
+                .collect(Collectors.toList());
+        if (elementsReplaced.equals(elements)) {
+            return this;
+        } else {
+            return new ResolvedIntersectionType(elementsReplaced);
+        }
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedLambdaConstraintType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedLambdaConstraintType.java
new file mode 100644
index 0000000..e43d434
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedLambdaConstraintType.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+public class ResolvedLambdaConstraintType implements ResolvedType {
+    private ResolvedType bound;
+
+    private ResolvedLambdaConstraintType(ResolvedType bound) {
+        this.bound = bound;
+    }
+
+    @Override
+    public String describe() {
+        return "? super " + bound.describe();
+    }
+
+    public ResolvedType getBound() {
+        return bound;
+    }
+
+    @Override
+    public boolean isConstraint() {
+        return true;
+    }
+
+    @Override
+    public ResolvedLambdaConstraintType asConstraintType() {
+        return this;
+    }
+
+    public static ResolvedLambdaConstraintType bound(ResolvedType bound){
+        return new ResolvedLambdaConstraintType(bound);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        return bound.isAssignableBy(other);
+    }
+
+    @Override
+    public String toString() {
+        return "LambdaConstraintType{" +
+                "bound=" + bound +
+                '}';
+    }
+}
\ No newline at end of file
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedPrimitiveType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedPrimitiveType.java
new file mode 100644
index 0000000..4a7e292
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedPrimitiveType.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public enum ResolvedPrimitiveType implements ResolvedType {
+
+
+    BYTE("byte", Byte.class.getCanonicalName(), Collections.emptyList()),
+    SHORT("short", Short.class.getCanonicalName(), Collections.singletonList(BYTE)),
+    CHAR("char", Character.class.getCanonicalName(), Collections.emptyList()),
+    INT("int", Integer.class.getCanonicalName(), Arrays.asList(BYTE, SHORT, CHAR)),
+    LONG("long", Long.class.getCanonicalName(), Arrays.asList(BYTE, SHORT, INT, CHAR)),
+    BOOLEAN("boolean", Boolean.class.getCanonicalName(), Collections.emptyList()),
+    FLOAT("float", Float.class.getCanonicalName(), Arrays.asList(LONG, INT, SHORT, BYTE, CHAR)),
+    DOUBLE("double", Double.class.getCanonicalName(), Arrays.asList(FLOAT, LONG, INT, SHORT, BYTE, CHAR));
+
+    ///
+    /// Fields
+    ///
+
+    private String name;
+    private String boxTypeQName;
+    private List<ResolvedPrimitiveType> promotionTypes;
+
+    private ResolvedPrimitiveType(String name, String boxTypeQName, List<ResolvedPrimitiveType> promotionTypes) {
+        this.name = name;
+        this.boxTypeQName = boxTypeQName;
+        this.promotionTypes = promotionTypes;
+    }
+
+    public static ResolvedType byName(String name) {
+        name = name.toLowerCase();
+        for (ResolvedPrimitiveType ptu : values()) {
+            if (ptu.describe().equals(name)) {
+                return ptu;
+            }
+        }
+        throw new IllegalArgumentException("Name " + name);
+    }
+
+    @Override
+    public String toString() {
+        return "PrimitiveTypeUsage{" +
+                "name='" + name + '\'' +
+                '}';
+    }
+
+    public ResolvedPrimitiveType asPrimitive() {
+        return this;
+    }
+
+    @Override
+    public boolean isArray() {
+        return false;
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return true;
+    }
+
+    @Override
+    public boolean isReferenceType() {
+        return false;
+    }
+
+    @Override
+    public String describe() {
+        return name;
+    }
+
+    @Override
+    public boolean isTypeVariable() {
+        return false;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        if (other.isPrimitive()) {
+            return this == other || promotionTypes.contains(other);
+        } else if (other.isReferenceType()) {
+            if (other.asReferenceType().getQualifiedName().equals(boxTypeQName)) {
+                return true;
+            }
+            for (ResolvedPrimitiveType promotion : promotionTypes) {
+                if (other.asReferenceType().getQualifiedName().equals(promotion.boxTypeQName)) {
+                    return true;
+                }
+            }
+            return false;
+        } else if (other.isConstraint()){
+            return this.isAssignableBy(other.asConstraintType().getBound());
+        } else {
+            return false;
+        }
+    }
+
+    public String getBoxTypeQName() {
+        return boxTypeQName;
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java
new file mode 100644
index 0000000..4fecaf6
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedReferenceType.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParameterValueProvider;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametrized;
+import com.github.javaparser.utils.Pair;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * A ReferenceType like a class, an interface or an enum. Note that this type can contain also the values
+ * specified for the type parameters.
+ *
+ * @author Federico Tomassetti
+ */
+public abstract class ResolvedReferenceType implements ResolvedType,
+        ResolvedTypeParametrized, ResolvedTypeParameterValueProvider {
+
+    //
+    // Fields
+    //
+
+    protected ResolvedReferenceTypeDeclaration typeDeclaration;
+    protected ResolvedTypeParametersMap typeParametersMap;
+
+    //
+    // Constructors
+    //
+
+    public ResolvedReferenceType(ResolvedReferenceTypeDeclaration typeDeclaration) {
+        this(typeDeclaration, deriveParams(typeDeclaration));
+    }
+
+    public ResolvedReferenceType(ResolvedReferenceTypeDeclaration typeDeclaration, List<ResolvedType> typeArguments) {
+        if (typeDeclaration.isTypeParameter()) {
+            throw new IllegalArgumentException("You should use only Classes, Interfaces and enums");
+        }
+        if (typeArguments.size() > 0 && typeArguments.size() != typeDeclaration.getTypeParameters().size()) {
+            throw new IllegalArgumentException(String.format(
+                    "expected either zero type arguments or has many as defined in the declaration (%d). Found %d",
+                    typeDeclaration.getTypeParameters().size(), typeArguments.size()));
+        }
+        ResolvedTypeParametersMap.Builder typeParametersMapBuilder = new ResolvedTypeParametersMap.Builder();
+        for (int i = 0; i < typeArguments.size(); i++) {
+            typeParametersMapBuilder.setValue(typeDeclaration.getTypeParameters().get(i), typeArguments.get(i));
+        }
+        this.typeParametersMap = typeParametersMapBuilder.build();
+        this.typeDeclaration = typeDeclaration;
+    }
+
+    //
+    // Public Object methods
+    //
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ResolvedReferenceType that = (ResolvedReferenceType) o;
+
+        if (!typeDeclaration.equals(that.typeDeclaration)) return false;
+        if (!typeParametersMap.equals(that.typeParametersMap)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = typeDeclaration.hashCode();
+        result = 31 * result + typeParametersMap.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "ReferenceType{" + getQualifiedName() +
+                ", typeParametersMap=" + typeParametersMap +
+                '}';
+    }
+
+    ///
+    /// Relation with other types
+    ///
+
+    @Override
+    public final boolean isReferenceType() {
+        return true;
+    }
+
+    ///
+    /// Downcasting
+    ///
+
+    @Override
+    public ResolvedReferenceType asReferenceType() {
+        return this;
+    }
+
+    ///
+    /// Naming
+    ///
+
+    @Override
+    public String describe() {
+        StringBuilder sb = new StringBuilder();
+        if (hasName()) {
+            sb.append(typeDeclaration.getQualifiedName());
+        } else {
+            sb.append("<anonymous class>");
+        }
+        if (!typeParametersMap().isEmpty()) {
+            sb.append("<");
+            sb.append(String.join(", ", typeDeclaration.getTypeParameters().stream()
+                    .map(tp -> typeParametersMap().getValue(tp).describe())
+                    .collect(Collectors.toList())));
+            sb.append(">");
+        }
+        return sb.toString();
+    }
+
+    ///
+    /// TypeParameters
+    ///
+
+    /**
+     * Execute a transformation on all the type parameters of this element.
+     */
+    public abstract ResolvedType transformTypeParameters(ResolvedTypeTransformer transformer);
+
+    @Override
+    public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced,
+                                     Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        if (replaced == null) {
+            throw new IllegalArgumentException();
+        }
+
+        ResolvedReferenceType result = this;
+        int i = 0;
+        for (ResolvedType tp : this.typeParametersValues()) {
+            ResolvedType transformedTp = tp.replaceTypeVariables(tpToReplace, replaced, inferredTypes);
+            // Identity comparison on purpose
+            if (tp.isTypeVariable() && tp.asTypeVariable().describe().equals(tpToReplace.getName())) {
+                inferredTypes.put(tp.asTypeParameter(), replaced);
+            }
+            // FIXME
+            if (true) {
+                List<ResolvedType> typeParametersCorrected = result.asReferenceType().typeParametersValues();
+                typeParametersCorrected.set(i, transformedTp);
+                result = create(typeDeclaration, typeParametersCorrected);
+            }
+            i++;
+        }
+
+        List<ResolvedType> values = result.typeParametersValues();
+        // FIXME
+        if(values.contains(tpToReplace)){
+            int index = values.indexOf(tpToReplace);
+            values.set(index, replaced);
+            return create(result.getTypeDeclaration(), values);
+        }
+
+        return result;
+    }
+
+    ///
+    /// Assignability
+    ///
+
+    /**
+     * This method checks if ThisType t = new OtherType() would compile.
+     */
+    @Override
+    public abstract boolean isAssignableBy(ResolvedType other);
+
+    ///
+    /// Ancestors
+    ///
+
+    /**
+     * Return all ancestors, that means all superclasses and interfaces.
+     * This list should always include Object (unless this is a reference to Object).
+     * The type typeParametersValues should be expressed in terms of this type typeParametersValues.
+     * <p>
+     * For example, given:
+     * <p>
+     * class Foo&lt;A, B&gt; {}
+     * class Bar&lt;C&gt; extends Foo&lt;C, String&gt; {}
+     * <p>
+     * a call to getAllAncestors on a reference to Bar having type parameter Boolean should include
+     * Foo&lt;Boolean, String&gt;.
+     */
+    public abstract List<ResolvedReferenceType> getAllAncestors();
+
+    public final List<ResolvedReferenceType> getAllInterfacesAncestors() {
+        return getAllAncestors().stream()
+                .filter(it -> it.getTypeDeclaration().isInterface())
+                .collect(Collectors.toList());
+    }
+
+    public final List<ResolvedReferenceType> getAllClassesAncestors() {
+        return getAllAncestors().stream()
+                .filter(it -> it.getTypeDeclaration().isClass())
+                .collect(Collectors.toList());
+    }
+
+    ///
+    /// Type parameters
+    ///
+
+    /**
+     * Get the type associated with the type parameter with the given name.
+     * It returns Optional.empty unless the type declaration declares a type parameter with the given name.
+     */
+    public Optional<ResolvedType> getGenericParameterByName(String name) {
+        for (ResolvedTypeParameterDeclaration tp : typeDeclaration.getTypeParameters()) {
+            if (tp.getName().equals(name)) {
+                return Optional.of(this.typeParametersMap().getValue(tp));
+            }
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * Get the values for all type parameters declared on this type.
+     * The list can be empty for raw types.
+     */
+    public List<ResolvedType> typeParametersValues() {
+        return this.typeParametersMap.isEmpty() ? Collections.emptyList() : typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap.getValue(tp)).collect(Collectors.toList());
+    }
+
+    /**
+     * Get the values for all type parameters declared on this type.
+     * In case of raw types the values correspond to TypeVariables.
+     */
+    public List<Pair<ResolvedTypeParameterDeclaration, ResolvedType>> getTypeParametersMap() {
+        List<Pair<ResolvedTypeParameterDeclaration, ResolvedType>> typeParametersMap = new ArrayList<>();
+        if (!isRawType()) {
+	        for (int i = 0; i < typeDeclaration.getTypeParameters().size(); i++) {
+	            typeParametersMap.add(new Pair<>(typeDeclaration.getTypeParameters().get(0), typeParametersValues().get(i)));
+	        }
+        }
+        return typeParametersMap;
+    }
+
+    @Override
+    public ResolvedTypeParametersMap typeParametersMap() {
+        return typeParametersMap;
+    }
+
+    ///
+    /// Other methods introduced by ReferenceType
+    ///
+
+    /**
+     * Corresponding TypeDeclaration
+     */
+    public final ResolvedReferenceTypeDeclaration getTypeDeclaration() {
+        return typeDeclaration;
+    }
+
+    /**
+     * The type of the field could be different from the one in the corresponding FieldDeclaration because
+     * type variables would be solved.
+     */
+    public Optional<ResolvedType> getFieldType(String name) {
+        if (!typeDeclaration.hasField(name)) {
+            return Optional.empty();
+        }
+        ResolvedType type = typeDeclaration.getField(name).getType();
+        type = useThisTypeParametersOnTheGivenType(type);
+        return Optional.of(type);
+    }
+
+    /**
+     * Has the TypeDeclaration a name? Anonymous classes do not have one.
+     */
+    public boolean hasName() {
+        return typeDeclaration.hasName();
+    }
+
+    /**
+     * Qualified name of the declaration.
+     */
+    public String getQualifiedName() {
+        return typeDeclaration.getQualifiedName();
+    }
+
+    /**
+     * Id of the declaration. It corresponds to the qualified name, unless for local classes.
+     */
+    public String getId() {
+        return typeDeclaration.getId();
+    }
+
+    /**
+     * Methods declared on this type.
+     */
+    public abstract Set<MethodUsage> getDeclaredMethods();
+
+    public boolean isRawType() {
+        if (!typeDeclaration.getTypeParameters().isEmpty()) {
+            if (typeParametersMap().isEmpty()) {
+                return true;
+            }
+            for (String name : typeParametersMap().getNames()) {
+                Optional<ResolvedType> value = typeParametersMap().getValueBySignature(name);
+                if (value.isPresent() && value.get().isTypeVariable() && value.get().asTypeVariable().qualifiedName().equals(name)) {
+                    // nothing to do
+                } else {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public Optional<ResolvedType> typeParamValue(ResolvedTypeParameterDeclaration typeParameterDeclaration) {
+        if (typeParameterDeclaration.declaredOnMethod()) {
+            throw new IllegalArgumentException();
+        }
+        String typeId = this.getTypeDeclaration().getId();
+        if (typeId.equals(typeParameterDeclaration.getContainerId())) {
+            return Optional.of(this.typeParametersMap().getValue(typeParameterDeclaration));
+        }
+        for (ResolvedReferenceType ancestor : this.getAllAncestors()) {
+            if (ancestor.getId().equals(typeParameterDeclaration.getContainerId())) {
+                return Optional.of(ancestor.typeParametersMap().getValue(typeParameterDeclaration));
+            }
+        }
+        return Optional.empty();
+    }
+
+    public abstract ResolvedType toRawType();
+
+    //
+    // Protected methods
+    //
+
+    protected abstract ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration, List<ResolvedType> typeParameters);
+
+    protected ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration, ResolvedTypeParametersMap typeParametersMap) {
+        return create(typeDeclaration, typeDeclaration.getTypeParameters().stream()
+                .map(typeParametersMap::getValue)
+                .collect(Collectors.toList()));
+    }
+
+    protected abstract ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration);
+
+    protected boolean isCorrespondingBoxingType(String typeName) {
+        switch (typeName) {
+            case "boolean":
+                return getQualifiedName().equals(Boolean.class.getCanonicalName());
+            case "char":
+                return getQualifiedName().equals(Character.class.getCanonicalName());
+            case "byte":
+                return getQualifiedName().equals(Byte.class.getCanonicalName());
+            case "short":
+                return getQualifiedName().equals(Short.class.getCanonicalName());
+            case "int":
+                return getQualifiedName().equals(Integer.class.getCanonicalName());
+            case "long":
+                return getQualifiedName().equals(Long.class.getCanonicalName());
+            case "float":
+                return getQualifiedName().equals(Float.class.getCanonicalName());
+            case "double":
+                return getQualifiedName().equals(Double.class.getCanonicalName());
+            default:
+                throw new UnsupportedOperationException(typeName);
+        }
+    }
+
+    protected boolean compareConsideringTypeParameters(ResolvedReferenceType other) {
+        if (other.equals(this)) {
+            return true;
+        }
+        if (this.getQualifiedName().equals(other.getQualifiedName())) {
+            if (this.isRawType() || other.isRawType()) {
+                return true;
+            }
+            if (this.typeParametersValues().size() != other.typeParametersValues().size()) {
+                throw new IllegalStateException();
+            }
+            for (int i = 0; i < typeParametersValues().size(); i++) {
+                ResolvedType thisParam = typeParametersValues().get(i);
+                ResolvedType otherParam = other.typeParametersValues().get(i);
+                if (!thisParam.equals(otherParam)) {
+                    if (thisParam instanceof ResolvedWildcard) {
+                        ResolvedWildcard thisParamAsWildcard = (ResolvedWildcard) thisParam;
+                        if (thisParamAsWildcard.isSuper() && otherParam.isAssignableBy(thisParamAsWildcard.getBoundedType())) {
+                            // ok
+                        } else if (thisParamAsWildcard.isExtends() && thisParamAsWildcard.getBoundedType().isAssignableBy(otherParam)) {
+                            // ok
+                        } else if (!thisParamAsWildcard.isBounded()) {
+                            // ok
+                        } else {
+                            return false;
+                        }
+                    } else {
+                        if (thisParam instanceof ResolvedTypeVariable && otherParam instanceof ResolvedTypeVariable) {
+                            List<ResolvedType> thisBounds = thisParam.asTypeVariable().asTypeParameter().getBounds().stream().map(bound -> bound.getType()).collect(Collectors.toList());
+                            List<ResolvedType> otherBounds = otherParam.asTypeVariable().asTypeParameter().getBounds().stream().map(bound -> bound.getType()).collect(Collectors.toList());
+                            if (thisBounds.size() == otherBounds.size() && otherBounds.containsAll(thisBounds)) {
+                                return true;
+                            }
+                        }
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    //
+    // Private methods
+    //
+
+    private static List<ResolvedType> deriveParams(ResolvedReferenceTypeDeclaration typeDeclaration) {
+        return typeDeclaration.getTypeParameters().stream().map((tp) -> new ResolvedTypeVariable(tp)).collect(Collectors.toList());
+    }
+
+    public abstract ResolvedReferenceType deriveTypeParameters(ResolvedTypeParametersMap typeParametersMap);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedType.java
new file mode 100644
index 0000000..d787b59
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedType.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A resolved type. It could be a primitive type or a reference type (enum, class, interface). In the later case it
+ * could take type typeParametersValues (other TypeUsages). It could also be a TypeVariable, like in:
+ * <p>
+ * class A&lt;Bgt; { }
+ * <p>
+ * where B is a TypeVariable. It could also be Wildcard Type, possibly with constraints.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedType {
+
+    ///
+    /// Relation with other types
+    ///
+
+    /**
+     * Does this type represent an array?
+     */
+    default boolean isArray() {
+        return false;
+    }
+
+    default int arrayLevel() {
+        if (isArray()) {
+            return 1 + this.asArrayType().getComponentType().arrayLevel();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Is this a primitive type?
+     */
+    default boolean isPrimitive() {
+        return false;
+    }
+
+    /**
+     * Is this the null type?
+     */
+    default boolean isNull() {
+        return false;
+    }
+
+    /**
+     * Is this a union type (as the ones used in multi catch clauses)?
+     */
+    default boolean isUnionType() {
+        return false;
+    }
+
+    /**
+     * Is this a non primitive value?
+     */
+    default boolean isReference() {
+        return isReferenceType() || isArray() || isTypeVariable() || isNull() || isWildcard() || isUnionType();
+    }
+
+    /**
+     * Is this a lambda constraint type?
+     */
+    default boolean isConstraint() { return false; }
+
+    /**
+     * Can this be seen as a ReferenceTypeUsage?
+     * In other words: is this a reference to a class, an interface or an enum?
+     */
+    default boolean isReferenceType() {
+        return false;
+    }
+
+    default boolean isVoid() {
+        return false;
+    }
+
+    default boolean isTypeVariable() {
+        return false;
+    }
+
+    default boolean isWildcard() {
+        return false;
+    }
+
+    ///
+    /// Downcasting
+    ///
+
+    default ResolvedArrayType asArrayType() {
+        throw new UnsupportedOperationException(String.format("%s is not an Array", this));
+    }
+
+    default ResolvedReferenceType asReferenceType() {
+        throw new UnsupportedOperationException(String.format("%s is not a Reference Type", this));
+    }
+
+    default ResolvedTypeParameterDeclaration asTypeParameter() {
+        throw new UnsupportedOperationException(String.format("%s is not a Type parameter", this));
+    }
+
+    default ResolvedTypeVariable asTypeVariable() {
+        throw new UnsupportedOperationException(String.format("%s is not a Type variable", this));
+    }
+
+    default ResolvedPrimitiveType asPrimitive() {
+        throw new UnsupportedOperationException(String.format("%s is not a Primitive type", this));
+    }
+
+    default ResolvedWildcard asWildcard() {
+        throw new UnsupportedOperationException(String.format("%s is not a Wildcard", this));
+    }
+
+    default ResolvedLambdaConstraintType asConstraintType() {
+        throw new UnsupportedOperationException(String.format("%s is not a constraint type", this));
+    }
+
+    default ResolvedUnionType asUnionType() {
+        throw new UnsupportedOperationException(String.format("%s is not a union type", this));
+    }
+
+    ///
+    /// Naming
+    ///
+
+    String describe();
+
+    ///
+    /// TypeParameters
+    ///
+
+    /**
+     * Replace all variables referring to the given TypeParameter with the given value.
+     * By replacing these values I could also infer some type equivalence.
+     * Those would be collected in the given map.
+     */
+    default ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        return this;
+    }
+
+    /**
+     * This is like ({@link #replaceTypeVariables(ResolvedTypeParameterDeclaration, ResolvedType, Map)} but ignores the inferred values.
+     */
+    default ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced) {
+        return replaceTypeVariables(tp, replaced, new HashMap<>());
+    }
+
+    /**
+     * Does this type mention at all, directly or indirectly, the given type parameters?
+     */
+    default boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+        throw new UnsupportedOperationException(this.getClass().getCanonicalName());
+    }
+
+    ///
+    /// Assignability
+    ///
+
+    /**
+     * This method checks if ThisType t = new OtherType() would compile.
+     */
+    boolean isAssignableBy(ResolvedType other);
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeTransformer.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeTransformer.java
new file mode 100644
index 0000000..a5eaebe
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeTransformer.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+/**
+ * @author Federico Tomassetti
+ */
+@FunctionalInterface
+public interface ResolvedTypeTransformer {
+    ResolvedType transform(ResolvedType type);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeVariable.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeVariable.java
new file mode 100644
index 0000000..5e91057
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedTypeVariable.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * From JLS 4.4: A type variable is introduced by the declaration of a type parameter of a generic class,
+ * interface, method, or constructor (§8.1.2, §9.1.2, §8.4.4, §8.8.4).
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedTypeVariable implements ResolvedType {
+
+    private ResolvedTypeParameterDeclaration typeParameter;
+
+    public ResolvedTypeVariable(ResolvedTypeParameterDeclaration typeParameter) {
+        this.typeParameter = typeParameter;
+    }
+
+    @Override
+    public String toString() {
+        return "TypeVariable {" + typeParameter.getQualifiedName() + "}";
+    }
+
+    public String qualifiedName() {
+        return this.typeParameter.getQualifiedName();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ResolvedTypeVariable that = (ResolvedTypeVariable) o;
+
+        if (!typeParameter.getName().equals(that.typeParameter.getName())) return false;
+        if (typeParameter.declaredOnType() != that.typeParameter.declaredOnType()) return false;
+        if (typeParameter.declaredOnMethod() != that.typeParameter.declaredOnMethod()) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return typeParameter.hashCode();
+    }
+
+    @Override
+    public boolean isArray() {
+        return false;
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return false;
+    }
+
+    @Override
+    public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToBeReplaced, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        if(tpToBeReplaced.getName().equals(this.typeParameter.getName())){
+            inferredTypes.put(this.asTypeParameter(), replaced);
+            return replaced;
+        } else {
+            return this;
+        }
+    }
+
+    @Override
+    public boolean isReferenceType() {
+        return false;
+    }
+
+    @Override
+    public String describe() {
+        return typeParameter.getName();
+    }
+
+    @Override
+    public ResolvedTypeParameterDeclaration asTypeParameter() {
+        return typeParameter;
+    }
+
+    @Override
+    public ResolvedTypeVariable asTypeVariable() {
+        return this;
+    }
+
+    @Override
+    public boolean isTypeVariable() {
+        return true;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        if (other.isTypeVariable()) {
+            return describe().equals(other.describe());
+        } else {
+            return true;
+        }
+    }
+
+    @Override
+    public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+        return typeParameters.contains(typeParameter);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedUnionType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedUnionType.java
new file mode 100644
index 0000000..bd5361a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedUnionType.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * A union type is defined in java as list of types separates by pipes.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedUnionType implements ResolvedType {
+    private List<ResolvedType> elements;
+
+    public ResolvedUnionType(List<ResolvedType> elements) {
+        if (elements.size() < 2) {
+            throw new IllegalArgumentException("An union type should have at least two elements. This has " + elements.size());
+        }
+        this.elements = new LinkedList<>(elements);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ResolvedUnionType that = (ResolvedUnionType) o;
+
+        return new HashSet<>(elements).equals(new HashSet<>(that.elements));
+    }
+
+    @Override
+    public int hashCode() {
+        return new HashSet<>(elements).hashCode();
+    }
+
+    @Override
+    public String describe() {
+        return String.join(" | ", elements.stream().map(ResolvedType::describe).collect(Collectors.toList()));
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        return elements.stream().allMatch(e -> e.isAssignableBy(other));
+    }
+
+    @Override
+    public boolean isUnionType() {
+        return true;
+    }
+
+    @Override
+    public ResolvedUnionType asUnionType() {
+        return this;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedVoidType.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedVoidType.java
new file mode 100644
index 0000000..b8f2194
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedVoidType.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+/**
+ * The special type void.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedVoidType implements ResolvedType {
+    public static final ResolvedType INSTANCE = new ResolvedVoidType();
+
+    private ResolvedVoidType() {
+    }
+
+    @Override
+    public String describe() {
+        return "void";
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isVoid() {
+        return true;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedWildcard.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedWildcard.java
new file mode 100644
index 0000000..51fd099
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/ResolvedWildcard.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A wildcard can be:
+ * - unbounded (?)
+ * - have a lower bound (? super Number)
+ * - have an upper bound (? extends Number)
+ * It is not possible to have both a lower and an upper bound at the same time.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedWildcard implements ResolvedType {
+
+    public static ResolvedWildcard UNBOUNDED = new ResolvedWildcard(null, null);
+
+    private BoundType type;
+    private ResolvedType boundedType;
+
+    private ResolvedWildcard(BoundType type, ResolvedType boundedType) {
+        if (type == null && boundedType != null) {
+            throw new IllegalArgumentException();
+        }
+        if (type != null && boundedType == null) {
+            throw new IllegalArgumentException();
+        }
+        this.type = type;
+        this.boundedType = boundedType;
+    }
+
+    public static ResolvedWildcard superBound(ResolvedType type) {
+        return new ResolvedWildcard(BoundType.SUPER, type);
+    }
+
+    public static ResolvedWildcard extendsBound(ResolvedType type) {
+        return new ResolvedWildcard(BoundType.EXTENDS, type);
+    }
+
+    @Override
+    public String toString() {
+        return "WildcardUsage{" +
+                "type=" + type +
+                ", boundedType=" + boundedType +
+                '}';
+    }
+
+    public boolean isWildcard() {
+        return true;
+    }
+
+    public ResolvedWildcard asWildcard() {
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ResolvedWildcard)) return false;
+
+        ResolvedWildcard that = (ResolvedWildcard) o;
+
+        if (boundedType != null ? !boundedType.equals(that.boundedType) : that.boundedType != null) return false;
+        if (type != that.type) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = type != null ? type.hashCode() : 0;
+        result = 31 * result + (boundedType != null ? boundedType.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String describe() {
+        if (type == null) {
+            return "?";
+        } else if (type == BoundType.SUPER) {
+            return "? super " + boundedType.describe();
+        } else if (type == BoundType.EXTENDS) {
+            return "? extends " + boundedType.describe();
+        } else {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public boolean isSuper() {
+        return type == BoundType.SUPER;
+    }
+
+    public boolean isExtends() {
+        return type == BoundType.EXTENDS;
+    }
+
+    public boolean isBounded() {
+        return isSuper() || isExtends();
+    }
+
+    public ResolvedType getBoundedType() {
+        if (boundedType == null) {
+            throw new IllegalStateException();
+        }
+        return boundedType;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        if (boundedType == null) {
+            //return other.isReferenceType() && other.asReferenceType().getQualifiedName().equals(Object.class.getCanonicalName());
+            return false;
+        } else if (type == BoundType.SUPER) {
+            return boundedType.isAssignableBy(other);
+        } else if (type == BoundType.EXTENDS) {
+            return false;
+        } else {
+            throw new RuntimeException();
+        }
+    }
+
+    @Override
+    public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tpToReplace, ResolvedType replaced, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        if (replaced == null) {
+            throw new IllegalArgumentException();
+        }
+        if (boundedType == null) {
+            return this;
+        }
+        ResolvedType boundedTypeReplaced = boundedType.replaceTypeVariables(tpToReplace, replaced, inferredTypes);
+        if (boundedTypeReplaced == null) {
+            throw new RuntimeException();
+        }
+        if (boundedTypeReplaced != boundedType) {
+            return new ResolvedWildcard(type, boundedTypeReplaced);
+        } else {
+            return this;
+        }
+    }
+
+    @Override
+    public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+        return boundedType != null && boundedType.mention(typeParameters);
+    }
+
+    public boolean isUpperBounded() {
+        return isSuper();
+    }
+
+    public boolean isLowerBounded() {
+        return isExtends();
+    }
+
+    public enum BoundType {
+        SUPER,
+        EXTENDS
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParameterValueProvider.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParameterValueProvider.java
new file mode 100644
index 0000000..c310fb5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParameterValueProvider.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types.parametrization;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedWildcard;
+
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParameterValueProvider {
+
+    /**
+     * Calculate the value for the given type parameter.
+     * It could be inherited.
+     */
+    Optional<ResolvedType> typeParamValue(ResolvedTypeParameterDeclaration typeParameterDeclaration);
+
+    /**
+     * Replace the type typeParametersValues present in the given type with the ones for which this type
+     * has a value.
+     */
+    default ResolvedType useThisTypeParametersOnTheGivenType(ResolvedType type) {
+        if (type.isTypeVariable()) {
+            ResolvedTypeParameterDeclaration typeParameter = type.asTypeParameter();
+            if (typeParameter.declaredOnType()) {
+                Optional<ResolvedType> typeParam = typeParamValue(typeParameter);
+                if (typeParam.isPresent()) {
+                    type = typeParam.get();
+                }
+            }
+        }
+
+        if (type.isWildcard() && type.asWildcard().isBounded()) {
+            if (type.asWildcard().isExtends()) {
+                return ResolvedWildcard.extendsBound(useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType()));
+            } else {
+                return ResolvedWildcard.superBound(useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType()));
+            }
+        }
+
+        if (type.isReferenceType()) {
+            type = type.asReferenceType().transformTypeParameters(this::useThisTypeParametersOnTheGivenType);
+        }
+
+        return type;
+    }
+
+    Optional<ResolvedType> getGenericParameterByName(String name);
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametersMap.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametersMap.java
new file mode 100644
index 0000000..b1cb16d
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametersMap.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types.parametrization;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+
+import java.util.*;
+
+/**
+ * A map of values associated to TypeParameters.
+ *
+ * @author Federico Tomassetti
+ */
+public class ResolvedTypeParametersMap {
+
+    public static class Builder {
+        private Map<String, ResolvedType> nameToValue;
+        private Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration;
+
+        public Builder() {
+            nameToValue = new HashMap<>();
+            nameToDeclaration = new HashMap<>();
+        }
+
+        private Builder(Map<String, ResolvedType> nameToValue,
+                        Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration) {
+            this.nameToValue = new HashMap<>();
+            this.nameToValue.putAll(nameToValue);
+            this.nameToDeclaration = new HashMap<>();
+            this.nameToDeclaration.putAll(nameToDeclaration);
+        }
+
+        public ResolvedTypeParametersMap build() {
+            return new ResolvedTypeParametersMap(nameToValue, nameToDeclaration);
+        }
+
+        public Builder setValue(ResolvedTypeParameterDeclaration typeParameter,
+                                ResolvedType value) {
+            // TODO: we shouldn't just silently overwrite existing types!
+            String qualifiedName = typeParameter.getQualifiedName();
+            nameToValue.put(qualifiedName, value);
+            nameToDeclaration.put(qualifiedName, typeParameter);
+            return this;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ResolvedTypeParametersMap)) return false;
+
+        ResolvedTypeParametersMap that = (ResolvedTypeParametersMap) o;
+
+        return nameToValue.equals(that.nameToValue) && nameToDeclaration.equals(that.nameToDeclaration);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return nameToValue.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "TypeParametersMap{" +
+                "nameToValue=" + nameToValue +
+                '}';
+    }
+
+    private Map<String, ResolvedType> nameToValue;
+    private Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration;
+
+    public static ResolvedTypeParametersMap empty() {
+        return new Builder().build();
+    }
+
+    private ResolvedTypeParametersMap(Map<String, ResolvedType> nameToValue,
+                                      Map<String, ResolvedTypeParameterDeclaration> nameToDeclaration) {
+        this.nameToValue = new HashMap<>();
+        this.nameToValue.putAll(nameToValue);
+        this.nameToDeclaration = new HashMap<>();
+        this.nameToDeclaration.putAll(nameToDeclaration);
+    }
+
+    public ResolvedType getValue(ResolvedTypeParameterDeclaration typeParameter) {
+        String qualifiedName = typeParameter.getQualifiedName();
+        if (nameToValue.containsKey(qualifiedName)) {
+            return nameToValue.get(qualifiedName);
+        } else {
+            return new ResolvedTypeVariable(typeParameter);
+        }
+    }
+
+    public Optional<ResolvedType> getValueBySignature(String signature) {
+        if (nameToValue.containsKey(signature)) {
+            return Optional.of(nameToValue.get(signature));
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    public List<String> getNames(){
+        return new ArrayList<>(nameToValue.keySet());
+    }
+
+    public List<ResolvedType> getTypes(){
+        return new ArrayList<>(nameToValue.values());
+    }
+
+    public Builder toBuilder() {
+        return new Builder(nameToValue, nameToDeclaration);
+    }
+
+    public boolean isEmpty() {
+        return nameToValue.isEmpty();
+    }
+
+    public ResolvedType replaceAll(ResolvedType type) {
+        Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
+        for (ResolvedTypeParameterDeclaration typeParameterDeclaration : this.nameToDeclaration.values()) {
+            type = type.replaceTypeVariables(typeParameterDeclaration, getValue(typeParameterDeclaration), inferredTypes);
+        }
+        return type;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametrized.java b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametrized.java
new file mode 100644
index 0000000..91a792a
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/resolution/types/parametrization/ResolvedTypeParametrized.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.resolution.types.parametrization;
+
+/**
+ * Something which can have values for TypeParameters.
+ *
+ * @author Federico Tomassetti
+ */
+public interface ResolvedTypeParametrized {
+    ResolvedTypeParametersMap typeParametersMap();
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/ClassUtils.java b/javaparser-core/src/main/java/com/github/javaparser/utils/ClassUtils.java
new file mode 100644
index 0000000..b0bdf05
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/ClassUtils.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClassUtils {
+    /**
+     * Maps primitive {@code Class}es to their corresponding wrapper {@code Class}.
+     */
+    private static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<>();
+
+    static {
+        primitiveWrapperMap.put(Boolean.TYPE, Boolean.class);
+        primitiveWrapperMap.put(Byte.TYPE, Byte.class);
+        primitiveWrapperMap.put(Character.TYPE, Character.class);
+        primitiveWrapperMap.put(Short.TYPE, Short.class);
+        primitiveWrapperMap.put(Integer.TYPE, Integer.class);
+        primitiveWrapperMap.put(Long.TYPE, Long.class);
+        primitiveWrapperMap.put(Double.TYPE, Double.class);
+        primitiveWrapperMap.put(Float.TYPE, Float.class);
+        primitiveWrapperMap.put(Void.TYPE, Void.TYPE);
+    }
+
+    /**
+     * Maps wrapper {@code Class}es to their corresponding primitive types.
+     */
+    private static final Map<Class<?>, Class<?>> wrapperPrimitiveMap = new HashMap<>();
+
+    static {
+        for (final Class<?> primitiveClass : primitiveWrapperMap.keySet()) {
+            final Class<?> wrapperClass = primitiveWrapperMap.get(primitiveClass);
+            if (!primitiveClass.equals(wrapperClass)) {
+                wrapperPrimitiveMap.put(wrapperClass, primitiveClass);
+            }
+        }
+    }
+
+    /**
+     * Returns whether the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte},
+     * {@link Character},
+     * {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     *
+     * @param type The class to query or null.
+     * @return true if the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte}, {@link
+     * Character}, {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     */
+    public static boolean isPrimitiveOrWrapper(final Class<?> type) {
+        if (type == null) {
+            return false;
+        }
+        return type.isPrimitive() || isPrimitiveWrapper(type);
+    }
+
+    /**
+     * Returns whether the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character},
+     * {@link Short},
+     * {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     *
+     * @param type The class to query or null.
+     * @return true if the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character},
+     * {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     * @since 3.1
+     */
+    public static boolean isPrimitiveWrapper(final Class<?> type) {
+        return wrapperPrimitiveMap.containsKey(type);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/CodeGenerationUtils.java b/javaparser-core/src/main/java/com/github/javaparser/utils/CodeGenerationUtils.java
new file mode 100644
index 0000000..098920b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/CodeGenerationUtils.java
@@ -0,0 +1,137 @@
+package com.github.javaparser.utils;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static com.github.javaparser.utils.Utils.capitalize;
+import static com.github.javaparser.utils.Utils.decapitalize;
+
+public final class CodeGenerationUtils {
+    private CodeGenerationUtils() {
+    }
+
+    public static String getterName(Class<?> type, String name) {
+        if (name.startsWith("is")) {
+            return name;
+        } else if (type.equals(Boolean.class)) {
+            return "is" + capitalize(name);
+        }
+        return "get" + capitalize(name);
+    }
+
+    public static String getterToPropertyName(String getterName) {
+        if (getterName.startsWith("is")) {
+            return decapitalize(getterName.substring("is".length()));
+        } else if (getterName.startsWith("get")) {
+            return decapitalize(getterName.substring("get".length()));
+        } else if (getterName.startsWith("has")) {
+            return decapitalize(getterName.substring("has".length()));
+        }
+        throw new IllegalArgumentException("Unexpected getterName '" + getterName + "'");
+    }
+
+    public static String setterName(String fieldName) {
+        if (fieldName.startsWith("is")) {
+            return "set" + fieldName.substring(2);
+        }
+        return "set" + capitalize(fieldName);
+    }
+
+    public static String optionalOf(String text, boolean isOptional) {
+        if (isOptional) {
+            return f("Optional.of(%s)", text);
+        } else {
+            return "Optional.empty()";
+        }
+    }
+
+    /**
+     * A shortcut to String.format.
+     */
+    public static String f(String format, Object... params) {
+        return String.format(format, params);
+    }
+
+    /**
+     * Calculates the path to a file in a package.
+     *
+     * @param root the root directory in which the package resides
+     * @param pkg the package in which the file resides, like "com.laamella.parser"
+     * @param file the filename of the file in the package.
+     */
+    public static Path fileInPackageAbsolutePath(String root, String pkg, String file) {
+        pkg = packageToPath(pkg);
+        return Paths.get(root, pkg, file).normalize();
+    }
+
+    public static Path fileInPackageAbsolutePath(Path root, String pkg, String file) {
+        return fileInPackageAbsolutePath(root.toString(), pkg, file);
+    }
+
+    /**
+     * Turns a package and a file into a relative path. "com.laamella" and "Simple.java" will become
+     * "com/laamella/Simple.java"
+     */
+    public static Path fileInPackageRelativePath(String pkg, String file) {
+        pkg = packageToPath(pkg);
+        return Paths.get(pkg, file).normalize();
+    }
+
+    /**
+     * Converts a package name like "com.laamella.parser" to a path like "com/laamella/parser"
+     */
+    public static String packageToPath(String pkg) {
+        return pkg.replace(".", File.separator);
+    }
+
+    /**
+     * Calculates the path of a package.
+     *
+     * @param root the root directory in which the package resides
+     * @param pkg the package, like "com.laamella.parser"
+     */
+    public static Path packageAbsolutePath(String root, String pkg) {
+        pkg = packageToPath(pkg);
+        return Paths.get(root, pkg).normalize();
+    }
+
+    public static Path packageAbsolutePath(Path root, String pkg) {
+        return packageAbsolutePath(root.toString(), pkg);
+    }
+
+    /**
+     * @return the root directory of the classloader for class c.
+     */
+    public static Path classLoaderRoot(Class<?> c) {
+        try {
+            return Paths.get(c.getProtectionDomain().getCodeSource().getLocation().toURI());
+        } catch (URISyntaxException e) {
+            throw new AssertionError("Bug in JavaParser, please report.", e);
+        }
+    }
+
+    /**
+     * Useful for locating source code in your Maven project. Finds the classpath for class c, then backs up out of
+     * "target/(test-)classes", giving the directory containing the pom.xml.
+     */
+    public static Path mavenModuleRoot(Class<?> c) {
+        return classLoaderRoot(c).resolve(Paths.get("..", "..")).normalize();
+    }
+
+    /**
+     * Shortens path "full" by cutting "difference" off the end of it.
+     */
+    public static Path subtractPaths(Path full, Path difference) {
+        while (difference != null) {
+            if (difference.getFileName().equals(full.getFileName())) {
+                difference = difference.getParent();
+                full = full.getParent();
+            } else {
+                throw new RuntimeException(f("'%s' could not be subtracted from '%s'", difference, full));
+            }
+        }
+        return full;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/Log.java b/javaparser-core/src/main/java/com/github/javaparser/utils/Log.java
new file mode 100644
index 0000000..12a9cdc
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/Log.java
@@ -0,0 +1,122 @@
+package com.github.javaparser.utils;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * To avoid dependencies on logging frameworks, we have invented yet another logging framework :-)
+ */
+public class Log {
+    /**
+     * This adapter logs to standard out and standard error.
+     */
+    public static class StandardOutStandardErrorAdapter implements Adapter {
+        @Override
+        public void info(String message) {
+            System.out.println(message);
+        }
+
+        @Override
+        public void trace(String message) {
+            System.out.println(message);
+        }
+
+        @Override
+        public void error(Throwable throwable, String message) {
+            if (message == null) {
+                System.err.println(throwable.getMessage());
+                printStackTrace(throwable);
+            } else if (throwable == null) {
+                System.err.println(message);
+            } else {
+                System.err.println(message + ":" + throwable.getMessage());
+                printStackTrace(throwable);
+            }
+        }
+
+        private void printStackTrace(Throwable throwable) {
+            try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
+                throwable.printStackTrace(pw);
+                trace(sw.toString());
+            } catch (IOException e) {
+                throw new AssertionError("Error in logging library");
+            }
+        }
+    }
+
+    /**
+     * This adapter logs nothing.
+     */
+    public static class SilentAdapter implements Adapter {
+        @Override
+        public void info(String message) {
+        }
+
+        @Override
+        public void trace(String message) {
+        }
+
+        @Override
+        public void error(Throwable throwable, String f) {
+        }
+    }
+
+    public interface Adapter {
+
+        void info(String message);
+
+        void trace(String message);
+
+        /**
+         * Both can be null.
+         */
+        void error(Throwable throwable, String f);
+    }
+
+    private static Adapter CURRENT_ADAPTER = new SilentAdapter();
+
+    /**
+     * Change how logging is handled. You can set your own implementation that forwards to your logging library.
+     */
+    public static void setAdapter(Adapter adapter) {
+        CURRENT_ADAPTER = adapter;
+    }
+
+    /**
+     * For logging information that may help solving a problem.
+     */
+    public static void trace(String format, Object... args) {
+        CURRENT_ADAPTER.trace(f(format, args));
+    }
+
+    /**
+     * For logging things that are nice to see scrolling by.
+     */
+    public static void info(String format, Object... args) {
+        CURRENT_ADAPTER.info(f(format, args));
+    }
+
+    /**
+     * For drawing attention to an error.
+     */
+    public static void error(Throwable throwable) {
+        CURRENT_ADAPTER.error(throwable, null);
+    }
+
+    /**
+     * For drawing attention to an error that you don't have an exception for.
+     */
+    public static void error(Throwable throwable, String format, Object... args) {
+        CURRENT_ADAPTER.error(throwable, f(format, args));
+    }
+
+    /**
+     * For drawing attention to an error that you don't have an exception for.
+     */
+    public static void error(String format, Object... args) {
+        CURRENT_ADAPTER.error(null, f(format, args));
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/Pair.java b/javaparser-core/src/main/java/com/github/javaparser/utils/Pair.java
new file mode 100644
index 0000000..6f84a7b
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/Pair.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.utils;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+/**
+ * Simply a pair of objects.
+ *
+ * @param <A> type of object a.
+ * @param <B> type of object b.
+ */
+public class Pair<A, B> {
+    public final A a;
+    public final B b;
+
+    public Pair(A a, B b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Pair<?, ?> pair = (Pair<?, ?>) o;
+
+        if (a != null ? !a.equals(pair.a) : pair.a != null) return false;
+        if (b != null ? !b.equals(pair.b) : pair.b != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = a != null ? a.hashCode() : 0;
+        return 31 * result + (b != null ? b.hashCode() : 0);
+    }
+
+    @Override
+    public String toString() {
+        return f("<%s, %s>", a, b);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/PositionUtils.java b/javaparser-core/src/main/java/com/github/javaparser/utils/PositionUtils.java
new file mode 100644
index 0000000..6852b29
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/PositionUtils.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.utils;
+
+import com.github.javaparser.Position;
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.Type;
+
+import java.util.List;
+
+import static java.lang.Integer.signum;
+
+public final class PositionUtils {
+
+    private PositionUtils() {
+        // prevent instantiation
+    }
+
+    public static <T extends Node> void sortByBeginPosition(List<T> nodes) {
+        sortByBeginPosition(nodes, false);
+    }
+
+    public static <T extends Node> void sortByBeginPosition(NodeList<T> nodes) {
+        sortByBeginPosition(nodes, false);
+    }
+
+    public static <T extends Node> void sortByBeginPosition(List<T> nodes, final boolean ignoringAnnotations) {
+        nodes.sort((o1, o2) -> PositionUtils.compare(o1, o2, ignoringAnnotations));
+    }
+
+    public static boolean areInOrder(Node a, Node b) {
+        return areInOrder(a, b, false);
+    }
+
+    public static boolean areInOrder(Node a, Node b, boolean ignoringAnnotations) {
+        return compare(a, b, ignoringAnnotations) <= 0;
+    }
+
+    private static int compare(Node a, Node b, boolean ignoringAnnotations) {
+        if(a.getRange().isPresent() && !b.getRange().isPresent()) {
+            return -1;
+        }
+        if(!a.getRange().isPresent() && b.getRange().isPresent()) {
+            return 1;
+        }
+        if (!a.getRange().isPresent() && !b.getRange().isPresent()) {
+            return 0;
+        }
+        if (ignoringAnnotations) {
+            int signLine = signum(beginLineWithoutConsideringAnnotation(a) - beginLineWithoutConsideringAnnotation(b));
+            if (signLine == 0) {
+                return signum(beginColumnWithoutConsideringAnnotation(a) - beginColumnWithoutConsideringAnnotation(b));
+            } else {
+                return signLine;
+            }
+        }
+
+        Position aBegin = a.getBegin().get();
+        Position bBegin = b.getBegin().get();
+
+        int signLine = signum(aBegin.line - bBegin.line);
+        if (signLine == 0) {
+            return signum(aBegin.column - bBegin.column);
+        } else {
+            return signLine;
+        }
+    }
+
+    public static AnnotationExpr getLastAnnotation(Node node) {
+        if (node instanceof NodeWithAnnotations) {
+            NodeList<AnnotationExpr> annotations = NodeList.nodeList(((NodeWithAnnotations<?>) node).getAnnotations());
+            if (annotations.isEmpty()) {
+                return null;
+            }
+            sortByBeginPosition(annotations);
+            return annotations.get(annotations.size() - 1);
+        } else {
+            return null;
+        }
+    }
+
+    private static int beginLineWithoutConsideringAnnotation(Node node) {
+        return beginNodeWithoutConsideringAnnotations(node).getRange().get().begin.line;
+    }
+
+
+    private static int beginColumnWithoutConsideringAnnotation(Node node) {
+        return beginNodeWithoutConsideringAnnotations(node).getRange().get().begin.column;
+    }
+
+    private static Node beginNodeWithoutConsideringAnnotations(Node node) {
+        if (node instanceof MethodDeclaration || node instanceof FieldDeclaration) {
+            NodeWithType<?, Type> casted = (NodeWithType<?, Type>) node;
+            return casted.getType();
+        } else if (node instanceof ClassOrInterfaceDeclaration) {
+            ClassOrInterfaceDeclaration casted = (ClassOrInterfaceDeclaration) node;
+            return casted.getName();
+        } else {
+            return node;
+        }
+    }
+
+    public static boolean nodeContains(Node container, Node contained, boolean ignoringAnnotations) {
+        final Range containedRange = contained.getRange().get();
+        final Range containerRange = container.getRange().get();
+        if (!ignoringAnnotations || PositionUtils.getLastAnnotation(container) == null) {
+            return container.containsWithin(contained);
+        }
+        if (!container.containsWithin(contained)) {
+            return false;
+        }
+        // if the node is contained, but it comes immediately after the annotations,
+        // let's not consider it contained
+        if (container instanceof NodeWithAnnotations) {
+            int bl = beginLineWithoutConsideringAnnotation(container);
+            int bc = beginColumnWithoutConsideringAnnotation(container);
+            if (bl > containedRange.begin.line) return false;
+            if (bl == containedRange.begin.line && bc > containedRange.begin.column) return false;
+            if (containerRange.end.line < containedRange.end.line) return false;
+            // TODO < or <= ?
+            return !(containerRange.end.line == containedRange.end.line && containerRange.end.column < containedRange.end.column);
+        }
+        return true;
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/SeparatedItemStringBuilder.java b/javaparser-core/src/main/java/com/github/javaparser/utils/SeparatedItemStringBuilder.java
new file mode 100644
index 0000000..3cef723
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/SeparatedItemStringBuilder.java
@@ -0,0 +1,45 @@
+package com.github.javaparser.utils;
+
+/**
+ * Builds a string containing a list of items with a prefix, a postfix, and a separator.
+ * <br/>Example: (1,2,3) which has prefix "(", separator ",", postfix ")" and the items 1 through 3.
+ * <p/>Java 8 offers the very nice Collectors.joining(String, String, String) which does the same thing.
+ */
+public class SeparatedItemStringBuilder {
+    private final String separator;
+    private final String postfix;
+    private boolean hasItems = false;
+    private StringBuilder builder;
+
+    public SeparatedItemStringBuilder(String prefix, String separator, String postfix) {
+        builder = new StringBuilder(prefix);
+        this.separator = separator;
+        this.postfix = postfix;
+
+    }
+
+    /**
+     * Add one item. Either pass a string, or a format for String.format and corresponding arguments.
+     */
+    public SeparatedItemStringBuilder append(CharSequence format, Object... args) {
+        if (hasItems) {
+            builder.append(separator);
+        }
+        builder.append(String.format(format.toString(), args));
+        hasItems = true;
+        return this;
+    }
+
+    public boolean hasItems() {
+        return hasItems;
+    }
+
+    /**
+     * Convert the builder into its final string representation.
+     */
+    @Override
+    public String toString() {
+        // This order of toStringing avoids debuggers from making a mess.
+        return builder.toString() + postfix;
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/SourceRoot.java b/javaparser-core/src/main/java/com/github/javaparser/utils/SourceRoot.java
new file mode 100644
index 0000000..02a90ff
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/SourceRoot.java
@@ -0,0 +1,577 @@
+package com.github.javaparser.utils;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseProblemException;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.printer.PrettyPrinter;
+
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.RecursiveAction;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.CodeGenerationUtils.fileInPackageRelativePath;
+import static com.github.javaparser.utils.CodeGenerationUtils.packageAbsolutePath;
+import static com.github.javaparser.utils.SourceRoot.Callback.Result.SAVE;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.nio.file.FileVisitResult.CONTINUE;
+import static java.nio.file.FileVisitResult.SKIP_SUBTREE;
+
+/**
+ * A collection of Java source files located in one directory and its subdirectories on the file system. Files can be
+ * parsed and written back one by one or all together. <b>Note that</b> the internal cache used is thread-safe.
+ * <ul>
+ * <li>methods called "tryToParse..." will return their result inside a "ParseResult", which supports parse successes and failures.</li>
+ * <li>methods called "parse..." will return "CompilationUnit"s. If a file fails to parse, an exception is thrown.</li>
+ * <li>methods ending in "...Parallelized" will speed up parsing by using multiple threads.</li>
+ * </ul>
+ */
+public class SourceRoot {
+    @FunctionalInterface
+    public interface Callback {
+        enum Result {
+            SAVE, DONT_SAVE
+        }
+
+        /**
+         * @param localPath the path to the file that was parsed, relative to the source root path.
+         * @param absolutePath the absolute path to the file that was parsed.
+         * @param result the result of of parsing the file.
+         */
+        Result process(Path localPath, Path absolutePath, ParseResult<CompilationUnit> result);
+    }
+
+    private final Path root;
+    private final Map<Path, ParseResult<CompilationUnit>> cache = new ConcurrentHashMap<>();
+    private ParserConfiguration parserConfiguration = new ParserConfiguration();
+    private Function<CompilationUnit, String> printer = new PrettyPrinter()::print;
+    private static final Pattern JAVA_IDENTIFIER = Pattern.compile("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*");
+
+    public SourceRoot(Path root) {
+        assertNotNull(root);
+        if (!Files.isDirectory(root)) {
+            throw new IllegalArgumentException("Only directories are allowed as root path!");
+        }
+        this.root = root.normalize();
+        Log.info("New source root at \"%s\"", this.root);
+    }
+
+    public SourceRoot(Path root, ParserConfiguration parserConfiguration) {
+        this(root);
+        setParserConfiguration(parserConfiguration);
+    }
+
+    /**
+     * Tries to parse a .java files under the source root and returns the ParseResult. It keeps track of the parsed file
+     * so you can write it out with the saveAll() call. Note that the cache grows with every file parsed, so if you
+     * don't need saveAll(), or you don't ask SourceRoot to parse files multiple times (where the cache is useful) you
+     * might want to use the parse method with a callback.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     * @deprecated pass ParserConfiguration instead of JavaParser
+     */
+    @Deprecated
+    public ParseResult<CompilationUnit> tryToParse(String startPackage, String filename, JavaParser javaParser)
+            throws IOException {
+        return tryToParse(startPackage, filename, javaParser.getParserConfiguration());
+    }
+
+    /**
+     * Tries to parse a .java files under the source root and returns the ParseResult. It keeps track of the parsed file
+     * so you can write it out with the saveAll() call. Note that the cache grows with every file parsed, so if you
+     * don't need saveAll(), or you don't ask SourceRoot to parse files multiple times (where the cache is useful) you
+     * might want to use the parse method with a callback.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public ParseResult<CompilationUnit> tryToParse(String startPackage, String filename, ParserConfiguration configuration) throws IOException {
+        assertNotNull(startPackage);
+        assertNotNull(filename);
+        final Path relativePath = fileInPackageRelativePath(startPackage, filename);
+        if (cache.containsKey(relativePath)) {
+            Log.trace("Retrieving cached %s", relativePath);
+            return cache.get(relativePath);
+        }
+        final Path path = root.resolve(relativePath);
+        Log.trace("Parsing %s", path);
+        final ParseResult<CompilationUnit> result = new JavaParser(configuration)
+                .parse(COMPILATION_UNIT, provider(path));
+        result.getResult().ifPresent(cu -> cu.setStorage(path));
+        cache.put(relativePath, result);
+        return result;
+    }
+
+    /**
+     * Tries to parse a .java files under the source root and returns the ParseResult. It keeps track of the parsed file
+     * so you can write it out with the saveAll() call. Note that the cache grows with every file parsed, so if you
+     * don't need saveAll(), or you don't ask SourceRoot to parse files multiple times (where the cache is useful) you
+     * might want to use the parse method with a callback.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public ParseResult<CompilationUnit> tryToParse(String startPackage, String filename) throws IOException {
+        return tryToParse(startPackage, filename, parserConfiguration);
+    }
+
+    /**
+     * Tries to parse all .java files in a package recursively, and returns all files ever parsed with this source root.
+     * It keeps track of all parsed files so you can write them out with a single saveAll() call. Note that the cache
+     * grows with every file parsed, so if you don't need saveAll(), or you don't ask SourceRoot to parse files multiple
+     * times (where the cache is useful) you might want to use the parse method with a callback.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public List<ParseResult<CompilationUnit>> tryToParse(String startPackage) throws IOException {
+        assertNotNull(startPackage);
+        logPackage(startPackage);
+        final Path path = packageAbsolutePath(root, startPackage);
+        Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                if (!attrs.isDirectory() && file.toString().endsWith(".java")) {
+                    Path relative = root.relativize(file.getParent());
+                    tryToParse(relative.toString(), file.getFileName().toString());
+                }
+                return CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+                return isSensibleDirectoryToEnter(dir) ? CONTINUE : SKIP_SUBTREE;
+            }
+        });
+        return getCache();
+    }
+
+    private static boolean isSensibleDirectoryToEnter(Path dir) throws IOException {
+        final String dirToEnter = dir.getFileName().toString();
+        final boolean directoryIsAValidJavaIdentifier = JAVA_IDENTIFIER.matcher(dirToEnter).matches();
+        if (Files.isHidden(dir) || !directoryIsAValidJavaIdentifier) {
+            Log.trace("Not processing directory \"%s\"", dirToEnter);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Tries to parse all .java files under the source root recursively, and returns all files ever parsed with this
+     * source root. It keeps track of all parsed files so you can write them out with a single saveAll() call. Note that
+     * the cache grows with every file parsed, so if you don't need saveAll(), or you don't ask SourceRoot to parse
+     * files multiple times (where the cache is useful) you might want to use the parse method with a callback.
+     */
+    public List<ParseResult<CompilationUnit>> tryToParse() throws IOException {
+        return tryToParse("");
+    }
+
+    /**
+     * Tries to parse all .java files in a package recursively using multiple threads, and returns all files ever parsed
+     * with this source root. A new thread is forked each time a new directory is visited and is responsible for parsing
+     * all .java files in that directory. <b>Note that</b> to ensure thread safety, a new parser instance is created for
+     * every file with the internal parser's (i.e. {@link #setJavaParser}) configuration. It keeps track of all parsed
+     * files so you can write them out with a single saveAll() call. Note that the cache grows with every file parsed,
+     * so if you don't need saveAll(), or you don't ask SourceRoot to parse files multiple times (where the cache is
+     * useful) you might want to use the parse method with a callback.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public List<ParseResult<CompilationUnit>> tryToParseParallelized(String startPackage) {
+        assertNotNull(startPackage);
+        logPackage(startPackage);
+        final Path path = packageAbsolutePath(root, startPackage);
+        ParallelParse parse = new ParallelParse(path, (file, attrs) -> {
+            if (!attrs.isDirectory() && file.toString().endsWith(".java")) {
+                Path relative = root.relativize(file.getParent());
+                try {
+                    tryToParse(
+                            relative.toString(),
+                            file.getFileName().toString(),
+                            parserConfiguration);
+                } catch (IOException e) {
+                    Log.error(e);
+                }
+            }
+            return CONTINUE;
+        });
+        ForkJoinPool pool = new ForkJoinPool();
+        pool.invoke(parse);
+        return getCache();
+    }
+
+    /**
+     * Tries to parse all .java files under the source root recursively using multiple threads, and returns all files
+     * ever parsed with this source root. A new thread is forked each time a new directory is visited and is responsible
+     * for parsing all .java files in that directory. <b>Note that</b> to ensure thread safety, a new parser instance is
+     * created for every file with the internal parser's (i.e. {@link #setJavaParser}) configuration. It keeps track of
+     * all parsed files so you can write them out with a single saveAll() call. Note that the cache grows with every
+     * file parsed, so if you don't need saveAll(), or you don't ask SourceRoot to parse files multiple times (where the
+     * cache is useful) you might want to use the parse method with a callback.
+     */
+    public List<ParseResult<CompilationUnit>> tryToParseParallelized() throws IOException {
+        return tryToParseParallelized("");
+    }
+
+    /**
+     * Parses a .java files under the source root and returns its CompilationUnit. It keeps track of the parsed file so
+     * you can write it out with the saveAll() call. Note that the cache grows with every file parsed, so if you don't
+     * need saveAll(), or you don't ask SourceRoot to parse files multiple times (where the cache is useful) you might
+     * want to use the parse method with a callback.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     * @throws ParseProblemException when something went wrong.
+     */
+    public CompilationUnit parse(String startPackage, String filename) {
+        assertNotNull(startPackage);
+        assertNotNull(filename);
+        try {
+            final ParseResult<CompilationUnit> result = tryToParse(startPackage, filename);
+            if (result.isSuccessful()) {
+                return result.getResult().get();
+            }
+            throw new ParseProblemException(result.getProblems());
+        } catch (IOException e) {
+            throw new ParseProblemException(e);
+        }
+    }
+
+    /**
+     * Tries to parse all .java files in a package recursively and passes them one by one to the callback. In comparison
+     * to the other parse methods, this is much more memory efficient, but saveAll() won't work.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     * @deprecated pass ParserConfiguration instead of JavaParser
+     */
+    @Deprecated
+    public SourceRoot parse(String startPackage, JavaParser javaParser, Callback callback) throws IOException {
+        return parse(startPackage, javaParser.getParserConfiguration(), callback);
+    }
+
+    /**
+     * Tries to parse all .java files in a package recursively and passes them one by one to the callback. In comparison
+     * to the other parse methods, this is much more memory efficient, but saveAll() won't work.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public SourceRoot parse(String startPackage, ParserConfiguration configuration, Callback callback) throws IOException {
+        assertNotNull(startPackage);
+        assertNotNull(configuration);
+        assertNotNull(callback);
+        logPackage(startPackage);
+        final JavaParser javaParser = new JavaParser(configuration);
+        final Path path = packageAbsolutePath(root, startPackage);
+        Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
+            @Override
+            public FileVisitResult visitFile(Path absolutePath, BasicFileAttributes attrs) throws IOException {
+                if (!attrs.isDirectory() && absolutePath.toString().endsWith(".java")) {
+                    Path localPath = root.relativize(absolutePath);
+                    Log.trace("Parsing %s", localPath);
+                    final ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT,
+                            provider(absolutePath));
+                    result.getResult().ifPresent(cu -> cu.setStorage(absolutePath));
+                    if (callback.process(localPath, absolutePath, result) == SAVE) {
+                        if (result.getResult().isPresent()) {
+                            save(result.getResult().get(), path);
+                        }
+                    }
+                }
+                return CONTINUE;
+            }
+
+            @Override
+            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+                return isSensibleDirectoryToEnter(dir) ? CONTINUE : SKIP_SUBTREE;
+            }
+        });
+        return this;
+    }
+
+    private void logPackage(String startPackage) {
+        if (startPackage.isEmpty()) {
+            return;
+        }
+        Log.info("Parsing package \"%s\"", startPackage);
+    }
+
+    /**
+     * Tries to parse all .java files in a package recursively using multiple threads, and passes them one by one to the
+     * callback. A new thread is forked each time a new directory is visited and is responsible for parsing all .java
+     * files in that directory. <b>Note that</b> the provided {@link Callback} code must be made thread-safe. <b>Note
+     * that</b> to ensure thread safety, a new parser instance is created for every file with the provided {@link
+     * ParserConfiguration}. In comparison to the other parse methods, this is much more memory efficient, but saveAll()
+     * won't work.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public SourceRoot parseParallelized(String startPackage, ParserConfiguration configuration, Callback callback) {
+        assertNotNull(startPackage);
+        assertNotNull(configuration);
+        assertNotNull(callback);
+        logPackage(startPackage);
+        final Path path = packageAbsolutePath(root, startPackage);
+        ParallelParse parse = new ParallelParse(path, (file, attrs) -> {
+            if (!attrs.isDirectory() && file.toString().endsWith(".java")) {
+                Path localPath = root.relativize(file);
+                Log.trace("Parsing %s", localPath);
+                try {
+                    ParseResult<CompilationUnit> result = new JavaParser(configuration)
+                            .parse(COMPILATION_UNIT, provider(file));
+                    result.getResult().ifPresent(cu -> cu.setStorage(file));
+                    if (callback.process(localPath, file, result) == SAVE) {
+                        if (result.getResult().isPresent()) {
+                            save(result.getResult().get(), path);
+                        }
+                    }
+                } catch (IOException e) {
+                    Log.error(e);
+                }
+            }
+            return CONTINUE;
+        });
+        ForkJoinPool pool = new ForkJoinPool();
+        pool.invoke(parse);
+        return this;
+    }
+
+    /**
+     * Tries to parse all .java files in a package recursively using multiple threads, and passes them one by one to the
+     * callback. A new thread is forked each time a new directory is visited and is responsible for parsing all .java
+     * files in that directory. <b>Note that</b> the provided {@link Callback} code must be made thread-safe. <b>Note
+     * that</b> to ensure thread safety, a new parser instance is created for every file. In comparison to the other
+     * parse methods, this is much more memory efficient, but saveAll() won't work.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public SourceRoot parseParallelized(String startPackage, Callback callback) throws IOException {
+        return parseParallelized(startPackage, new ParserConfiguration(), callback);
+    }
+
+    /**
+     * Tries to parse all .java files recursively using multiple threads, and passes them one by one to the callback. A
+     * new thread is forked each time a new directory is visited and is responsible for parsing all .java files in that
+     * directory. <b>Note that</b> the provided {@link Callback} code must be made thread-safe. <b>Note that</b> to
+     * ensure thread safety, a new parser instance is created for every file. In comparison to the other parse methods,
+     * this is much more memory efficient, but saveAll() won't work.
+     */
+    public SourceRoot parseParallelized(Callback callback) throws IOException {
+        return parseParallelized("", new ParserConfiguration(), callback);
+    }
+
+    /**
+     * Add a newly created Java file to the cache of this source root. It will be saved when saveAll is called.
+     *
+     * @param startPackage files in this package and deeper are parsed. Pass "" to parse all files.
+     */
+    public SourceRoot add(String startPackage, String filename, CompilationUnit compilationUnit) {
+        assertNotNull(startPackage);
+        assertNotNull(filename);
+        assertNotNull(compilationUnit);
+        Log.trace("Adding new file %s.%s", startPackage, filename);
+        final Path path = fileInPackageRelativePath(startPackage, filename);
+        final ParseResult<CompilationUnit> parseResult = new ParseResult<>(
+                compilationUnit,
+                new ArrayList<>(),
+                null,
+                null);
+        cache.put(path, parseResult);
+        return this;
+    }
+
+    /**
+     * Add a newly created Java file to the cache of this source root. It will be saved when saveAll is called. It needs
+     * to have its path set.
+     */
+    public SourceRoot add(CompilationUnit compilationUnit) {
+        assertNotNull(compilationUnit);
+        if (compilationUnit.getStorage().isPresent()) {
+            final Path path = compilationUnit.getStorage().get().getPath();
+            Log.trace("Adding new file %s", path);
+            final ParseResult<CompilationUnit> parseResult = new ParseResult<>(
+                    compilationUnit,
+                    new ArrayList<>(),
+                    null,
+                    null);
+            cache.put(path, parseResult);
+        } else {
+            throw new AssertionError("Files added with this method should have their path set.");
+        }
+        return this;
+    }
+
+    /**
+     * Save the given compilation unit to the given path.
+     */
+    private SourceRoot save(CompilationUnit cu, Path path) {
+        assertNotNull(cu);
+        assertNotNull(path);
+        cu.setStorage(path);
+        cu.getStorage().get().save(printer);
+        return this;
+    }
+
+    /**
+     * Save all previously parsed files back to a new path.
+     */
+    public SourceRoot saveAll(Path root) {
+        assertNotNull(root);
+        Log.info("Saving all files (%s) to %s", cache.size(), root);
+        for (Map.Entry<Path, ParseResult<CompilationUnit>> cu : cache.entrySet()) {
+            final Path path = root.resolve(cu.getKey());
+            if (cu.getValue().getResult().isPresent()) {
+                Log.trace("Saving %s", path);
+                save(cu.getValue().getResult().get(), path);
+            }
+        }
+        return this;
+    }
+
+    /**
+     * Save all previously parsed files back to where they were found.
+     */
+    public SourceRoot saveAll() {
+        return saveAll(root);
+    }
+
+    /**
+     * The Java files that have been parsed by this source root object, or have been added manually.
+     */
+    public List<ParseResult<CompilationUnit>> getCache() {
+        return new ArrayList<>(cache.values());
+    }
+
+    /**
+     * The CompilationUnits of the Java files that have been parsed succesfully by this source root object, or have been
+     * added manually.
+     */
+    public List<CompilationUnit> getCompilationUnits() {
+        return cache.values().stream()
+                .filter(ParseResult::isSuccessful)
+                .map(p -> p.getResult().get())
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * The path that was passed in the constructor.
+     */
+    public Path getRoot() {
+        return root;
+    }
+
+    /**
+     * @deprecated store ParserConfiguration now
+     */
+    @Deprecated
+    public JavaParser getJavaParser() {
+        return new JavaParser(parserConfiguration);
+    }
+
+    /**
+     * Set the parser that is used for parsing by default.
+     *
+     * @deprecated store ParserConfiguration now
+     */
+    @Deprecated
+    public SourceRoot setJavaParser(JavaParser javaParser) {
+        assertNotNull(javaParser);
+        this.parserConfiguration = javaParser.getParserConfiguration();
+        return this;
+    }
+
+    public ParserConfiguration getParserConfiguration() {
+        return parserConfiguration;
+    }
+
+    /**
+     * Set the parser configuration that is used for parsing when no configuration is passed to a method.
+     */
+    public SourceRoot setParserConfiguration(ParserConfiguration parserConfiguration) {
+        assertNotNull(parserConfiguration);
+        this.parserConfiguration = parserConfiguration;
+        return this;
+    }
+
+    /**
+     * Set the printing function that transforms compilation units into a string to save.
+     */
+    public SourceRoot setPrinter(Function<CompilationUnit, String> printer) {
+        assertNotNull(printer);
+        this.printer = printer;
+        return this;
+    }
+
+    /**
+     * Get the printing function.
+     */
+    public Function<CompilationUnit, String> getPrinter() {
+        return printer;
+    }
+
+    /**
+     * Executes a recursive file tree walk using threads. A new thread is invoked for each new directory discovered
+     * during the walk. For each file visited, the user-provided {@link VisitFileCallback} is called with the current
+     * path and file attributes. Any shared resources accessed in a {@link VisitFileCallback} should be made
+     * thread-safe.
+     */
+    private static class ParallelParse extends RecursiveAction {
+
+        private static final long serialVersionUID = 1L;
+        private final Path path;
+        private final VisitFileCallback callback;
+
+        ParallelParse(Path path, VisitFileCallback callback) {
+            this.path = path;
+            this.callback = callback;
+        }
+
+        @Override
+        protected void compute() {
+            final List<ParallelParse> walks = new ArrayList<>();
+            try {
+                Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
+                    @Override
+                    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+                        if (!SourceRoot.isSensibleDirectoryToEnter(dir)) {
+                            return SKIP_SUBTREE;
+                        }
+                        if (!dir.equals(ParallelParse.this.path)) {
+                            ParallelParse w = new ParallelParse(dir, callback);
+                            w.fork();
+                            walks.add(w);
+                            return SKIP_SUBTREE;
+                        } else {
+                            return CONTINUE;
+                        }
+                    }
+
+                    @Override
+                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+                        return callback.process(file, attrs);
+                    }
+                });
+            } catch (IOException e) {
+                Log.error(e);
+            }
+
+            for (ParallelParse w : walks) {
+                w.join();
+            }
+        }
+
+        interface VisitFileCallback {
+            FileVisitResult process(Path file, BasicFileAttributes attrs);
+        }
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/SourceZip.java b/javaparser-core/src/main/java/com/github/javaparser/utils/SourceZip.java
new file mode 100644
index 0000000..ffb64f4
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/SourceZip.java
@@ -0,0 +1,169 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.utils;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ParseResult;

+import com.github.javaparser.ParserConfiguration;

+import com.github.javaparser.ast.CompilationUnit;

+

+import java.io.IOException;

+import java.nio.file.Path;

+import java.nio.file.Paths;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.List;

+import java.util.zip.ZipEntry;

+import java.util.zip.ZipFile;

+

+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;

+import static com.github.javaparser.Providers.provider;

+import static com.github.javaparser.utils.Utils.assertNotNull;

+

+/**

+ * A collection of Java source files and its sub-directories located in a ZIP or JAR file on the file system.

+ * Files can be parsed with a callback.

+ *

+ */

+public class SourceZip {

+

+    private final Path zipPath;

+    private ParserConfiguration parserConfiguration;

+

+    /**

+     * Create a new ZIP parser. An instance of {@link JavaParser} with the default {@link ParserConfiguration} will be

+     * used to parse the ZIP.

+     *

+     * @param zipPath The absolute path of ZIP file to parse.

+     */

+    public SourceZip(Path zipPath) {

+        this(zipPath, new ParserConfiguration());

+    }

+

+    /**

+     * Create a new ZIP parser. An instance of {@link JavaParser} with the given configuration will be used to parse

+     * the ZIP.

+     *

+     * @param zipPath The absolute path of ZIP file to parse.

+     * @param configuration The configuration to initiate the default parser with.

+     */

+    public SourceZip(Path zipPath, ParserConfiguration configuration) {

+        assertNotNull(zipPath);

+        assertNotNull(configuration);

+        this.zipPath = zipPath.normalize();

+        this.parserConfiguration = configuration;

+        Log.info("New source zip at \"%s\"", this.zipPath);

+    }

+

+    /**

+     * Tries to parse all '.java' files in the ZIP located at this <i>SourceZip</i>'s path and returns the parse

+     * results in a list.

+     *

+     * @return A list of path-compilation unit pairs.

+     *

+     * @throws IOException If an error occurs while trying to parse the given source.

+     */

+    public List<Pair<Path, ParseResult<CompilationUnit>>> parse() throws IOException {

+        Log.info("Parsing zip at \"%s\"", zipPath);

+        List<Pair<Path, ParseResult<CompilationUnit>>> results = new ArrayList<>();

+        parse((path, result) -> results.add(new Pair<>(path, result)));

+        return results;

+    }

+

+    /**

+     * Tries to parse all '.java' files in the ZIP located at this <i>SourceZip</i>'s path and returns the parse

+     * results in a list.

+     *

+     * @return A list of path-compilation unit pairs.

+     *

+     * @throws IOException If an error occurs while trying to parse the given source.

+     */

+    public SourceZip parse(Callback callback) throws IOException {

+        Log.info("Parsing zip at \"%s\"", zipPath);

+        JavaParser javaParser = new JavaParser(parserConfiguration);

+        try (ZipFile zipFile = new ZipFile(zipPath.toFile())) {

+            for (ZipEntry entry : Collections.list(zipFile.entries())) {

+                if (!entry.isDirectory() && entry.getName().endsWith(".java")) {

+                    Log.info("Parsing zip entry \"%s\"", entry.getName());

+                    final ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT,

+                            provider(zipFile.getInputStream(entry)));

+                    callback.process(Paths.get(entry.getName()), result);

+                }

+            }

+        }

+        return this;

+    }

+

+    /**

+     * An interface to define a callback for each file that's parsed.

+     */

+    @FunctionalInterface

+    public interface Callback {

+

+        /**

+         * Process the given parse result.

+         *

+         * @param relativeZipEntryPath The relative path of the entry in the ZIP file that was parsed.

+         * @param result The parse result of file located at <i>absolutePath</i>.

+         */

+        void process(Path relativeZipEntryPath, ParseResult<CompilationUnit> result);

+    }

+

+    /**

+     * Get the path of the ZIP file to be parsed.

+     *

+     * @return The absolute path of this ZIP file.

+     */

+    public Path getZipPath() {

+        return zipPath;

+    }

+    

+    /**

+     * @deprecated store ParserConfiguration now

+     */

+    @Deprecated

+    public JavaParser getJavaParser() {

+        return new JavaParser(parserConfiguration);

+    }

+

+    /**

+     * Set the parser that is used for parsing by default.

+     *

+     * @deprecated store ParserConfiguration now

+     */

+    @Deprecated

+    public SourceZip setJavaParser(JavaParser javaParser) {

+        assertNotNull(javaParser);

+        this.parserConfiguration = javaParser.getParserConfiguration();

+        return this;

+    }

+

+    public ParserConfiguration getParserConfiguration() {

+        return parserConfiguration;

+    }

+

+    public SourceZip setParserConfiguration(ParserConfiguration parserConfiguration) {

+        assertNotNull(parserConfiguration);

+        this.parserConfiguration = parserConfiguration;

+        return this;

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/StringEscapeUtils.java b/javaparser-core/src/main/java/com/github/javaparser/utils/StringEscapeUtils.java
new file mode 100644
index 0000000..a9732b9
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/StringEscapeUtils.java
@@ -0,0 +1,435 @@
+/*
+ * 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.
+ */
+package com.github.javaparser.utils;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * Adapted from apache commons-lang3 project.
+ * <p>
+ * Unescapes escaped chars in strings.
+ */
+public class StringEscapeUtils {
+
+    private StringEscapeUtils() {
+    }
+
+    /**
+     * <p>Escapes the characters in a {@code String} using Java String rules.</p>
+     * <p>
+     * <p>Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.) </p>
+     * <p>
+     * <p>So a tab becomes the characters {@code '\\'} and
+     * {@code 't'}.</p>
+     * <p>
+     * <p>The only difference between Java strings and JavaScript strings
+     * is that in JavaScript, a single quote and forward-slash (/) are escaped.</p>
+     * <p>
+     * <p>Example:</p>
+     * <pre>
+     * input string: He didn't say, "Stop!"
+     * output string: He didn't say, \"Stop!\"
+     * </pre>
+     *
+     * @param input String to escape values in, may be null
+     * @return String with escaped values, {@code null} if null string input
+     */
+    public static String escapeJava(final String input) {
+        return ESCAPE_JAVA.translate(input);
+    }
+
+    /**
+     * <p>Unescapes any Java literals found in the {@code String}.
+     * For example, it will turn a sequence of {@code '\'} and
+     * {@code 'n'} into a newline character, unless the {@code '\'}
+     * is preceded by another {@code '\'}.</p>
+     *
+     * @param input the {@code String} to unescape, may be null
+     * @return a new unescaped {@code String}, {@code null} if null string input
+     */
+    public static String unescapeJava(final String input) {
+        return UNESCAPE_JAVA.translate(input);
+    }
+
+    private static final String[][] JAVA_CTRL_CHARS_UNESCAPE = {
+            {"\\b", "\b"},
+            {"\\n", "\n"},
+            {"\\t", "\t"},
+            {"\\f", "\f"},
+            {"\\r", "\r"}
+    };
+
+    private static final String[][] JAVA_CTRL_CHARS_ESCAPE = {
+            {"\b", "\\b"},
+            {"\n", "\\n"},
+            {"\t", "\\t"},
+            {"\f", "\\f"},
+            {"\r", "\\r"}
+    };
+
+    private static final CharSequenceTranslator ESCAPE_JAVA =
+            new AggregateTranslator(
+                    new LookupTranslator(
+                            new String[][]{
+                                    {"\"", "\\\""},
+                                    {"\\", "\\\\"},
+                            }),
+                    new LookupTranslator(JAVA_CTRL_CHARS_ESCAPE.clone())
+            );
+
+    private static final CharSequenceTranslator UNESCAPE_JAVA =
+            new AggregateTranslator(
+                    new OctalUnescaper(),
+                    new UnicodeUnescaper(),
+                    new LookupTranslator(JAVA_CTRL_CHARS_UNESCAPE.clone()),
+                    new LookupTranslator(
+                            new String[][]{
+                                    {"\\\\", "\\"},
+                                    {"\\\"", "\""},
+                                    {"\\'", "'"},
+                                    {"\\", ""}
+                            })
+            );
+
+    /**
+     * Adapted from apache commons-lang3 project.
+     * <p>
+     * An API for translating text.
+     * Its core use is to escape and unescape text. Because escaping and unescaping
+     * is completely contextual, the API does not present two separate signatures.
+     *
+     * @since 3.0
+     */
+    private static abstract class CharSequenceTranslator {
+
+        /**
+         * Translate a set of codepoints, represented by an int index into a CharSequence,
+         * into another set of codepoints. The number of codepoints consumed must be returned,
+         * and the only IOExceptions thrown must be from interacting with the Writer so that
+         * the top level API may reliably ignore StringWriter IOExceptions.
+         *
+         * @param input CharSequence that is being translated
+         * @param index int representing the current point of translation
+         * @param out Writer to translate the text to
+         * @return int count of codepoints consumed
+         * @throws IOException if and only if the Writer produces an IOException
+         */
+        public abstract int translate(CharSequence input, int index, Writer out) throws IOException;
+
+        /**
+         * Helper for non-Writer usage.
+         *
+         * @param input CharSequence to be translated
+         * @return String output of translation
+         */
+        public final String translate(final CharSequence input) {
+            if (input == null) {
+                return null;
+            }
+            try {
+                final StringWriter writer = new StringWriter(input.length() * 2);
+                translate(input, writer);
+                return writer.toString();
+            } catch (final IOException ioe) {
+                // this should never ever happen while writing to a StringWriter
+                throw new RuntimeException(ioe);
+            }
+        }
+
+        /**
+         * Translate an input onto a Writer. This is intentionally final as its algorithm is
+         * tightly coupled with the abstract method of this class.
+         *
+         * @param input CharSequence that is being translated
+         * @param out Writer to translate the text to
+         * @throws IOException if and only if the Writer produces an IOException
+         */
+        public final void translate(final CharSequence input, final Writer out) throws IOException {
+            if (out == null) {
+                throw new IllegalArgumentException("The Writer must not be null");
+            }
+            if (input == null) {
+                return;
+            }
+            int pos = 0;
+            final int len = input.length();
+            while (pos < len) {
+                final int consumed = translate(input, pos, out);
+                if (consumed == 0) {
+                    // inlined implementation of Character.toChars(Character.codePointAt(input, pos))
+                    // avoids allocating temp char arrays and duplicate checks
+                    char c1 = input.charAt(pos);
+                    out.write(c1);
+                    pos++;
+                    if (Character.isHighSurrogate(c1) && pos < len) {
+                        char c2 = input.charAt(pos);
+                        if (Character.isLowSurrogate(c2)) {
+                            out.write(c2);
+                            pos++;
+                        }
+                    }
+                    continue;
+                }
+                // contract with translators is that they have to understand codepoints
+                // and they just took care of a surrogate pair
+                for (int pt = 0; pt < consumed; pt++) {
+                    pos += Character.charCount(Character.codePointAt(input, pos));
+                }
+            }
+        }
+
+        /**
+         * Helper method to create a merger of this translator with another set of
+         * translators. Useful in customizing the standard functionality.
+         *
+         * @param translators CharSequenceTranslator array of translators to merge with this one
+         * @return CharSequenceTranslator merging this translator with the others
+         */
+        public final CharSequenceTranslator with(final CharSequenceTranslator... translators) {
+            final CharSequenceTranslator[] newArray = new CharSequenceTranslator[translators.length + 1];
+            newArray[0] = this;
+            System.arraycopy(translators, 0, newArray, 1, translators.length);
+            return new AggregateTranslator(newArray);
+        }
+
+    }
+
+    /**
+     * Adapted from apache commons-lang3 project.
+     * <p>
+     * Translates a value using a lookup table.
+     *
+     * @since 3.0
+     */
+    private static class LookupTranslator extends CharSequenceTranslator {
+
+        private final HashMap<String, String> lookupMap;
+        private final HashSet<Character> prefixSet;
+        private final int shortest;
+        private final int longest;
+
+        /**
+         * Define the lookup table to be used in translation
+         * <p>
+         * Note that, as of Lang 3.1, the key to the lookup table is converted to a
+         * java.lang.String. This is because we need the key to support hashCode and
+         * equals(Object), allowing it to be the key for a HashMap. See LANG-882.
+         *
+         * @param lookup CharSequence[][] table of size [*][2]
+         */
+        public LookupTranslator(final CharSequence[]... lookup) {
+            lookupMap = new HashMap<>();
+            prefixSet = new HashSet<>();
+            int _shortest = Integer.MAX_VALUE;
+            int _longest = 0;
+            if (lookup != null) {
+                for (final CharSequence[] seq : lookup) {
+                    this.lookupMap.put(seq[0].toString(), seq[1].toString());
+                    this.prefixSet.add(seq[0].charAt(0));
+                    final int sz = seq[0].length();
+                    if (sz < _shortest) {
+                        _shortest = sz;
+                    }
+                    if (sz > _longest) {
+                        _longest = sz;
+                    }
+                }
+            }
+            shortest = _shortest;
+            longest = _longest;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
+            // check if translation exists for the input at position index
+            if (prefixSet.contains(input.charAt(index))) {
+                int max = longest;
+                if (index + longest > input.length()) {
+                    max = input.length() - index;
+                }
+                // implement greedy algorithm by trying maximum match first
+                for (int i = max; i >= shortest; i--) {
+                    final CharSequence subSeq = input.subSequence(index, index + i);
+                    final String result = lookupMap.get(subSeq.toString());
+
+                    if (result != null) {
+                        out.write(result);
+                        return i;
+                    }
+                }
+            }
+            return 0;
+        }
+    }
+
+    /**
+     * Adapted from apache commons-lang3 project.
+     * <p>
+     * Executes a sequence of translators one after the other. Execution ends whenever
+     * the first translator consumes codepoints from the input.
+     *
+     * @since 3.0
+     */
+    private static class AggregateTranslator extends CharSequenceTranslator {
+
+        private final CharSequenceTranslator[] translators;
+
+        /**
+         * Specify the translators to be used at creation time.
+         *
+         * @param translators CharSequenceTranslator array to aggregate
+         */
+        public AggregateTranslator(final CharSequenceTranslator... translators) {
+            this.translators = translators == null ? null : translators.clone();
+        }
+
+        /**
+         * The first translator to consume codepoints from the input is the 'winner'.
+         * Execution stops with the number of consumed codepoints being returned.
+         * {@inheritDoc}
+         */
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
+            for (final CharSequenceTranslator translator : translators) {
+                final int consumed = translator.translate(input, index, out);
+                if (consumed != 0) {
+                    return consumed;
+                }
+            }
+            return 0;
+        }
+
+    }
+
+    /**
+     * Adapted from apache commons-lang3 project.
+     * <p>
+     * Translate escaped octal Strings back to their octal values.
+     * <p>
+     * For example, "\45" should go back to being the specific value (a %).
+     * <p>
+     * Note that this currently only supports the viable range of octal for Java; namely
+     * 1 to 377. This is because parsing Java is the main use case.
+     *
+     * @since 3.0
+     */
+    private static class OctalUnescaper extends CharSequenceTranslator {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
+            final int remaining = input.length() - index - 1; // how many characters left, ignoring the first \
+            final StringBuilder builder = new StringBuilder();
+            if (input.charAt(index) == '\\' && remaining > 0 && isOctalDigit(input.charAt(index + 1))) {
+                final int next = index + 1;
+                final int next2 = index + 2;
+                final int next3 = index + 3;
+
+                // we know this is good as we checked it in the if block above
+                builder.append(input.charAt(next));
+
+                if (remaining > 1 && isOctalDigit(input.charAt(next2))) {
+                    builder.append(input.charAt(next2));
+                    if (remaining > 2 && isZeroToThree(input.charAt(next)) && isOctalDigit(input.charAt(next3))) {
+                        builder.append(input.charAt(next3));
+                    }
+                }
+
+                out.write(Integer.parseInt(builder.toString(), 8));
+                return 1 + builder.length();
+            }
+            return 0;
+        }
+
+        /**
+         * Checks if the given char is an octal digit. Octal digits are the character representations of the digits 0 to
+         * 7.
+         *
+         * @param ch the char to check
+         * @return true if the given char is the character representation of one of the digits from 0 to 7
+         */
+        private boolean isOctalDigit(final char ch) {
+            return ch >= '0' && ch <= '7';
+        }
+
+        /**
+         * Checks if the given char is the character representation of one of the digit from 0 to 3.
+         *
+         * @param ch the char to check
+         * @return true if the given char is the character representation of one of the digits from 0 to 3
+         */
+        private boolean isZeroToThree(final char ch) {
+            return ch >= '0' && ch <= '3';
+        }
+    }
+
+    /**
+     * Adapted from apache commons-lang3 project.
+     * <p>
+     * Translates escaped Unicode values of the form \\u+\d\d\d\d back to
+     * Unicode. It supports multiple 'u' characters and will work with or
+     * without the +.
+     *
+     * @since 3.0
+     */
+    private static class UnicodeUnescaper extends CharSequenceTranslator {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
+            if (input.charAt(index) == '\\' && index + 1 < input.length() && input.charAt(index + 1) == 'u') {
+                // consume optional additional 'u' chars
+                int i = 2;
+                while (index + i < input.length() && input.charAt(index + i) == 'u') {
+                    i++;
+                }
+
+                if (index + i < input.length() && input.charAt(index + i) == '+') {
+                    i++;
+                }
+
+                if (index + i + 4 <= input.length()) {
+                    // Get 4 hex digits
+                    final CharSequence unicode = input.subSequence(index + i, index + i + 4);
+
+                    try {
+                        final int value = Integer.parseInt(unicode.toString(), 16);
+                        out.write((char) value);
+                    } catch (final NumberFormatException nfe) {
+                        throw new IllegalArgumentException("Unable to parse unicode value: " + unicode, nfe);
+                    }
+                    return i + 4;
+                }
+                throw new IllegalArgumentException("Less than 4 hex digits in unicode value: '" + input.subSequence(index, input.length())
+                        + "' due to end of CharSequence");
+            }
+            return 0;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/Utils.java b/javaparser-core/src/main/java/com/github/javaparser/utils/Utils.java
new file mode 100644
index 0000000..2db00e5
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/Utils.java
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.utils;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.function.Function;
+
+import static java.util.Arrays.*;
+
+/**
+ * Any kind of utility.
+ *
+ * @author Federico Tomassetti
+ */
+public class Utils {
+    public static final String EOL = System.getProperty("line.separator");
+
+    public static final Predicate<String> STRING_NOT_EMPTY = s -> !s.isEmpty();
+
+    /**
+     * @deprecated This is no longer in use by JavaParser, please write your own replacement.
+     */
+    public static <T> List<T> ensureNotNull(List<T> list) {
+        return list == null ? new ArrayList<>() : list;
+    }
+
+    public static <E> boolean isNullOrEmpty(Collection<E> collection) {
+        return collection == null || collection.isEmpty();
+    }
+
+    public static <T> T assertNotNull(T o) {
+        if (o == null) {
+            throw new AssertionError("A reference was unexpectedly null.");
+        }
+        return o;
+    }
+
+    public static String assertNonEmpty(String string) {
+        if (string == null || string.isEmpty()) {
+            throw new AssertionError("A string was unexpectedly empty.");
+        }
+        return string;
+    }
+
+    /**
+     * @return string with ASCII characters 10 and 13 replaced by the text "\n" and "\r".
+     */
+    public static String escapeEndOfLines(String string) {
+        StringBuilder escapedString = new StringBuilder();
+        for (char c : string.toCharArray()) {
+            switch (c) {
+                case '\n':
+                    escapedString.append("\\n");
+                    break;
+                case '\r':
+                    escapedString.append("\\r");
+                    break;
+                default:
+                    escapedString.append(c);
+            }
+        }
+        return escapedString.toString();
+    }
+
+    public static String readerToString(Reader reader) throws IOException {
+        final StringBuilder result = new StringBuilder();
+        final char[] buffer = new char[8 * 1024];
+        int numChars;
+
+        while ((numChars = reader.read(buffer, 0, buffer.length)) > 0) {
+            result.append(buffer, 0, numChars);
+        }
+
+        return result.toString();
+    }
+
+    /**
+     * Puts varargs in a mutable list.
+     * This does not have the disadvantage of Arrays#asList that it has a static size.
+     *
+     * @deprecated This is no longer in use by JavaParser, please write your own replacement.
+     */
+    @Deprecated
+    public static <T> List<T> arrayToList(T[] array) {
+        List<T> list = new LinkedList<>();
+        Collections.addAll(list, array);
+        return list;
+    }
+
+    /**
+     * @deprecated use screamingToCamelCase
+     */
+    public static String toCamelCase(String original) {
+        return screamingToCamelCase(original);
+    }
+
+    /**
+     * Transform a string to the camel case conversion.
+     * <p>
+     * For example "ABC_DEF" becomes "abcDef"
+     */
+    public static String screamingToCamelCase(String original) {
+        StringBuilder sb = new StringBuilder();
+        String[] parts = original.toLowerCase().split("_");
+        for (int i = 0; i < parts.length; i++) {
+            sb.append(i == 0 ? parts[i] : capitalize(parts[i]));
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * @param input "aCamelCaseString"
+     * @return "A_CAMEL_CASE_STRING"
+     */
+    public static String camelCaseToScreaming(String input) {
+        if (input.isEmpty()) {
+            return "";
+        }
+        StringBuilder scream = new StringBuilder(input.substring(0, 1).toUpperCase());
+        for (char c : input.substring(1).toCharArray()) {
+            if (Character.isUpperCase(c)) {
+                scream.append("_");
+            }
+            scream.append(Character.toUpperCase(c));
+        }
+        return scream.toString();
+    }
+
+    /**
+     * Return the next word of the string, in other words it stops when a space is encountered.
+     */
+    public static String nextWord(String string) {
+        int index = 0;
+        while (index < string.length() && !Character.isWhitespace(string.charAt(index))) {
+            index++;
+        }
+        return string.substring(0, index);
+    }
+
+    /**
+     * Make an indent by appending indentLevel tab characters to the builder.
+     */
+    public static StringBuilder indent(StringBuilder builder, int indentLevel) {
+        for (int i = 0; i < indentLevel; i++) {
+            builder.append("\t");
+        }
+        return builder;
+    }
+
+    /**
+     * Capitalizes the first character in the string.
+     */
+    public static String capitalize(String s) {
+        return stringTransformer(s, "capitalize", String::toUpperCase);
+    }
+
+    /**
+     * Lower-cases the first character in the string.
+     */
+    public static String decapitalize(String s) {
+        return stringTransformer(s, "decapitalize", String::toLowerCase);
+    }
+
+    private static String stringTransformer(String s, String operationDescription, Function<String, String> transformation) {
+        if (s.isEmpty()) {
+            throw new IllegalArgumentException(String.format("You cannot %s an empty string", operationDescription));
+        }
+        return transformation.apply(s.substring(0, 1)) +
+                s.substring(1);
+    }
+
+    /**
+     * @return true if the value is null, an empty Optional, or an empty String.
+     */
+    public static boolean valueIsNullOrEmpty(Object value) {
+        if (value == null) {
+            return true;
+        }
+        if (value instanceof Optional) {
+            if (((Optional) value).isPresent()) {
+                value = ((Optional) value).get();
+            } else {
+                return true;
+            }
+        }
+        if (value instanceof Collection) {
+            if (((Collection) value).isEmpty()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @return a set of the items.
+     */
+    public static <T> Set<T> set(T... items) {
+        return new HashSet<>(asList(items));
+    }
+
+    /**
+     * @return content with all kinds of EOL characters replaced by endOfLineCharacter
+     */
+    public static String normalizeEolInTextBlock(String content, String endOfLineCharacter) {
+        return content
+                .replaceAll("\\R", endOfLineCharacter);
+    }
+
+    /**
+     * @return the filename with the last "." and everything following it removed.
+     */
+    public static String removeFileExtension(String filename) {
+        int extensionIndex = filename.lastIndexOf(".");
+        if (extensionIndex == -1)
+            return filename;
+
+        return filename.substring(0, extensionIndex);
+    }
+
+    /**
+     * Like {@link String#trim()}, but only the trailing spaces.
+     */
+    public static String trimTrailingSpaces(String line) {
+        while (line.length() > 0 && line.charAt(line.length() - 1) <= 0x20) {
+            line = line.substring(0, line.length() - 1);
+        }
+        return line;
+    }
+
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java
new file mode 100644
index 0000000..ea21787
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorList.java
@@ -0,0 +1,303 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.utils;

+

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Iterator;

+import java.util.List;

+import java.util.ListIterator;

+import java.util.stream.Collectors;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.visitor.GenericVisitor;

+import com.github.javaparser.ast.visitor.Visitable;

+import com.github.javaparser.ast.visitor.VoidVisitor;

+

+/**

+ * A list that overrides the equals and hashcode calculation of the added nodes

+ * by using another equals and hashcode visitor for those methods.

+ */

+public class VisitorList<N extends Node> implements List<N> {

+

+    protected List<EqualsHashcodeOverridingFacade> innerList;

+    protected final GenericVisitor<Integer, Void> hashcodeVisitor;

+    protected final GenericVisitor<Boolean, Visitable> equalsVisitor;

+

+    /**

+     * Pass the visitors to use for equals and hashcode.

+     */

+    public VisitorList(GenericVisitor<Integer, Void> hashcodeVisitor,

+                       GenericVisitor<Boolean, Visitable> equalsVisitor) {

+        this.hashcodeVisitor = hashcodeVisitor;

+        this.equalsVisitor = equalsVisitor;

+        innerList = new ArrayList<>();

+    }

+

+    @Override

+    public boolean add(N elem) {

+        return innerList.add(new EqualsHashcodeOverridingFacade(elem));

+    }

+

+    @Override

+    public void add(int index, N elem) {

+        innerList.add(index, new EqualsHashcodeOverridingFacade(elem));

+    }

+

+    @Override

+    public boolean addAll(Collection<? extends N> col) {

+        boolean modified = false;

+        for (N elem : col)

+            if (add(elem))

+                modified = true;

+        return modified;

+    }

+

+    @Override

+    public boolean addAll(int index, Collection<? extends N> col) {

+        if (col.isEmpty())

+            return false;

+        for (N elem : col) {

+            if (index == size())

+                add(elem);

+            else

+                add(index, elem);

+            index++;

+        }

+        return true;

+    }

+

+    @Override

+    public void clear() {

+        innerList.clear();

+    }

+

+    @Override

+    public boolean contains(Object elem) {

+        return innerList.contains(new EqualsHashcodeOverridingFacade((N) elem));

+    }

+

+    @Override

+    public boolean containsAll(Collection<?> col) {

+        for (Object elem : col)

+            if (!contains(elem))

+                return false;

+        return true;

+    }

+

+    @Override

+    public N get(int index) {

+        return innerList.get(index).overridden;

+    }

+

+    @Override

+    public int indexOf(Object elem) {

+        return innerList.indexOf(new EqualsHashcodeOverridingFacade((N) elem));

+    }

+

+    @Override

+    public boolean isEmpty() {

+        return innerList.isEmpty();

+    }

+

+    @Override

+    public Iterator<N> iterator() {

+        return new Iterator<N>() {

+            final Iterator<EqualsHashcodeOverridingFacade> itr = innerList.iterator();

+

+            @Override

+            public boolean hasNext() {

+                return itr.hasNext();

+            }

+

+            @Override

+            public N next() {

+                return itr.next().overridden;

+            }

+

+            @Override

+            public void remove() {

+                itr.remove();

+            }

+        };

+    }

+

+    @Override

+    public int lastIndexOf(Object elem) {

+        return innerList.lastIndexOf(new EqualsHashcodeOverridingFacade((N) elem));

+    }

+

+    @Override

+    public ListIterator<N> listIterator() {

+        return listIterator(0);

+    }

+

+    @Override

+    public ListIterator<N> listIterator(int index) {

+        return new ListIterator<N>() {

+            final ListIterator<EqualsHashcodeOverridingFacade> itr = innerList.listIterator(index);

+

+            @Override

+            public boolean hasNext() {

+                return itr.hasNext();

+            }

+

+            @Override

+            public N next() {

+                return itr.next().overridden;

+            }

+

+            @Override

+            public void remove() {

+                itr.remove();

+            }

+

+            @Override

+            public void add(N elem) {

+                itr.add(new EqualsHashcodeOverridingFacade((N) elem));

+            }

+

+            @Override

+            public boolean hasPrevious() {

+                return itr.hasPrevious();

+            }

+

+            @Override

+            public int nextIndex() {

+                return itr.nextIndex();

+            }

+

+            @Override

+            public N previous() {

+                return itr.previous().overridden;

+            }

+

+            @Override

+            public int previousIndex() {

+                return itr.previousIndex();

+            }

+

+            @Override

+            public void set(N elem) {

+                itr.set(new EqualsHashcodeOverridingFacade((N) elem));

+            }

+        };

+    }

+

+    @Override

+    public boolean remove(Object elem) {

+        return innerList.remove(new EqualsHashcodeOverridingFacade((N) elem));

+    }

+

+    @Override

+    public N remove(int index) {

+        return innerList.remove(index).overridden;

+    }

+

+    @Override

+    public boolean removeAll(Collection<?> col) {

+        boolean modified = false;

+        for (Object elem : col)

+            if (remove(elem))

+                modified = true;

+        return modified;

+    }

+

+    @Override

+    public boolean retainAll(Collection<?> col) {

+        int oldSize = size();

+        clear();

+        addAll((Collection<? extends N>) col);

+        return size() != oldSize;

+    }

+

+    @Override

+    public N set(int index, N elem) {

+        return innerList.set(index, new EqualsHashcodeOverridingFacade((N) elem)).overridden;

+    }

+

+    @Override

+    public int size() {

+        return innerList.size();

+    }

+

+    @Override

+    public List<N> subList(int fromIndex, int toIndex) {

+        return new VisitorList<N>(hashcodeVisitor, equalsVisitor) {

+            {

+                this.innerList = VisitorList.this.innerList.subList(fromIndex, toIndex);

+            }

+        };

+    }

+

+    @Override

+    public Object[] toArray() {

+        return innerList.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray();

+    }

+

+    @Override

+    public <T> T[] toArray(T[] arr) {

+        return innerList.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray(arr);

+    }

+

+    @Override

+    public String toString() {

+        StringBuilder sb = new StringBuilder("[");

+        if (size() == 0)

+            return sb.append("]").toString();

+        for (EqualsHashcodeOverridingFacade facade : innerList) {

+            sb.append(facade.overridden.toString() + ", ");

+        }

+        return sb.replace(sb.length() - 2, sb.length(), "]").toString();

+    }

+

+    private class EqualsHashcodeOverridingFacade implements Visitable {

+        private final N overridden;

+

+        EqualsHashcodeOverridingFacade(N overridden) {

+            this.overridden = overridden;

+        }

+

+        @Override

+        public <R, A> R accept(GenericVisitor<R, A> v, A arg) {

+            throw new AssertionError();

+        }

+

+        @Override

+        public <A> void accept(VoidVisitor<A> v, A arg) {

+            throw new AssertionError();

+        }

+

+        @Override

+        public final int hashCode() {

+            return overridden.accept(hashcodeVisitor, null);

+        }

+

+        @Override

+        public boolean equals(final Object obj) {

+            if (obj == null || !(obj instanceof VisitorList.EqualsHashcodeOverridingFacade)) {

+                return false;

+            }

+            return overridden.accept(equalsVisitor, ((EqualsHashcodeOverridingFacade) obj).overridden);

+        }

+    }

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorMap.java b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorMap.java
new file mode 100644
index 0000000..ab21b91
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorMap.java
@@ -0,0 +1,125 @@
+package com.github.javaparser.utils;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.Visitable;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * A map that overrides the equals and hashcode calculation of the added nodes
+ * by using another equals and hashcode visitor for those methods.
+ */
+public class VisitorMap<N extends Node, V> implements Map<N, V> {
+    private final Map<EqualsHashcodeOverridingFacade, V> innerMap = new HashMap<>();
+    private final GenericVisitor<Integer, Void> hashcodeVisitor;
+    private final GenericVisitor<Boolean, Visitable> equalsVisitor;
+
+    /**
+     * Pass the visitors to use for equals and hashcode.
+     */
+    public VisitorMap(GenericVisitor<Integer, Void> hashcodeVisitor, GenericVisitor<Boolean, Visitable> equalsVisitor) {
+        this.hashcodeVisitor = hashcodeVisitor;
+        this.equalsVisitor = equalsVisitor;
+    }
+    
+    @Override
+    public int size() {
+        return innerMap.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return innerMap.isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return innerMap.containsKey(new EqualsHashcodeOverridingFacade((N) key));
+    }
+
+    @Override
+    public boolean containsValue(Object value) {
+        return innerMap.containsValue(value);
+    }
+
+    @Override
+    public V get(Object key) {
+        return innerMap.get(new EqualsHashcodeOverridingFacade((N) key));
+    }
+
+    @Override
+    public V put(N key, V value) {
+        return innerMap.put(new EqualsHashcodeOverridingFacade(key), value);
+    }
+
+    private class EqualsHashcodeOverridingFacade implements Visitable {
+        private final N overridden;
+
+        EqualsHashcodeOverridingFacade(N overridden) {
+            this.overridden = overridden;
+        }
+
+        @Override
+        public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+            throw new AssertionError();
+        }
+
+        @Override
+        public <A> void accept(VoidVisitor<A> v, A arg) {
+            throw new AssertionError();
+        }
+
+        @Override
+        public final int hashCode() {
+            return overridden.accept(hashcodeVisitor, null);
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            if (obj == null || !(obj instanceof VisitorMap.EqualsHashcodeOverridingFacade)) {
+                return false;
+            }
+            return overridden.accept(equalsVisitor, ((EqualsHashcodeOverridingFacade) obj).overridden);
+        }
+    }
+
+    @Override
+    public V remove(Object key) {
+        return innerMap.remove(new EqualsHashcodeOverridingFacade((N) key));
+    }
+
+    @Override
+    public void putAll(Map<? extends N, ? extends V> m) {
+        m.forEach(this::put);
+    }
+
+    @Override
+    public void clear() {
+        innerMap.clear();
+    }
+
+    @Override
+    public Set<N> keySet() {
+        return innerMap.keySet().stream()
+                .map(k -> k.overridden)
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public Collection<V> values() {
+        return innerMap.values();
+    }
+
+    @Override
+    public Set<Entry<N, V>> entrySet() {
+        return innerMap.entrySet().stream()
+                .map(e -> new HashMap.SimpleEntry<>(e.getKey().overridden, e.getValue()))
+                .collect(Collectors.toSet());
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java
new file mode 100644
index 0000000..70fc358
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/utils/VisitorSet.java
@@ -0,0 +1,191 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.utils;

+

+import java.util.Collection;

+import java.util.HashSet;

+import java.util.Iterator;

+import java.util.Set;

+import java.util.stream.Collectors;

+

+import com.github.javaparser.ast.Node;

+import com.github.javaparser.ast.visitor.GenericVisitor;

+import com.github.javaparser.ast.visitor.Visitable;

+import com.github.javaparser.ast.visitor.VoidVisitor;

+

+/**

+ * A set that overrides the equals and hashcode calculation of the added nodes

+ * by using another equals and hashcode visitor for those methods.

+ */

+public class VisitorSet<N extends Node> implements Set<N> {

+

+    private final Set<EqualsHashcodeOverridingFacade> innerSet = new HashSet<>();

+    private final GenericVisitor<Integer, Void> hashcodeVisitor;

+    private final GenericVisitor<Boolean, Visitable> equalsVisitor;

+

+    /**

+     * Pass the visitors to use for equals and hashcode.

+     */

+    public VisitorSet(GenericVisitor<Integer, Void> hashcodeVisitor, GenericVisitor<Boolean, Visitable> equalsVisitor) {

+        this.hashcodeVisitor = hashcodeVisitor;

+        this.equalsVisitor = equalsVisitor;

+    }

+

+    @Override

+    public boolean add(N elem) {

+        return innerSet.add(new EqualsHashcodeOverridingFacade(elem));

+    }

+

+    @Override

+    public boolean addAll(Collection<? extends N> col) {

+        boolean modified = false;

+        for (N elem : col)

+            if (add(elem))

+                modified = true;

+        return modified;

+    }

+

+    @Override

+    public void clear() {

+        innerSet.clear();

+    }

+

+    @Override

+    public boolean contains(Object elem) {

+        return innerSet.contains(new EqualsHashcodeOverridingFacade((N) elem));

+    }

+

+    @Override

+    public boolean containsAll(Collection<?> col) {

+        for (Object elem : col)

+            if (!contains(elem))

+                return false;

+        return true;

+    }

+

+    @Override

+    public boolean isEmpty() {

+        return innerSet.isEmpty();

+    }

+

+    @Override

+    public Iterator<N> iterator() {

+        return new Iterator<N>() {

+            final Iterator<EqualsHashcodeOverridingFacade> itr = innerSet.iterator();

+

+            @Override

+            public boolean hasNext() {

+                return itr.hasNext();

+            }

+

+            @Override

+            public N next() {

+                return itr.next().overridden;

+            }

+

+            @Override

+            public void remove() {

+                itr.remove();

+            }

+        };

+    }

+

+    @Override

+    public boolean remove(Object elem) {

+        return innerSet.remove(new EqualsHashcodeOverridingFacade((N) elem));

+    }

+

+    @Override

+    public boolean removeAll(Collection<?> col) {

+        boolean modified = false;

+        for (Object elem : col)

+            if (remove(elem))

+                modified = true;

+        return modified;

+    }

+

+    @Override

+    public boolean retainAll(Collection<?> col) {

+        int oldSize = size();

+        clear();

+        addAll((Collection<? extends N>) col);

+        return size() != oldSize;

+    }

+

+    @Override

+    public int size() {

+        return innerSet.size();

+    }

+

+    @Override

+    public Object[] toArray() {

+        return innerSet.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray();

+    }

+

+    @Override

+    public <T> T[] toArray(T[] arr) {

+        return innerSet.stream().map(facade -> facade.overridden).collect(Collectors.toList()).toArray(arr);

+    }

+

+    @Override

+    public String toString() {

+        StringBuilder sb = new StringBuilder("[");

+        if (size() == 0)

+            return sb.append("]").toString();

+        for (EqualsHashcodeOverridingFacade facade : innerSet) {

+            sb.append(facade.overridden.toString() + ",");

+        }

+        return sb.replace(sb.length() - 2, sb.length(), "]").toString();

+    }

+

+    private class EqualsHashcodeOverridingFacade implements Visitable {

+        private final N overridden;

+

+        EqualsHashcodeOverridingFacade(N overridden) {

+            this.overridden = overridden;

+        }

+

+        @Override

+        public <R, A> R accept(GenericVisitor<R, A> v, A arg) {

+            throw new AssertionError();

+        }

+

+        @Override

+        public <A> void accept(VoidVisitor<A> v, A arg) {

+            throw new AssertionError();

+        }

+

+        @Override

+        public final int hashCode() {

+            return overridden.accept(hashcodeVisitor, null);

+        }

+

+        @Override

+        public boolean equals(final Object obj) {

+            if (obj == null || !(obj instanceof VisitorSet.EqualsHashcodeOverridingFacade)) {

+                return false;

+            }

+            return overridden.accept(equalsVisitor, ((EqualsHashcodeOverridingFacade) obj).overridden);

+        }

+    }

+

+}

diff --git a/javaparser-core/src/main/java/com/github/javaparser/version/Java10PostProcessor.java b/javaparser-core/src/main/java/com/github/javaparser/version/Java10PostProcessor.java
new file mode 100644
index 0000000..7130870
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/version/Java10PostProcessor.java
@@ -0,0 +1,24 @@
+package com.github.javaparser.version;
+
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.VarType;
+
+import static com.github.javaparser.ParseResult.PostProcessor;
+
+/**
+ * Processes the generic AST into a Java 10 AST and validates it.
+ */
+public class Java10PostProcessor extends PostProcessors {
+    protected final PostProcessor varNodeCreator = (result, configuration) ->
+            result.getResult().ifPresent(node -> {
+                node.findAll(ClassOrInterfaceType.class).forEach(n -> {
+                    if (n.getNameAsString().equals("var")) {
+                        n.replace(new VarType(n.getTokenRange().orElse(null)));
+                    }
+                });
+            });
+
+    public Java10PostProcessor() {
+        add(varNodeCreator);
+    }
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/version/Java11PostProcessor.java b/javaparser-core/src/main/java/com/github/javaparser/version/Java11PostProcessor.java
new file mode 100644
index 0000000..004967e
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/version/Java11PostProcessor.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.version;
+
+/**
+ * Processes the generic AST into a Java 10 AST and validates it.
+ */
+public class Java11PostProcessor extends Java10PostProcessor {
+}
diff --git a/javaparser-core/src/main/java/com/github/javaparser/version/PostProcessors.java b/javaparser-core/src/main/java/com/github/javaparser/version/PostProcessors.java
new file mode 100644
index 0000000..4220de3
--- /dev/null
+++ b/javaparser-core/src/main/java/com/github/javaparser/version/PostProcessors.java
@@ -0,0 +1,49 @@
+package com.github.javaparser.version;
+
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.Node;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.github.javaparser.ParseResult.PostProcessor;
+
+/**
+ * A post processor that will call a collection of post processors.
+ */
+public class PostProcessors implements PostProcessor {
+    private final List<PostProcessor> postProcessors = new ArrayList<>();
+
+    public PostProcessors(PostProcessor... postProcessors) {
+        this.postProcessors.addAll(Arrays.asList(postProcessors));
+    }
+
+    public List<PostProcessor> getPostProcessors() {
+        return postProcessors;
+    }
+
+    public PostProcessors remove(PostProcessor postProcessor) {
+        if (!postProcessors.remove(postProcessor)) {
+            throw new AssertionError("Trying to remove a post processor that isn't there.");
+        }
+        return this;
+    }
+
+    public PostProcessors replace(PostProcessor oldProcessor, PostProcessor newProcessor) {
+        remove(oldProcessor);
+        add(newProcessor);
+        return this;
+    }
+
+    public PostProcessors add(PostProcessor newProcessor) {
+        postProcessors.add(newProcessor);
+        return this;
+    }
+
+    @Override
+    public void process(ParseResult<? extends Node> result, ParserConfiguration configuration) {
+        postProcessors.forEach(pp -> pp.process(result, configuration));
+    }
+}
diff --git a/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java
new file mode 100644
index 0000000..ef0b7ef
--- /dev/null
+++ b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserBase.java
@@ -0,0 +1,369 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.ArrayCreationLevel;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.comments.CommentsCollection;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.utils.Pair;
+
+import java.util.*;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.EOF;
+import static com.github.javaparser.ast.type.ArrayType.unwrapArrayTypes;
+import static com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Base class for {@link GeneratedJavaParser}
+ */
+abstract class GeneratedJavaParserBase {
+    //// Interface with the generated code
+    abstract GeneratedJavaParserTokenManager getTokenSource();
+
+    abstract void ReInit(Provider provider);
+
+    /* Returns the JavaParser specific token type of the last matched token */
+    abstract JavaToken token();
+
+    abstract Token getNextToken();
+
+    ////
+
+    /* The problems encountered while parsing */
+    List<Problem> problems = new ArrayList<>();
+    /* Configuration flag whether we store tokens and tokenranges */
+    boolean storeTokens;
+
+    /* Resets the parser for reuse, gaining a little performance */
+    void reset(Provider provider) {
+        ReInit(provider);
+        problems = new ArrayList<>();
+        getTokenSource().reset();
+    }
+
+    /**
+     * Return the list of JavaParser specific tokens that have been encountered while parsing code using this parser.
+     *
+     * @return a list of tokens
+     */
+    public List<JavaToken> getTokens() {
+        return getTokenSource().getTokens();
+    }
+
+    /* The collection of comments encountered */
+    CommentsCollection getCommentsCollection() {
+        return getTokenSource().getCommentsCollection();
+    }
+
+    /* Reports a problem to the user */
+    void addProblem(String message) {
+        // TODO tokenRange only takes the final token. Need all the tokens.
+        problems.add(new Problem(message, tokenRange(), null));
+    }
+
+    /* Returns a tokenRange that spans the last matched token */
+    TokenRange tokenRange() {
+        if (storeTokens) {
+            return new TokenRange(token(), token());
+        }
+        return null;
+    }
+
+    /**
+     * Return a TokenRange spanning from begin to end
+     */
+    TokenRange range(JavaToken begin, JavaToken end) {
+        if (storeTokens) {
+            return new TokenRange(begin, end);
+        }
+        return null;
+    }
+
+    /**
+     * Return a TokenRange spanning from begin to end
+     */
+    TokenRange range(Node begin, JavaToken end) {
+        if (storeTokens) {
+            return new TokenRange(begin.getTokenRange().get().getBegin(), end);
+        }
+        return null;
+    }
+
+    /**
+     * Return a TokenRange spanning from begin to end
+     */
+    TokenRange range(JavaToken begin, Node end) {
+        if (storeTokens) {
+            return new TokenRange(begin, end.getTokenRange().get().getEnd());
+        }
+        return null;
+    }
+
+    /**
+     * Return a TokenRange spanning from begin to end
+     */
+    TokenRange range(Node begin, Node end) {
+        if (storeTokens) {
+            return new TokenRange(begin.getTokenRange().get().getBegin(), end.getTokenRange().get().getEnd());
+        }
+        return null;
+    }
+
+    /**
+     * @return secondChoice if firstChoice is JavaToken.UNKNOWN, otherwise firstChoice
+     */
+    JavaToken orIfInvalid(JavaToken firstChoice, JavaToken secondChoice) {
+        if (storeTokens) {
+            assertNotNull(firstChoice);
+            assertNotNull(secondChoice);
+            if (firstChoice.valid() || secondChoice.invalid()) {
+                return firstChoice;
+            }
+            return secondChoice;
+        }
+        return null;
+    }
+
+    /**
+     * @return the begin-token secondChoice if firstChoice is JavaToken.UNKNOWN, otherwise firstChoice
+     */
+    JavaToken orIfInvalid(JavaToken firstChoice, Node secondChoice) {
+        if (storeTokens) {
+            return orIfInvalid(firstChoice, secondChoice.getTokenRange().get().getBegin());
+        }
+        return null;
+    }
+
+    /**
+     * Get the token that starts the NodeList l
+     */
+    JavaToken nodeListBegin(NodeList<?> l) {
+        if (!storeTokens || l.isEmpty()) {
+            return JavaToken.INVALID;
+        }
+        return l.get(0).getTokenRange().get().getBegin();
+    }
+
+    /* Sets the kind of the last matched token to newKind */
+    void setTokenKind(int newKind) {
+        token().setKind(newKind);
+    }
+
+    /* Makes the parser keep a list of tokens */
+    void setStoreTokens(boolean storeTokens) {
+        this.storeTokens = storeTokens;
+        getTokenSource().setStoreTokens(storeTokens);
+    }
+
+    /* Called from within a catch block to skip forward to a known token,
+        and report the occurred exception as a problem. */
+    TokenRange recover(int recoveryTokenType, ParseException p) {
+        JavaToken begin = null;
+        if (p.currentToken != null) {
+            begin = token();
+        }
+        Token t;
+        do {
+            t = getNextToken();
+        } while (t.kind != recoveryTokenType && t.kind != EOF);
+
+        JavaToken end = token();
+
+        TokenRange tokenRange = null;
+        if (begin != null && end != null) {
+            tokenRange = range(begin, end);
+        }
+
+        problems.add(new Problem(makeMessageForParseException(p), tokenRange, p));
+        return tokenRange;
+    }
+
+    /**
+     * Quickly create a new NodeList
+     */
+    <T extends Node> NodeList<T> emptyList() {
+        return new NodeList<>();
+    }
+
+    /**
+     * Add obj to list and return it. Create a new list if list is null
+     */
+    <T extends Node> NodeList<T> add(NodeList<T> list, T obj) {
+        if (list == null) {
+            list = new NodeList<>();
+        }
+        list.add(obj);
+        return list;
+    }
+
+    /**
+     * Add obj to list only when list is not null
+     */
+    <T extends Node> NodeList<T> addWhenNotNull(NodeList<T> list, T obj) {
+        if (obj == null) {
+            return list;
+        }
+        return add(list, obj);
+    }
+
+    /**
+     * Add obj to list at position pos
+     */
+    <T extends Node> NodeList<T> prepend(NodeList<T> list, T obj) {
+        if (list == null) {
+            list = new NodeList<>();
+        }
+        list.addFirst(obj);
+        return list;
+    }
+
+    /**
+     * Add obj to list
+     */
+    <T> List<T> add(List<T> list, T obj) {
+        if (list == null) {
+            list = new LinkedList<>();
+        }
+        list.add(obj);
+        return list;
+    }
+
+    /**
+     * Add modifier mod to modifiers
+     */
+    void addModifier(EnumSet<Modifier> modifiers, Modifier mod) {
+        if (modifiers.contains(mod)) {
+            addProblem("Duplicated modifier");
+        }
+        modifiers.add(mod);
+    }
+
+    /**
+     * Propagate expansion of the range on the right to the parent. This is necessary when the right border of the child
+     * is determining the right border of the parent (i.e., the child is the last element of the parent). In this case
+     * when we "enlarge" the child we should enlarge also the parent.
+     */
+    private void propagateRangeGrowthOnRight(Node node, Node endNode) {
+        if (storeTokens) {
+            node.getParentNode().ifPresent(nodeParent -> {
+                boolean isChildOnTheRightBorderOfParent = node.getTokenRange().get().getEnd().equals(nodeParent.getTokenRange().get().getEnd());
+                if (isChildOnTheRightBorderOfParent) {
+                    propagateRangeGrowthOnRight(nodeParent, endNode);
+                }
+            });
+            node.setTokenRange(range(node, endNode));
+        }
+    }
+
+    /**
+     * Workaround for rather complex ambiguity that lambda's create
+     */
+    Expression generateLambda(Expression ret, Statement lambdaBody) {
+        if (ret instanceof EnclosedExpr) {
+            Expression inner = ((EnclosedExpr) ret).getInner();
+            SimpleName id = ((NameExpr) inner).getName();
+            NodeList<Parameter> params = add(new NodeList<>(), new Parameter(ret.getTokenRange().orElse(null), EnumSet.noneOf(Modifier.class), new NodeList<>(), new UnknownType(), false, new NodeList<>(), id));
+            ret = new LambdaExpr(range(ret, lambdaBody), params, lambdaBody, true);
+        } else if (ret instanceof NameExpr) {
+            SimpleName id = ((NameExpr) ret).getName();
+            NodeList<Parameter> params = add(new NodeList<>(), new Parameter(ret.getTokenRange().orElse(null), EnumSet.noneOf(Modifier.class), new NodeList<>(), new UnknownType(), false, new NodeList<>(), id));
+            ret = new LambdaExpr(range(ret, lambdaBody), params, lambdaBody, false);
+        } else if (ret instanceof LambdaExpr) {
+            ((LambdaExpr) ret).setBody(lambdaBody);
+            propagateRangeGrowthOnRight(ret, lambdaBody);
+        } else if (ret instanceof CastExpr) {
+            CastExpr castExpr = (CastExpr) ret;
+            Expression inner = generateLambda(castExpr.getExpression(), lambdaBody);
+            castExpr.setExpression(inner);
+        } else {
+            addProblem("Failed to parse lambda expression! Please create an issue at https://github.com/javaparser/javaparser/issues");
+        }
+        return ret;
+    }
+
+    /**
+     * Throws together an ArrayCreationExpr from a lot of pieces
+     */
+    ArrayCreationExpr juggleArrayCreation(TokenRange range, List<TokenRange> levelRanges, Type type, NodeList<Expression> dimensions, List<NodeList<AnnotationExpr>> arrayAnnotations, ArrayInitializerExpr arrayInitializerExpr) {
+        NodeList<ArrayCreationLevel> levels = new NodeList<>();
+
+        for (int i = 0; i < arrayAnnotations.size(); i++) {
+            levels.add(new ArrayCreationLevel(levelRanges.get(i), dimensions.get(i), arrayAnnotations.get(i)));
+        }
+        return new ArrayCreationExpr(range, type, levels, arrayInitializerExpr);
+    }
+
+    /**
+     * Throws together a Type, taking care of all the array brackets
+     */
+    Type juggleArrayType(Type partialType, List<ArrayType.ArrayBracketPair> additionalBrackets) {
+        Pair<Type, List<ArrayType.ArrayBracketPair>> partialParts = unwrapArrayTypes(partialType);
+        Type elementType = partialParts.a;
+        List<ArrayType.ArrayBracketPair> leftMostBrackets = partialParts.b;
+        return wrapInArrayTypes(elementType, leftMostBrackets, additionalBrackets).clone();
+    }
+
+    /**
+     * This is the code from ParseException.initialise, modified to be more horizontal.
+     */
+    private String makeMessageForParseException(ParseException exception) {
+        final StringBuilder sb = new StringBuilder("Parse error. Found ");
+        final StringBuilder expected = new StringBuilder();
+
+        int maxExpectedTokenSequenceLength = 0;
+        TreeSet<String> sortedOptions = new TreeSet<>();
+        for (int i = 0; i < exception.expectedTokenSequences.length; i++) {
+            if (maxExpectedTokenSequenceLength < exception.expectedTokenSequences[i].length) {
+                maxExpectedTokenSequenceLength = exception.expectedTokenSequences[i].length;
+            }
+            for (int j = 0; j < exception.expectedTokenSequences[i].length; j++) {
+                sortedOptions.add(exception.tokenImage[exception.expectedTokenSequences[i][j]]);
+            }
+        }
+
+        for (String option : sortedOptions) {
+            expected.append(" ").append(option);
+        }
+
+        sb.append("");
+
+        Token token = exception.currentToken.next;
+        for (int i = 0; i < maxExpectedTokenSequenceLength; i++) {
+            String tokenText = token.image;
+            String escapedTokenText = ParseException.add_escapes(tokenText);
+            if (i != 0) {
+                sb.append(" ");
+            }
+            if (token.kind == 0) {
+                sb.append(exception.tokenImage[0]);
+                break;
+            }
+            escapedTokenText = "\"" + escapedTokenText + "\"";
+            String image = exception.tokenImage[token.kind];
+            if (image.equals(escapedTokenText)) {
+                sb.append(image);
+            } else {
+                sb.append(" ")
+                        .append(escapedTokenText)
+                        .append(" ")
+                        .append(image);
+            }
+            token = token.next;
+        }
+
+        if (exception.expectedTokenSequences.length != 0) {
+            int numExpectedTokens = exception.expectedTokenSequences.length;
+            sb.append(", expected")
+                    .append(numExpectedTokens == 1 ? "" : " one of ")
+                    .append(expected.toString());
+        }
+        return sb.toString();
+    }
+}
diff --git a/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserTokenManagerBase.java b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserTokenManagerBase.java
new file mode 100644
index 0000000..da4331e
--- /dev/null
+++ b/javaparser-core/src/main/javacc-support/com/github/javaparser/GeneratedJavaParserTokenManagerBase.java
@@ -0,0 +1,46 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.*;
+import static com.github.javaparser.Position.pos;
+
+/**
+ * Base class for {@link com.github.javaparser.GeneratedJavaParserTokenManager}
+ */
+abstract class GeneratedJavaParserTokenManagerBase {
+    /**
+     * Create a TokenRange that spans exactly one token
+     */
+    private static TokenRange tokenRange(Token token) {
+        JavaToken javaToken = token.javaToken;
+        return new TokenRange(javaToken, javaToken);
+    }
+
+    /**
+     * Since comments are completely captured in a single token, including their delimiters, deconstruct them here so we
+     * can turn them into nodes later on.
+     */
+    static Comment createCommentFromToken(Token token) {
+        String commentText = token.image;
+        if (token.kind == JAVADOC_COMMENT) {
+            return new JavadocComment(tokenRange(token), commentText.substring(3, commentText.length() - 2));
+        } else if (token.kind == MULTI_LINE_COMMENT) {
+            return new BlockComment(tokenRange(token), commentText.substring(2, commentText.length() - 2));
+        } else if (token.kind == SINGLE_LINE_COMMENT) {
+            // line comments have their end of line character(s) included, and we don't want that.
+            Range range = new Range(pos(token.beginLine, token.beginColumn), pos(token.endLine, token.endColumn));
+            while (commentText.endsWith("\r") || commentText.endsWith("\n")) {
+                commentText = commentText.substring(0, commentText.length() - 1);
+            }
+            range = range.withEnd(pos(range.begin.line, range.begin.column + commentText.length()));
+            LineComment comment = new LineComment(tokenRange(token), commentText.substring(2));
+            comment.setRange(range);
+            return comment;
+        }
+        throw new AssertionError("Unexpectedly got passed a non-comment token.");
+    }
+}
diff --git a/javaparser-core/src/main/javacc-support/com/github/javaparser/ModifierHolder.java b/javaparser-core/src/main/javacc-support/com/github/javaparser/ModifierHolder.java
new file mode 100644
index 0000000..46d2e8f
--- /dev/null
+++ b/javaparser-core/src/main/javacc-support/com/github/javaparser/ModifierHolder.java
@@ -0,0 +1,24 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+
+import java.util.EnumSet;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Helper class for {@link GeneratedJavaParser}
+ */
+class ModifierHolder {
+    final EnumSet<Modifier> modifiers;
+    final NodeList<AnnotationExpr> annotations;
+    final JavaToken begin;
+
+    ModifierHolder(JavaToken begin, EnumSet<Modifier> modifiers, NodeList<AnnotationExpr> annotations) {
+        this.begin = begin;
+        this.modifiers = assertNotNull(modifiers);
+        this.annotations = annotations;
+    }
+}
diff --git a/javaparser-core/src/main/javacc-support/com/github/javaparser/RangedList.java b/javaparser-core/src/main/javacc-support/com/github/javaparser/RangedList.java
new file mode 100644
index 0000000..328ec50
--- /dev/null
+++ b/javaparser-core/src/main/javacc-support/com/github/javaparser/RangedList.java
@@ -0,0 +1,33 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+
+/**
+ * Helper class for {@link GeneratedJavaParser}
+ */
+class RangedList<T extends Node> {
+    /* A ranged list MUST be set to a begin and end,
+       or these temporary values will leak out */
+    TokenRange range = new TokenRange(JavaToken.INVALID, JavaToken.INVALID);
+    NodeList<T> list;
+
+    RangedList(NodeList<T> list) {
+        this.list = list;
+    }
+
+    void beginAt(JavaToken begin) {
+        range = range.withBegin(begin);
+    }
+
+    void endAt(JavaToken end) {
+        range = range.withEnd(end);
+    }
+
+    void add(T t) {
+        if (list == null) {
+            list = new NodeList<>();
+        }
+        list.add(t);
+    }
+}
diff --git a/javaparser-core/src/main/javacc-support/com/github/javaparser/TokenBase.java b/javaparser-core/src/main/javacc-support/com/github/javaparser/TokenBase.java
new file mode 100644
index 0000000..c52663c
--- /dev/null
+++ b/javaparser-core/src/main/javacc-support/com/github/javaparser/TokenBase.java
@@ -0,0 +1,18 @@
+package com.github.javaparser;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.GT;
+
+/**
+ * Base class for the generated {@link Token}
+ */
+abstract class TokenBase {
+    /**
+     * For tracking the >> >>> ambiguity.
+     */
+    int realKind = GT;
+    
+    /**
+     * This is the link to the token that JavaParser presents to the user
+     */
+    JavaToken javaToken = null;
+}
diff --git a/javaparser-core/src/main/javacc/java.jj b/javaparser-core/src/main/javacc/java.jj
new file mode 100644
index 0000000..c688228
--- /dev/null
+++ b/javaparser-core/src/main/javacc/java.jj
@@ -0,0 +1,2795 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+options {
+  STATIC=false;
+  COMMON_TOKEN_ACTION=true;
+  JDK_VERSION = "1.8";
+  TOKEN_EXTENDS ="TokenBase";
+  JAVA_TEMPLATE_TYPE = "modern";
+}
+
+PARSER_BEGIN(GeneratedJavaParser)
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser;
+import java.io.*;
+import java.util.*;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.utils.*;
+import javax.annotation.Generated;
+import static com.github.javaparser.JavaToken.INVALID;
+import static com.github.javaparser.ast.Node.Parsedness.UNPARSABLE;
+import static com.github.javaparser.utils.Utils.*;
+import static com.github.javaparser.ast.NodeList.*;
+import static com.github.javaparser.GeneratedJavaParser.*;
+import static com.github.javaparser.Range.*;
+import static com.github.javaparser.Position.*;
+import static com.github.javaparser.ast.type.ArrayType.*;
+import static com.github.javaparser.GeneratedJavaParserTokenManagerBase.*;
+
+@Generated("JavaCC")
+final class GeneratedJavaParser extends GeneratedJavaParserBase {
+    /* Returns the JavaParser specific token type of the last matched token */
+    JavaToken token() {
+        return token.javaToken;
+    }
+
+    /* Changes the amount by which the horizontal position is increased when a tab character is encountered.
+        One by default.*/
+    void setTabSize(int size) {
+        jj_input_stream.setTabSize(size);
+    }
+
+    @Override
+    GeneratedJavaParserTokenManager getTokenSource() {
+        return token_source;
+    }
+}
+
+PARSER_END(GeneratedJavaParser)
+
+/* WHITE SPACE */
+
+SPECIAL_TOKEN :
+{
+  <SPACE: [" ", "\t", "\f", "\u0085", "\u00A0", "\u1680", "\u180e", "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005",
+      "\u2006", "\u2007", "\u2008", "\u2009", "\u200a", "\u200b", "\u200c", "\u200d", "\u2028", "\u2029", "\u202f", "\u205f", "\u2060", "\u3000", "\ufeff"]>
+| <WINDOWS_EOL : "\r\n">
+| <UNIX_EOL: "\n">
+| <OLD_MAC_EOL: "\r">
+}
+
+TOKEN_MGR_DECLS :
+{
+    private List<JavaToken> tokens = new ArrayList<JavaToken>();
+    private CommentsCollection commentsCollection = new CommentsCollection();
+    private JavaToken homeToken;
+    private Stack<Token> tokenWorkStack = new Stack<Token>();
+    private boolean storeTokens;
+
+    void reset() {
+        tokens = new ArrayList<JavaToken>();
+        commentsCollection = new CommentsCollection();
+        homeToken = null;
+    }
+
+    List<JavaToken> getTokens() {
+        if(storeTokens) {
+            return tokens;
+        }
+        return null;
+    }
+
+    CommentsCollection getCommentsCollection() {
+        return commentsCollection;
+    }
+
+    /* Get the very first token in the file */
+    JavaToken getHomeToken() {
+        return homeToken;
+    }
+
+    /* Makes the parser keep a list of tokens */
+    public void setStoreTokens(boolean storeTokens) {
+        this.storeTokens = storeTokens;
+    }
+
+    private void CommonTokenAction(Token token) {
+        // Use an intermediary stack to avoid recursion, see issue 1003
+        do {
+            tokenWorkStack.push(token);
+            token = token.specialToken;
+        } while (token != null);
+
+        // The stack is now filled with tokens in left-to-right order. Process them.
+        while(!tokenWorkStack.empty()) {
+            token = tokenWorkStack.pop();
+            token.javaToken = new JavaToken(token, tokens);
+
+            if(storeTokens) {
+                tokens.add(token.javaToken);
+            }
+
+            if (homeToken == null) {
+                homeToken = token.javaToken;
+            }
+
+            if(TokenTypes.isComment(token.kind)) {
+                Comment comment = createCommentFromToken(token);
+                commentsCollection.addComment(comment);
+            }
+        }
+    }
+}
+
+/* COMMENTS */
+
+SPECIAL_TOKEN :
+{
+  <SINGLE_LINE_COMMENT: "//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")? >
+}
+
+MORE :
+{
+  <ENTER_JAVADOC_COMMENT: "/**" ~["/"]> { input_stream.backup(1); } : IN_JAVADOC_COMMENT
+|
+  <ENTER_MULTILINE_COMMENT: "/*"> : IN_MULTI_LINE_COMMENT
+}
+
+<IN_JAVADOC_COMMENT>
+SPECIAL_TOKEN :
+{
+  <JAVADOC_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_MULTI_LINE_COMMENT>
+SPECIAL_TOKEN :
+{
+  <MULTI_LINE_COMMENT: "*/" > : DEFAULT
+}
+
+<IN_JAVADOC_COMMENT, IN_MULTI_LINE_COMMENT>
+MORE :
+{
+  <COMMENT_CONTENT: ~[] >
+}
+
+/* RESERVED WORDS AND LITERALS */
+
+TOKEN :
+{
+  < ABSTRACT: "abstract" >
+| < ASSERT: "assert" >
+| < BOOLEAN: "boolean" >
+| < BREAK: "break" >
+| < BYTE: "byte" >
+| < CASE: "case" >
+| < CATCH: "catch" >
+| < CHAR: "char" >
+| < CLASS: "class" >
+| < CONST: "const" >
+| < CONTINUE: "continue" >
+| < _DEFAULT: "default" >
+| < DO: "do" >
+| < DOUBLE: "double" >
+| < ELSE: "else" >
+| < ENUM: "enum" >
+| < EXTENDS: "extends" >
+| < FALSE: "false" >
+| < FINAL: "final" >
+| < FINALLY: "finally" >
+| < FLOAT: "float" >
+| < FOR: "for" >
+| < GOTO: "goto" >
+| < IF: "if" >
+| < IMPLEMENTS: "implements" >
+| < IMPORT: "import" >
+| < INSTANCEOF: "instanceof" >
+| < INT: "int" >
+| < INTERFACE: "interface" >
+| < LONG: "long" >
+| < NATIVE: "native" >
+| < NEW: "new" >
+| < NULL: "null" >
+| < PACKAGE: "package">
+| < PRIVATE: "private" >
+| < PROTECTED: "protected" >
+| < PUBLIC: "public" >
+| < RETURN: "return" >
+| < SHORT: "short" >
+| < STATIC: "static" >
+| < STRICTFP: "strictfp" >
+| < SUPER: "super" >
+| < SWITCH: "switch" >
+| < SYNCHRONIZED: "synchronized" >
+| < THIS: "this" >
+| < THROW: "throw" >
+| < THROWS: "throws" >
+| < TRANSIENT: "transient" >
+| < TRUE: "true" >
+| < TRY: "try" >
+| < VOID: "void" >
+| < VOLATILE: "volatile" >
+| < WHILE: "while" >
+| < REQUIRES: "requires" >
+| < TO: "to" >
+| < WITH: "with" >
+| < OPEN: "open" >
+| < OPENS: "opens" >
+| < USES: "uses" >
+| < MODULE: "module" >
+| < EXPORTS: "exports" >
+| < PROVIDES: "provides" >
+| < TRANSITIVE: "transitive" >
+}
+
+/* LITERALS */
+
+TOKEN :
+{
+  < LONG_LITERAL:
+        <DECIMAL_LITERAL> (["l","L"])
+      | <HEX_LITERAL> (["l","L"])
+      | <OCTAL_LITERAL> (["l","L"])
+      | <BINARY_LITERAL> (["l","L"])
+  >
+|
+  < INTEGER_LITERAL:
+        <DECIMAL_LITERAL>
+      | <HEX_LITERAL>
+      | <OCTAL_LITERAL>
+      | <BINARY_LITERAL>
+  >
+|
+  < #DECIMAL_LITERAL: ["0"-"9"]((["0"-"9","_"])*["0"-"9"])? >
+|
+  < #HEX_LITERAL: "0" ["x","X"] <HEX_DIGITS> >
+|
+  < #OCTAL_LITERAL: "0" ["0"-"7"]((["0"-"7","_"])*["0"-"7"])? >
+|
+  < #BINARY_LITERAL: "0" ["b","B"] ["0","1"]((["0","1","_"])*["0","1"])? >
+|
+  < FLOATING_POINT_LITERAL:
+        <DECIMAL_FLOATING_POINT_LITERAL>
+      | <HEXADECIMAL_FLOATING_POINT_LITERAL>
+  >
+|
+  < #DECIMAL_FLOATING_POINT_LITERAL:
+        <DECIMAL_LITERAL> "." (<DECIMAL_LITERAL>)? (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | "." <DECIMAL_LITERAL> (<DECIMAL_EXPONENT>)? (["f","F","d","D"])?
+      | <DECIMAL_LITERAL> <DECIMAL_EXPONENT> (["f","F","d","D"])?
+      | <DECIMAL_LITERAL> (<DECIMAL_EXPONENT>)? ["f","F","d","D"]
+  >
+|
+  < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (<DECIMAL_LITERAL>)+ >
+|
+  < #HEXADECIMAL_FLOATING_POINT_LITERAL:
+        <HEX_LITERAL> (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+      | "0" ["x","X"] (<HEX_DIGITS>)? "." <HEX_DIGITS> <HEXADECIMAL_EXPONENT> (["f","F","d","D"])?
+  >
+|
+  < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? <DECIMAL_LITERAL> >
+|
+  < #HEX_DIGITS: ["0"-"9","a"-"f","A"-"F"]((["0"-"9","a"-"f","A"-"F","_"])*["0"-"9","a"-"f","A"-"F"])? >
+|
+  < #UNICODE_ESCAPE:
+    "\\u"
+    ["0"-"9","A"-"F","a"-"f"]
+    ["0"-"9","A"-"F","a"-"f"]
+    ["0"-"9","A"-"F","a"-"f"]
+    ["0"-"9","A"-"F","a"-"f"] >
+|
+  < CHARACTER_LITERAL:
+      "'"
+      (   (~["'","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+        | <UNICODE_ESCAPE>
+      )
+      "'"
+  >
+|
+  < STRING_LITERAL:
+      "\""
+      (   (~["\"","\\","\n","\r"])
+        | ("\\"
+            ( ["n","t","b","r","f","\\","'","\""]
+            | ["0"-"7"] ( ["0"-"7"] )?
+            | ["0"-"3"] ["0"-"7"] ["0"-"7"]
+            )
+          )
+        | ("\\u"
+        	["0"-"9","A"-"F","a"-"f"]
+        	["0"-"9","A"-"F","a"-"f"]
+        	["0"-"9","A"-"F","a"-"f"]
+        	["0"-"9","A"-"F","a"-"f"]
+          )
+      )*
+      "\""
+  >
+}
+
+/* IDENTIFIERS */
+
+TOKEN :
+{
+  < IDENTIFIER: <LETTER> (<PART_LETTER>)* >
+|
+  < #LETTER: [
+         "\u0024",  "\u0041"-"\u005a",  "\u005f",  "\u0061"-"\u007a",  "\u00a2"-"\u00a5",  "\u00aa",  "\u00b5",  
+         "\u00ba",  "\u00c0"-"\u00d6",  "\u00d8"-"\u00f6",  "\u00f8"-"\u02c1",  "\u02c6"-"\u02d1",  "\u02e0"-"\u02e4",  
+         "\u02ec",  "\u02ee",  "\u0370"-"\u0374",  "\u0376"-"\u0377",  "\u037a"-"\u037d",  "\u0386",  "\u0388"-"\u038a",  
+         "\u038c",  "\u038e"-"\u03a1",  "\u03a3"-"\u03f5",  "\u03f7"-"\u0481",  "\u048a"-"\u0527",  "\u0531"-"\u0556",  
+         "\u0559",  "\u0561"-"\u0587",  "\u058f",  "\u05d0"-"\u05ea",  "\u05f0"-"\u05f2",  "\u060b",  "\u0620"-"\u064a",  
+         "\u066e"-"\u066f",  "\u0671"-"\u06d3",  "\u06d5",  "\u06e5"-"\u06e6",  "\u06ee"-"\u06ef",  "\u06fa"-"\u06fc",  
+         "\u06ff",  "\u0710",  "\u0712"-"\u072f",  "\u074d"-"\u07a5",  "\u07b1",  "\u07ca"-"\u07ea",  "\u07f4"-"\u07f5",  
+         "\u07fa",  "\u0800"-"\u0815",  "\u081a",  "\u0824",  "\u0828",  "\u0840"-"\u0858",  "\u08a0",  "\u08a2"-"\u08ac",  
+         "\u0904"-"\u0939",  "\u093d",  "\u0950",  "\u0958"-"\u0961",  "\u0971"-"\u0977",  "\u0979"-"\u097f",  
+         "\u0985"-"\u098c",  "\u098f"-"\u0990",  "\u0993"-"\u09a8",  "\u09aa"-"\u09b0",  "\u09b2",  "\u09b6"-"\u09b9",  
+         "\u09bd",  "\u09ce",  "\u09dc"-"\u09dd",  "\u09df"-"\u09e1",  "\u09f0"-"\u09f3",  "\u09fb",  "\u0a05"-"\u0a0a",  
+         "\u0a0f"-"\u0a10",  "\u0a13"-"\u0a28",  "\u0a2a"-"\u0a30",  "\u0a32"-"\u0a33",  "\u0a35"-"\u0a36",  
+         "\u0a38"-"\u0a39",  "\u0a59"-"\u0a5c",  "\u0a5e",  "\u0a72"-"\u0a74",  "\u0a85"-"\u0a8d",  "\u0a8f"-"\u0a91",  
+         "\u0a93"-"\u0aa8",  "\u0aaa"-"\u0ab0",  "\u0ab2"-"\u0ab3",  "\u0ab5"-"\u0ab9",  "\u0abd",  "\u0ad0",  
+         "\u0ae0"-"\u0ae1",  "\u0af1",  "\u0b05"-"\u0b0c",  "\u0b0f"-"\u0b10",  "\u0b13"-"\u0b28",  "\u0b2a"-"\u0b30",  
+         "\u0b32"-"\u0b33",  "\u0b35"-"\u0b39",  "\u0b3d",  "\u0b5c"-"\u0b5d",  "\u0b5f"-"\u0b61",  "\u0b71",  
+         "\u0b83",  "\u0b85"-"\u0b8a",  "\u0b8e"-"\u0b90",  "\u0b92"-"\u0b95",  "\u0b99"-"\u0b9a",  "\u0b9c",  
+         "\u0b9e"-"\u0b9f",  "\u0ba3"-"\u0ba4",  "\u0ba8"-"\u0baa",  "\u0bae"-"\u0bb9",  "\u0bd0",  "\u0bf9",  
+         "\u0c05"-"\u0c0c",  "\u0c0e"-"\u0c10",  "\u0c12"-"\u0c28",  "\u0c2a"-"\u0c33",  "\u0c35"-"\u0c39",  
+         "\u0c3d",  "\u0c58"-"\u0c59",  "\u0c60"-"\u0c61",  "\u0c85"-"\u0c8c",  "\u0c8e"-"\u0c90",  "\u0c92"-"\u0ca8",  
+         "\u0caa"-"\u0cb3",  "\u0cb5"-"\u0cb9",  "\u0cbd",  "\u0cde",  "\u0ce0"-"\u0ce1",  "\u0cf1"-"\u0cf2",  
+         "\u0d05"-"\u0d0c",  "\u0d0e"-"\u0d10",  "\u0d12"-"\u0d3a",  "\u0d3d",  "\u0d4e",  "\u0d60"-"\u0d61",  
+         "\u0d7a"-"\u0d7f",  "\u0d85"-"\u0d96",  "\u0d9a"-"\u0db1",  "\u0db3"-"\u0dbb",  "\u0dbd",  "\u0dc0"-"\u0dc6",  
+         "\u0e01"-"\u0e30",  "\u0e32"-"\u0e33",  "\u0e3f"-"\u0e46",  "\u0e81"-"\u0e82",  "\u0e84",  "\u0e87"-"\u0e88",  
+         "\u0e8a",  "\u0e8d",  "\u0e94"-"\u0e97",  "\u0e99"-"\u0e9f",  "\u0ea1"-"\u0ea3",  "\u0ea5",  "\u0ea7",  
+         "\u0eaa"-"\u0eab",  "\u0ead"-"\u0eb0",  "\u0eb2"-"\u0eb3",  "\u0ebd",  "\u0ec0"-"\u0ec4",  "\u0ec6",  
+         "\u0edc"-"\u0edf",  "\u0f00",  "\u0f40"-"\u0f47",  "\u0f49"-"\u0f6c",  "\u0f88"-"\u0f8c",  "\u1000"-"\u102a",  
+         "\u103f",  "\u1050"-"\u1055",  "\u105a"-"\u105d",  "\u1061",  "\u1065"-"\u1066",  "\u106e"-"\u1070",  
+         "\u1075"-"\u1081",  "\u108e",  "\u10a0"-"\u10c5",  "\u10c7",  "\u10cd",  "\u10d0"-"\u10fa",  "\u10fc"-"\u1248",  
+         "\u124a"-"\u124d",  "\u1250"-"\u1256",  "\u1258",  "\u125a"-"\u125d",  "\u1260"-"\u1288",  "\u128a"-"\u128d",  
+         "\u1290"-"\u12b0",  "\u12b2"-"\u12b5",  "\u12b8"-"\u12be",  "\u12c0",  "\u12c2"-"\u12c5",  "\u12c8"-"\u12d6",  
+         "\u12d8"-"\u1310",  "\u1312"-"\u1315",  "\u1318"-"\u135a",  "\u1380"-"\u138f",  "\u13a0"-"\u13f4",  
+         "\u1401"-"\u166c",  "\u166f"-"\u167f",  "\u1681"-"\u169a",  "\u16a0"-"\u16ea",  "\u16ee"-"\u16f0",  
+         "\u1700"-"\u170c",  "\u170e"-"\u1711",  "\u1720"-"\u1731",  "\u1740"-"\u1751",  "\u1760"-"\u176c",  
+         "\u176e"-"\u1770",  "\u1780"-"\u17b3",  "\u17d7",  "\u17db"-"\u17dc",  "\u1820"-"\u1877",  "\u1880"-"\u18a8",  
+         "\u18aa",  "\u18b0"-"\u18f5",  "\u1900"-"\u191c",  "\u1950"-"\u196d",  "\u1970"-"\u1974",  "\u1980"-"\u19ab",  
+         "\u19c1"-"\u19c7",  "\u1a00"-"\u1a16",  "\u1a20"-"\u1a54",  "\u1aa7",  "\u1b05"-"\u1b33",  "\u1b45"-"\u1b4b",  
+         "\u1b83"-"\u1ba0",  "\u1bae"-"\u1baf",  "\u1bba"-"\u1be5",  "\u1c00"-"\u1c23",  "\u1c4d"-"\u1c4f",  
+         "\u1c5a"-"\u1c7d",  "\u1ce9"-"\u1cec",  "\u1cee"-"\u1cf1",  "\u1cf5"-"\u1cf6",  "\u1d00"-"\u1dbf",  
+         "\u1e00"-"\u1f15",  "\u1f18"-"\u1f1d",  "\u1f20"-"\u1f45",  "\u1f48"-"\u1f4d",  "\u1f50"-"\u1f57",  
+         "\u1f59",  "\u1f5b",  "\u1f5d",  "\u1f5f"-"\u1f7d",  "\u1f80"-"\u1fb4",  "\u1fb6"-"\u1fbc",  "\u1fbe",  
+         "\u1fc2"-"\u1fc4",  "\u1fc6"-"\u1fcc",  "\u1fd0"-"\u1fd3",  "\u1fd6"-"\u1fdb",  "\u1fe0"-"\u1fec",  
+         "\u1ff2"-"\u1ff4",  "\u1ff6"-"\u1ffc",  "\u203f"-"\u2040",  "\u2054",  "\u2071",  "\u207f",  "\u2090"-"\u209c",  
+         "\u20a0"-"\u20ba",  "\u2102",  "\u2107",  "\u210a"-"\u2113",  "\u2115",  "\u2119"-"\u211d",  "\u2124",  
+         "\u2126",  "\u2128",  "\u212a"-"\u212d",  "\u212f"-"\u2139",  "\u213c"-"\u213f",  "\u2145"-"\u2149",  
+         "\u214e",  "\u2160"-"\u2188",  "\u2c00"-"\u2c2e",  "\u2c30"-"\u2c5e",  "\u2c60"-"\u2ce4",  "\u2ceb"-"\u2cee",  
+         "\u2cf2"-"\u2cf3",  "\u2d00"-"\u2d25",  "\u2d27",  "\u2d2d",  "\u2d30"-"\u2d67",  "\u2d6f",  "\u2d80"-"\u2d96",  
+         "\u2da0"-"\u2da6",  "\u2da8"-"\u2dae",  "\u2db0"-"\u2db6",  "\u2db8"-"\u2dbe",  "\u2dc0"-"\u2dc6",  
+         "\u2dc8"-"\u2dce",  "\u2dd0"-"\u2dd6",  "\u2dd8"-"\u2dde",  "\u2e2f",  "\u3005"-"\u3007",  "\u3021"-"\u3029",  
+         "\u3031"-"\u3035",  "\u3038"-"\u303c",  "\u3041"-"\u3096",  "\u309d"-"\u309f",  "\u30a1"-"\u30fa",  
+         "\u30fc"-"\u30ff",  "\u3105"-"\u312d",  "\u3131"-"\u318e",  "\u31a0"-"\u31ba",  "\u31f0"-"\u31ff",  
+         "\u3400"-"\u4db5",  "\u4e00"-"\u9fcc",  "\ua000"-"\ua48c",  "\ua4d0"-"\ua4fd",  "\ua500"-"\ua60c",  
+         "\ua610"-"\ua61f",  "\ua62a"-"\ua62b",  "\ua640"-"\ua66e",  "\ua67f"-"\ua697",  "\ua6a0"-"\ua6ef",  
+         "\ua717"-"\ua71f",  "\ua722"-"\ua788",  "\ua78b"-"\ua78e",  "\ua790"-"\ua793",  "\ua7a0"-"\ua7aa",  
+         "\ua7f8"-"\ua801",  "\ua803"-"\ua805",  "\ua807"-"\ua80a",  "\ua80c"-"\ua822",  "\ua838",  "\ua840"-"\ua873",  
+         "\ua882"-"\ua8b3",  "\ua8f2"-"\ua8f7",  "\ua8fb",  "\ua90a"-"\ua925",  "\ua930"-"\ua946",  "\ua960"-"\ua97c",  
+         "\ua984"-"\ua9b2",  "\ua9cf",  "\uaa00"-"\uaa28",  "\uaa40"-"\uaa42",  "\uaa44"-"\uaa4b",  "\uaa60"-"\uaa76",  
+         "\uaa7a",  "\uaa80"-"\uaaaf",  "\uaab1",  "\uaab5"-"\uaab6",  "\uaab9"-"\uaabd",  "\uaac0",  "\uaac2",  
+         "\uaadb"-"\uaadd",  "\uaae0"-"\uaaea",  "\uaaf2"-"\uaaf4",  "\uab01"-"\uab06",  "\uab09"-"\uab0e",  
+         "\uab11"-"\uab16",  "\uab20"-"\uab26",  "\uab28"-"\uab2e",  "\uabc0"-"\uabe2",  "\uac00"-"\ud7a3",  
+         "\ud7b0"-"\ud7c6",  "\ud7cb"-"\ud7fb",  "\ud800"-"\udfff",  "\uf900"-"\ufa6d",  "\ufa70"-"\ufad9",  
+         "\ufb00"-"\ufb06",  "\ufb13"-"\ufb17",  "\ufb1d",  "\ufb1f"-"\ufb28",  "\ufb2a"-"\ufb36",  "\ufb38"-"\ufb3c",  
+         "\ufb3e",  "\ufb40"-"\ufb41",  "\ufb43"-"\ufb44",  "\ufb46"-"\ufbb1",  "\ufbd3"-"\ufd3d",  "\ufd50"-"\ufd8f",  
+         "\ufd92"-"\ufdc7",  "\ufdf0"-"\ufdfc",  "\ufe33"-"\ufe34",  "\ufe4d"-"\ufe4f",  "\ufe69",  "\ufe70"-"\ufe74",  
+         "\ufe76"-"\ufefc",  "\uff04",  "\uff21"-"\uff3a",  "\uff3f",  "\uff41"-"\uff5a",  "\uff66"-"\uffbe",  
+         "\uffc2"-"\uffc7",  "\uffca"-"\uffcf",  "\uffd2"-"\uffd7",  "\uffda"-"\uffdc",  "\uffe0"-"\uffe1",  
+         "\uffe5"-"\uffe6"  ]
+        | <UNICODE_ESCAPE>
+  >
+|
+  < #PART_LETTER: [
+         "\u0000"-"\u0008",  "\u000e"-"\u001b",  "\u0024",  "\u0030"-"\u0039",  "\u0041"-"\u005a",  "\u005f",  
+         "\u0061"-"\u007a",  "\u007f"-"\u009f",  "\u00a2"-"\u00a5",  "\u00aa",  "\u00ad",  "\u00b5",  "\u00ba",  
+         "\u00c0"-"\u00d6",  "\u00d8"-"\u00f6",  "\u00f8"-"\u02c1",  "\u02c6"-"\u02d1",  "\u02e0"-"\u02e4",  
+         "\u02ec",  "\u02ee",  "\u0300"-"\u0374",  "\u0376"-"\u0377",  "\u037a"-"\u037d",  "\u0386",  "\u0388"-"\u038a",  
+         "\u038c",  "\u038e"-"\u03a1",  "\u03a3"-"\u03f5",  "\u03f7"-"\u0481",  "\u0483"-"\u0487",  "\u048a"-"\u0527",  
+         "\u0531"-"\u0556",  "\u0559",  "\u0561"-"\u0587",  "\u058f",  "\u0591"-"\u05bd",  "\u05bf",  "\u05c1"-"\u05c2",  
+         "\u05c4"-"\u05c5",  "\u05c7",  "\u05d0"-"\u05ea",  "\u05f0"-"\u05f2",  "\u0600"-"\u0604",  "\u060b",  
+         "\u0610"-"\u061a",  "\u0620"-"\u0669",  "\u066e"-"\u06d3",  "\u06d5"-"\u06dd",  "\u06df"-"\u06e8",  
+         "\u06ea"-"\u06fc",  "\u06ff",  "\u070f"-"\u074a",  "\u074d"-"\u07b1",  "\u07c0"-"\u07f5",  "\u07fa",  
+         "\u0800"-"\u082d",  "\u0840"-"\u085b",  "\u08a0",  "\u08a2"-"\u08ac",  "\u08e4"-"\u08fe",  "\u0900"-"\u0963",  
+         "\u0966"-"\u096f",  "\u0971"-"\u0977",  "\u0979"-"\u097f",  "\u0981"-"\u0983",  "\u0985"-"\u098c",  
+         "\u098f"-"\u0990",  "\u0993"-"\u09a8",  "\u09aa"-"\u09b0",  "\u09b2",  "\u09b6"-"\u09b9",  "\u09bc"-"\u09c4",  
+         "\u09c7"-"\u09c8",  "\u09cb"-"\u09ce",  "\u09d7",  "\u09dc"-"\u09dd",  "\u09df"-"\u09e3",  "\u09e6"-"\u09f3",  
+         "\u09fb",  "\u0a01"-"\u0a03",  "\u0a05"-"\u0a0a",  "\u0a0f"-"\u0a10",  "\u0a13"-"\u0a28",  "\u0a2a"-"\u0a30",  
+         "\u0a32"-"\u0a33",  "\u0a35"-"\u0a36",  "\u0a38"-"\u0a39",  "\u0a3c",  "\u0a3e"-"\u0a42",  "\u0a47"-"\u0a48",  
+         "\u0a4b"-"\u0a4d",  "\u0a51",  "\u0a59"-"\u0a5c",  "\u0a5e",  "\u0a66"-"\u0a75",  "\u0a81"-"\u0a83",  
+         "\u0a85"-"\u0a8d",  "\u0a8f"-"\u0a91",  "\u0a93"-"\u0aa8",  "\u0aaa"-"\u0ab0",  "\u0ab2"-"\u0ab3",  
+         "\u0ab5"-"\u0ab9",  "\u0abc"-"\u0ac5",  "\u0ac7"-"\u0ac9",  "\u0acb"-"\u0acd",  "\u0ad0",  "\u0ae0"-"\u0ae3",  
+         "\u0ae6"-"\u0aef",  "\u0af1",  "\u0b01"-"\u0b03",  "\u0b05"-"\u0b0c",  "\u0b0f"-"\u0b10",  "\u0b13"-"\u0b28",  
+         "\u0b2a"-"\u0b30",  "\u0b32"-"\u0b33",  "\u0b35"-"\u0b39",  "\u0b3c"-"\u0b44",  "\u0b47"-"\u0b48",  
+         "\u0b4b"-"\u0b4d",  "\u0b56"-"\u0b57",  "\u0b5c"-"\u0b5d",  "\u0b5f"-"\u0b63",  "\u0b66"-"\u0b6f",  
+         "\u0b71",  "\u0b82"-"\u0b83",  "\u0b85"-"\u0b8a",  "\u0b8e"-"\u0b90",  "\u0b92"-"\u0b95",  "\u0b99"-"\u0b9a",  
+         "\u0b9c",  "\u0b9e"-"\u0b9f",  "\u0ba3"-"\u0ba4",  "\u0ba8"-"\u0baa",  "\u0bae"-"\u0bb9",  "\u0bbe"-"\u0bc2",  
+         "\u0bc6"-"\u0bc8",  "\u0bca"-"\u0bcd",  "\u0bd0",  "\u0bd7",  "\u0be6"-"\u0bef",  "\u0bf9",  "\u0c01"-"\u0c03",  
+         "\u0c05"-"\u0c0c",  "\u0c0e"-"\u0c10",  "\u0c12"-"\u0c28",  "\u0c2a"-"\u0c33",  "\u0c35"-"\u0c39",  
+         "\u0c3d"-"\u0c44",  "\u0c46"-"\u0c48",  "\u0c4a"-"\u0c4d",  "\u0c55"-"\u0c56",  "\u0c58"-"\u0c59",  
+         "\u0c60"-"\u0c63",  "\u0c66"-"\u0c6f",  "\u0c82"-"\u0c83",  "\u0c85"-"\u0c8c",  "\u0c8e"-"\u0c90",  
+         "\u0c92"-"\u0ca8",  "\u0caa"-"\u0cb3",  "\u0cb5"-"\u0cb9",  "\u0cbc"-"\u0cc4",  "\u0cc6"-"\u0cc8",  
+         "\u0cca"-"\u0ccd",  "\u0cd5"-"\u0cd6",  "\u0cde",  "\u0ce0"-"\u0ce3",  "\u0ce6"-"\u0cef",  "\u0cf1"-"\u0cf2",  
+         "\u0d02"-"\u0d03",  "\u0d05"-"\u0d0c",  "\u0d0e"-"\u0d10",  "\u0d12"-"\u0d3a",  "\u0d3d"-"\u0d44",  
+         "\u0d46"-"\u0d48",  "\u0d4a"-"\u0d4e",  "\u0d57",  "\u0d60"-"\u0d63",  "\u0d66"-"\u0d6f",  "\u0d7a"-"\u0d7f",  
+         "\u0d82"-"\u0d83",  "\u0d85"-"\u0d96",  "\u0d9a"-"\u0db1",  "\u0db3"-"\u0dbb",  "\u0dbd",  "\u0dc0"-"\u0dc6",  
+         "\u0dca",  "\u0dcf"-"\u0dd4",  "\u0dd6",  "\u0dd8"-"\u0ddf",  "\u0df2"-"\u0df3",  "\u0e01"-"\u0e3a",  
+         "\u0e3f"-"\u0e4e",  "\u0e50"-"\u0e59",  "\u0e81"-"\u0e82",  "\u0e84",  "\u0e87"-"\u0e88",  "\u0e8a",  
+         "\u0e8d",  "\u0e94"-"\u0e97",  "\u0e99"-"\u0e9f",  "\u0ea1"-"\u0ea3",  "\u0ea5",  "\u0ea7",  "\u0eaa"-"\u0eab",  
+         "\u0ead"-"\u0eb9",  "\u0ebb"-"\u0ebd",  "\u0ec0"-"\u0ec4",  "\u0ec6",  "\u0ec8"-"\u0ecd",  "\u0ed0"-"\u0ed9",  
+         "\u0edc"-"\u0edf",  "\u0f00",  "\u0f18"-"\u0f19",  "\u0f20"-"\u0f29",  "\u0f35",  "\u0f37",  "\u0f39",  
+         "\u0f3e"-"\u0f47",  "\u0f49"-"\u0f6c",  "\u0f71"-"\u0f84",  "\u0f86"-"\u0f97",  "\u0f99"-"\u0fbc",  
+         "\u0fc6",  "\u1000"-"\u1049",  "\u1050"-"\u109d",  "\u10a0"-"\u10c5",  "\u10c7",  "\u10cd",  "\u10d0"-"\u10fa",  
+         "\u10fc"-"\u1248",  "\u124a"-"\u124d",  "\u1250"-"\u1256",  "\u1258",  "\u125a"-"\u125d",  "\u1260"-"\u1288",  
+         "\u128a"-"\u128d",  "\u1290"-"\u12b0",  "\u12b2"-"\u12b5",  "\u12b8"-"\u12be",  "\u12c0",  "\u12c2"-"\u12c5",  
+         "\u12c8"-"\u12d6",  "\u12d8"-"\u1310",  "\u1312"-"\u1315",  "\u1318"-"\u135a",  "\u135d"-"\u135f",  
+         "\u1380"-"\u138f",  "\u13a0"-"\u13f4",  "\u1401"-"\u166c",  "\u166f"-"\u167f",  "\u1681"-"\u169a",  
+         "\u16a0"-"\u16ea",  "\u16ee"-"\u16f0",  "\u1700"-"\u170c",  "\u170e"-"\u1714",  "\u1720"-"\u1734",  
+         "\u1740"-"\u1753",  "\u1760"-"\u176c",  "\u176e"-"\u1770",  "\u1772"-"\u1773",  "\u1780"-"\u17d3",  
+         "\u17d7",  "\u17db"-"\u17dd",  "\u17e0"-"\u17e9",  "\u180b"-"\u180d",  "\u1810"-"\u1819",  "\u1820"-"\u1877",  
+         "\u1880"-"\u18aa",  "\u18b0"-"\u18f5",  "\u1900"-"\u191c",  "\u1920"-"\u192b",  "\u1930"-"\u193b",  
+         "\u1946"-"\u196d",  "\u1970"-"\u1974",  "\u1980"-"\u19ab",  "\u19b0"-"\u19c9",  "\u19d0"-"\u19d9",  
+         "\u1a00"-"\u1a1b",  "\u1a20"-"\u1a5e",  "\u1a60"-"\u1a7c",  "\u1a7f"-"\u1a89",  "\u1a90"-"\u1a99",  
+         "\u1aa7",  "\u1b00"-"\u1b4b",  "\u1b50"-"\u1b59",  "\u1b6b"-"\u1b73",  "\u1b80"-"\u1bf3",  "\u1c00"-"\u1c37",  
+         "\u1c40"-"\u1c49",  "\u1c4d"-"\u1c7d",  "\u1cd0"-"\u1cd2",  "\u1cd4"-"\u1cf6",  "\u1d00"-"\u1de6",  
+         "\u1dfc"-"\u1f15",  "\u1f18"-"\u1f1d",  "\u1f20"-"\u1f45",  "\u1f48"-"\u1f4d",  "\u1f50"-"\u1f57",  
+         "\u1f59",  "\u1f5b",  "\u1f5d",  "\u1f5f"-"\u1f7d",  "\u1f80"-"\u1fb4",  "\u1fb6"-"\u1fbc",  "\u1fbe",  
+         "\u1fc2"-"\u1fc4",  "\u1fc6"-"\u1fcc",  "\u1fd0"-"\u1fd3",  "\u1fd6"-"\u1fdb",  "\u1fe0"-"\u1fec",  
+         "\u1ff2"-"\u1ff4",  "\u1ff6"-"\u1ffc",  "\u200b"-"\u200f",  "\u202a"-"\u202e",  "\u203f"-"\u2040",  
+         "\u2054",  "\u2060"-"\u2064",  "\u206a"-"\u206f",  "\u2071",  "\u207f",  "\u2090"-"\u209c",  "\u20a0"-"\u20ba",  
+         "\u20d0"-"\u20dc",  "\u20e1",  "\u20e5"-"\u20f0",  "\u2102",  "\u2107",  "\u210a"-"\u2113",  "\u2115",  
+         "\u2119"-"\u211d",  "\u2124",  "\u2126",  "\u2128",  "\u212a"-"\u212d",  "\u212f"-"\u2139",  "\u213c"-"\u213f",  
+         "\u2145"-"\u2149",  "\u214e",  "\u2160"-"\u2188",  "\u2c00"-"\u2c2e",  "\u2c30"-"\u2c5e",  "\u2c60"-"\u2ce4",  
+         "\u2ceb"-"\u2cf3",  "\u2d00"-"\u2d25",  "\u2d27",  "\u2d2d",  "\u2d30"-"\u2d67",  "\u2d6f",  "\u2d7f"-"\u2d96",  
+         "\u2da0"-"\u2da6",  "\u2da8"-"\u2dae",  "\u2db0"-"\u2db6",  "\u2db8"-"\u2dbe",  "\u2dc0"-"\u2dc6",  
+         "\u2dc8"-"\u2dce",  "\u2dd0"-"\u2dd6",  "\u2dd8"-"\u2dde",  "\u2de0"-"\u2dff",  "\u2e2f",  "\u3005"-"\u3007",  
+         "\u3021"-"\u302f",  "\u3031"-"\u3035",  "\u3038"-"\u303c",  "\u3041"-"\u3096",  "\u3099"-"\u309a",  
+         "\u309d"-"\u309f",  "\u30a1"-"\u30fa",  "\u30fc"-"\u30ff",  "\u3105"-"\u312d",  "\u3131"-"\u318e",  
+         "\u31a0"-"\u31ba",  "\u31f0"-"\u31ff",  "\u3400"-"\u4db5",  "\u4e00"-"\u9fcc",  "\ua000"-"\ua48c",  
+         "\ua4d0"-"\ua4fd",  "\ua500"-"\ua60c",  "\ua610"-"\ua62b",  "\ua640"-"\ua66f",  "\ua674"-"\ua67d",  
+         "\ua67f"-"\ua697",  "\ua69f"-"\ua6f1",  "\ua717"-"\ua71f",  "\ua722"-"\ua788",  "\ua78b"-"\ua78e",  
+         "\ua790"-"\ua793",  "\ua7a0"-"\ua7aa",  "\ua7f8"-"\ua827",  "\ua838",  "\ua840"-"\ua873",  "\ua880"-"\ua8c4",  
+         "\ua8d0"-"\ua8d9",  "\ua8e0"-"\ua8f7",  "\ua8fb",  "\ua900"-"\ua92d",  "\ua930"-"\ua953",  "\ua960"-"\ua97c",  
+         "\ua980"-"\ua9c0",  "\ua9cf"-"\ua9d9",  "\uaa00"-"\uaa36",  "\uaa40"-"\uaa4d",  "\uaa50"-"\uaa59",  
+         "\uaa60"-"\uaa76",  "\uaa7a"-"\uaa7b",  "\uaa80"-"\uaac2",  "\uaadb"-"\uaadd",  "\uaae0"-"\uaaef",  
+         "\uaaf2"-"\uaaf6",  "\uab01"-"\uab06",  "\uab09"-"\uab0e",  "\uab11"-"\uab16",  "\uab20"-"\uab26",  
+         "\uab28"-"\uab2e",  "\uabc0"-"\uabea",  "\uabec"-"\uabed",  "\uabf0"-"\uabf9",  "\uac00"-"\ud7a3",  
+         "\ud7b0"-"\ud7c6",  "\ud7cb"-"\ud7fb",  "\ud800"-"\udfff",  "\uf900"-"\ufa6d",  "\ufa70"-"\ufad9",  
+         "\ufb00"-"\ufb06",  "\ufb13"-"\ufb17",  "\ufb1d"-"\ufb28",  "\ufb2a"-"\ufb36",  "\ufb38"-"\ufb3c",  
+         "\ufb3e",  "\ufb40"-"\ufb41",  "\ufb43"-"\ufb44",  "\ufb46"-"\ufbb1",  "\ufbd3"-"\ufd3d",  "\ufd50"-"\ufd8f",  
+         "\ufd92"-"\ufdc7",  "\ufdf0"-"\ufdfc",  "\ufe00"-"\ufe0f",  "\ufe20"-"\ufe26",  "\ufe33"-"\ufe34",  
+         "\ufe4d"-"\ufe4f",  "\ufe69",  "\ufe70"-"\ufe74",  "\ufe76"-"\ufefc",  "\ufeff",  "\uff04",  "\uff10"-"\uff19",  
+         "\uff21"-"\uff3a",  "\uff3f",  "\uff41"-"\uff5a",  "\uff66"-"\uffbe",  "\uffc2"-"\uffc7",  "\uffca"-"\uffcf",  
+         "\uffd2"-"\uffd7",  "\uffda"-"\uffdc",  "\uffe0"-"\uffe1",  "\uffe5"-"\uffe6",  "\ufff9"-"\ufffb" ]
+        | <UNICODE_ESCAPE>
+  >
+}
+
+/* SEPARATORS */
+
+TOKEN :
+{
+  < LPAREN: "(" >
+| < RPAREN: ")" >
+| < LBRACE: "{" >
+| < RBRACE: "}" >
+| < LBRACKET: "[" >
+| < RBRACKET: "]" >
+| < SEMICOLON: ";" >
+| < COMMA: "," >
+| < DOT: "." >
+| < AT: "@" >
+}
+
+/* OPERATORS */
+
+TOKEN :
+{
+  < ASSIGN: "=" >
+| < LT: "<" >
+| < BANG: "!" >
+| < TILDE: "~" >
+| < HOOK: "?" >
+| < COLON: ":" >
+| < EQ: "==" >
+| < LE: "<=" >
+| < GE: ">=" >
+| < NE: "!=" >
+| < SC_OR: "||" >
+| < SC_AND: "&&" >
+| < INCR: "++" >
+| < DECR: "--" >
+| < PLUS: "+" >
+| < MINUS: "-" >
+| < STAR: "*" >
+| < SLASH: "/" >
+| < BIT_AND: "&" >
+| < BIT_OR: "|" >
+| < XOR: "^" >
+| < REM: "%" >
+| < LSHIFT: "<<" >
+| < PLUSASSIGN: "+=" >
+| < MINUSASSIGN: "-=" >
+| < STARASSIGN: "*=" >
+| < SLASHASSIGN: "/=" >
+| < ANDASSIGN: "&=" >
+| < ORASSIGN: "|=" >
+| < XORASSIGN: "^=" >
+| < REMASSIGN: "%=" >
+| < LSHIFTASSIGN: "<<=" >
+| < RSIGNEDSHIFTASSIGN: ">>=" >
+| < RUNSIGNEDSHIFTASSIGN: ">>>=" >
+| < ELLIPSIS: "..." >
+| < ARROW: "->" >
+| < DOUBLECOLON: "::" >
+}
+
+/* >'s need special attention due to generics syntax. */
+TOKEN :
+{
+  < RUNSIGNEDSHIFT: ">>>" >
+  {
+     matchedToken.kind = GT;
+     matchedToken.realKind = RUNSIGNEDSHIFT;
+     input_stream.backup(2);
+  }
+| < RSIGNEDSHIFT: ">>" >
+  {
+     matchedToken.kind = GT;
+     matchedToken.realKind = RSIGNEDSHIFT;
+     input_stream.backup(1);
+  }
+| < GT: ">" >
+}
+
+TOKEN: { <CTRL_Z: "\u001A" /** ctrl+z char **/> }
+
+/*****************************************
+ * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
+ *****************************************/
+
+/*
+ * Program structuring syntax follows.
+ */
+
+CompilationUnit CompilationUnit():
+{
+	PackageDeclaration pakage = null;
+	NodeList<ImportDeclaration> imports = emptyList();
+	ImportDeclaration in = null;
+	NodeList<TypeDeclaration<?>> types = emptyList();
+   ModifierHolder modifier;
+	TypeDeclaration tn = null;
+	ModuleDeclaration module = null;
+}
+{
+    try {
+        ( LOOKAHEAD(2)";" )*
+        [ LOOKAHEAD(PackageDeclaration()) pakage = PackageDeclaration() ]
+        (
+            in = ImportDeclaration() { imports = add(imports, in); } 
+        |
+            (
+                modifier = Modifiers()
+                (
+                    tn = ClassOrInterfaceDeclaration(modifier) { types = add(types, tn); }
+                |
+                    tn = EnumDeclaration(modifier) { types = add(types, tn); }
+                |
+                    tn = AnnotationTypeDeclaration(modifier) { types = add(types, tn); }
+                |
+                    module = ModuleDeclaration(modifier)
+                |
+                    ";"
+                )
+            )
+        )*
+        (<EOF> | <CTRL_Z>)
+        { return new CompilationUnit(range(token_source.getHomeToken(), token()), pakage, imports, types, module); }
+    } catch (ParseException e) {
+        recover(EOF, e);
+        final CompilationUnit compilationUnit = new CompilationUnit(range(token_source.getHomeToken(), token()), null, new NodeList<ImportDeclaration>(), new NodeList<TypeDeclaration<?>>(), null);
+        compilationUnit.setParsed(UNPARSABLE);
+        return compilationUnit;
+    }
+}
+
+PackageDeclaration PackageDeclaration():
+{
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+	Name name;
+	JavaToken begin;
+}
+{
+  annotations = Annotations() 
+  "package" {begin = token();}  name = Name() ";"
+  { return new PackageDeclaration(range(begin, token()), annotations, name); }
+}
+
+
+ImportDeclaration ImportDeclaration():
+{
+    Name name;
+    boolean isStatic = false;
+    boolean isAsterisk = false;
+    JavaToken begin;
+}
+{
+    "import" {begin = token();} 
+    [ "static" { isStatic = true; } ] 
+    name = Name() 
+    [ "." "*" { isAsterisk = true; } ] ";"
+    { return new ImportDeclaration(range(begin, token()), name, isStatic, isAsterisk); }
+}
+
+/*
+ * Modifiers. We match all modifiers in a single rule to reduce the chances of
+ * syntax errors for simple modifier mistakes. It will also enable us to give
+ * better error messages.
+ */
+
+ModifierHolder Modifiers():
+{
+	JavaToken begin = INVALID;
+    EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+    AnnotationExpr ann;
+}
+{
+ (
+  LOOKAHEAD(2)
+  (
+   "public" { addModifier(modifiers, Modifier.PUBLIC); begin = orIfInvalid(begin, token()); }
+  |
+   "static" { addModifier(modifiers, Modifier.STATIC); begin = orIfInvalid(begin, token()); }
+  |
+   "protected" {  addModifier(modifiers, Modifier.PROTECTED); begin = orIfInvalid(begin, token()); }
+  |
+   "private" { addModifier(modifiers, Modifier.PRIVATE); begin = orIfInvalid(begin, token()); }
+  |
+   "final" { addModifier(modifiers, Modifier.FINAL); begin = orIfInvalid(begin, token()); }
+  |
+   "abstract" { addModifier(modifiers, Modifier.ABSTRACT); begin = orIfInvalid(begin, token()); }
+  |
+   "synchronized" { addModifier(modifiers, Modifier.SYNCHRONIZED); begin = orIfInvalid(begin, token()); }
+  |
+   "native" { addModifier(modifiers, Modifier.NATIVE); begin = orIfInvalid(begin, token()); }
+  |
+   "transient" { addModifier(modifiers, Modifier.TRANSIENT); begin = orIfInvalid(begin, token()); }
+  |
+   "volatile" { addModifier(modifiers, Modifier.VOLATILE); begin = orIfInvalid(begin, token()); }
+  |
+   "strictfp" { addModifier(modifiers, Modifier.STRICTFP);  begin = orIfInvalid(begin, token()); }
+  |
+   "transitive" { addModifier(modifiers, Modifier.TRANSITIVE);  begin = orIfInvalid(begin, token()); }
+  |
+   "default" { addModifier(modifiers, Modifier.DEFAULT);  begin = orIfInvalid(begin, token()); }
+  |
+   ann = Annotation() { annotations = add(annotations, ann); begin = orIfInvalid(begin, ann); }
+  )
+ )*
+
+ {
+    return new ModifierHolder(begin, modifiers, annotations);
+ }
+}
+
+/*
+ * Declaration syntax follows.
+ */
+
+ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration(ModifierHolder modifier):
+{
+    boolean isInterface = false;
+    SimpleName name;
+    RangedList<TypeParameter> typePar = new RangedList<TypeParameter>(emptyList());
+    NodeList<ClassOrInterfaceType> extList = emptyList();
+    NodeList<ClassOrInterfaceType> impList = emptyList();
+    NodeList<BodyDeclaration<?>> members = emptyList();
+    JavaToken begin = modifier.begin;
+}
+{
+  ( "class" | "interface" { isInterface = true; } ) { begin = orIfInvalid(begin, token()); }
+  name = SimpleName()
+  [ typePar = TypeParameters() ]
+  [ extList = ExtendsList() ]
+  [ impList = ImplementsList() ]
+  members = ClassOrInterfaceBody()
+
+	{ return new ClassOrInterfaceDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, isInterface, name, typePar.list, extList, impList, members); }
+}
+
+NodeList<ClassOrInterfaceType> ExtendsList():
+{
+   boolean extendsMoreThanOne = false;
+   NodeList<ClassOrInterfaceType> ret = new NodeList<ClassOrInterfaceType>();
+   ClassOrInterfaceType cit;
+}
+{
+   "extends" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
+   ( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); extendsMoreThanOne = true; } )*
+   { return ret; }
+}
+
+NodeList<ClassOrInterfaceType> ImplementsList():
+{
+   NodeList<ClassOrInterfaceType> ret = new NodeList<ClassOrInterfaceType>();
+   ClassOrInterfaceType cit;
+}
+{
+   "implements" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
+   ( "," cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )*
+   { return ret; }
+}
+
+EnumDeclaration EnumDeclaration(ModifierHolder modifier):
+{
+	SimpleName name;
+    NodeList<ClassOrInterfaceType> impList = emptyList();
+	EnumConstantDeclaration entry;
+	NodeList<EnumConstantDeclaration> entries = emptyList();
+	BodyDeclaration<?> member;
+    NodeList<BodyDeclaration<?>> members = emptyList();
+	JavaToken begin = modifier.begin;
+}
+{
+    "enum" { begin = orIfInvalid(begin, token()); }
+    name = SimpleName()
+    [ impList = ImplementsList() ]
+    "{"
+    [
+        entry = EnumConstantDeclaration() { entries.add(entry); } ( LOOKAHEAD(2) "," entry = EnumConstantDeclaration() { entries.add(entry); } )*
+    ]
+    [ "," ]
+    [
+        ";" (
+            member = ClassOrInterfaceBodyDeclaration() { members = add(members, member); } 
+        |
+            ";"
+        )*
+    ]
+    "}"
+    
+    { return new EnumDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, name, impList, entries, members); }
+}
+
+
+EnumConstantDeclaration EnumConstantDeclaration():
+{
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+	AnnotationExpr ann;
+	SimpleName name;
+	NodeList<Expression> args = emptyList();
+	NodeList<BodyDeclaration<?>> classBody = emptyList();
+	JavaToken begin = INVALID;
+}
+{
+  {  }
+  ( ann = Annotation() { annotations = add(annotations, ann); begin = orIfInvalid(begin, ann); } )*
+  name = SimpleName() { begin = orIfInvalid(begin, token()); } 
+  [ args = Arguments() ] [ classBody = ClassOrInterfaceBody() ]
+  { 
+      return new EnumConstantDeclaration(range(begin, token()), annotations, name, args, classBody);  
+  }
+}
+
+/**
+ * If the list inside the returned RangedList is null, there are no brackets.
+ * If it is empty, there are brackets, but nothing is in them <>.
+ * The normal case is that it contains TypeParameters, like <A, B, C>.
+ */
+RangedList<TypeParameter> TypeParameters():
+{
+	RangedList<TypeParameter> ret = new RangedList<TypeParameter>(new NodeList<TypeParameter>());
+	TypeParameter tp;
+	NodeList<AnnotationExpr> annotations;
+}
+{
+   "<" { ret.beginAt(token()); }
+   annotations = Annotations() 
+   tp = TypeParameter(annotations) { ret.add(tp); annotations = null; }
+   ( "," 
+   annotations = Annotations() tp = TypeParameter(annotations) { ret.add(tp); annotations = null; } )*
+   ">" { ret.endAt(token()); }
+   { return ret; }
+}
+
+TypeParameter TypeParameter(NodeList<AnnotationExpr> annotations):
+{
+	SimpleName name;
+	NodeList<ClassOrInterfaceType> typeBound  = emptyList();
+	JavaToken begin;
+}
+{
+   name = SimpleName() { begin=token(); } [ typeBound = TypeBound() ]
+   { return new TypeParameter(range(begin, token()), name, typeBound, annotations); }
+}
+
+NodeList<ClassOrInterfaceType> TypeBound():
+{
+	NodeList<ClassOrInterfaceType> ret = emptyList();
+	ClassOrInterfaceType cit;
+}
+{
+   "extends" cit = AnnotatedClassOrInterfaceType() { ret.add(cit); }
+   ( "&"   cit = AnnotatedClassOrInterfaceType() { ret.add(cit); } )*
+   { return ret; }
+}
+
+NodeList<BodyDeclaration<?>> ClassOrInterfaceBody():
+{
+	NodeList<BodyDeclaration<?>> ret = emptyList();
+	BodyDeclaration member;
+}
+{
+    "{" (
+        member = ClassOrInterfaceBodyDeclaration() { ret.add(member); }
+    |
+        ";"
+    )* "}"
+    { return ret; }
+}
+
+BodyDeclaration<?> ClassOrInterfaceBodyDeclaration():
+{
+   ModifierHolder modifier;
+   BodyDeclaration<?> ret;
+}
+{
+  (
+	  LOOKAHEAD(2)
+	  ret = InitializerDeclaration()
+	|
+      // Just get all the modifiers out of the way. If you want to do
+      // more checks, pass the modifiers down to the member
+	  modifier = Modifiers()
+	  (
+	      ret = ClassOrInterfaceDeclaration(modifier)
+	    | LOOKAHEAD("enum")
+	      ret = EnumDeclaration(modifier)
+	    | LOOKAHEAD("@" "interface")
+	      ret = AnnotationTypeDeclaration(modifier)
+	    | LOOKAHEAD( [ TypeParameters() ] Identifier() "(" )
+	      ret = ConstructorDeclaration(modifier)
+	    | LOOKAHEAD( Type() Identifier() ( ArrayBracketPair() )* ( "," | "=" | ";" ) )
+	      ret = FieldDeclaration(modifier)
+	    |
+	      ret = MethodDeclaration(modifier)
+	  )
+  )
+  { return ret; }
+}
+
+FieldDeclaration FieldDeclaration(ModifierHolder modifier):
+{
+	Type partialType;
+	NodeList<VariableDeclarator> variables = new NodeList<VariableDeclarator>();
+	VariableDeclarator val;
+}
+{
+    // Modifiers are already matched in the caller
+    partialType = Type(emptyList()) val = VariableDeclarator(partialType) { variables.add(val); }
+        ( "," val = VariableDeclarator(partialType) { variables.add(val); } )* ";"
+    {
+        JavaToken begin = orIfInvalid(modifier.begin, partialType);
+        return new FieldDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, variables);
+    }
+}
+
+VariableDeclarator VariableDeclarator(Type partialType):
+{
+	Pair<SimpleName, List<ArrayBracketPair>> id;
+	Expression init = null;
+}
+{
+    id = VariableDeclaratorId() [ "=" init = VariableInitializer() ]
+    { return new VariableDeclarator(range(id.a, token()), juggleArrayType(partialType, id.b), id.a, init); }
+}
+
+Pair<SimpleName, List<ArrayBracketPair>> VariableDeclaratorId():
+{
+	SimpleName name;
+	JavaToken begin;
+	ArrayBracketPair arrayBracketPair;
+	List<ArrayBracketPair> arrayBracketPairs = new ArrayList(0);
+}
+{
+    name = SimpleName() { begin=token();}  ( arrayBracketPair = ArrayBracketPair(Origin.NAME) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )*
+    {
+        if(storeTokens) {
+            name.setTokenRange(name.getTokenRange().get().withEnd(token()));
+        }    
+        return new Pair(name, arrayBracketPairs);
+    }
+}
+
+Expression VariableInitializer():
+{
+	Expression ret;
+}
+{
+  (
+	  ret = ArrayInitializer()
+	|
+	  ret = Expression()
+  )
+  { return ret;}
+}
+
+ArrayInitializerExpr ArrayInitializer():
+{
+	NodeList<Expression> values = emptyList();
+	Expression val;
+	JavaToken begin;
+}
+{
+  "{" {begin=token();} [ val = VariableInitializer() { values = add(values, val); } ( LOOKAHEAD(2) "," val = VariableInitializer() { values = add(values, val); } )* ] [ "," ] "}"
+  { return new ArrayInitializerExpr(range(begin, token()), values); }
+}
+
+MethodDeclaration MethodDeclaration(ModifierHolder modifier):
+{
+	RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(emptyList());
+	Type type;
+	SimpleName name;
+	Pair<NodeList<Parameter>, ReceiverParameter> parameters = new Pair<NodeList<Parameter>, ReceiverParameter>(emptyList(), null);
+	ArrayBracketPair arrayBracketPair;
+	List<ArrayBracketPair> arrayBracketPairs = new ArrayList(0);
+	NodeList<ReferenceType> throws_ = emptyList();
+	BlockStmt body = null;
+	NodeList<AnnotationExpr> annotations;
+	JavaToken begin = modifier.begin;
+	ReferenceType throwType;
+}
+{
+    // Modifiers already matched in the caller!
+    [ typeParameters = TypeParameters() { begin = orIfInvalid(begin, typeParameters.range.getBegin()); } ]
+    annotations = Annotations() { modifier.annotations.addAll(annotations); begin = orIfInvalid(begin, nodeListBegin(annotations)); }
+    type = ResultType(emptyList()) { begin = orIfInvalid(begin, type); }
+    name = SimpleName() parameters = Parameters() ( arrayBracketPair = ArrayBracketPair(Origin.NAME) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )*
+    [ "throws" throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); }
+      ("," throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); } )* ]
+    ( body = Block() | ";" )
+    { 
+        type = juggleArrayType(type, arrayBracketPairs);
+        return new MethodDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, typeParameters.list, type, name, parameters.a, throws_, body, parameters.b);
+    }
+}
+
+ReferenceType AnnotatedReferenceType():
+{
+	NodeList<AnnotationExpr> annotations;
+	ReferenceType type;
+}
+{
+    annotations = Annotations() 
+    type = ReferenceType(annotations)
+    { return type; }
+}
+
+Type AnnotatedType():
+{
+	NodeList<AnnotationExpr> annotations;
+	Type type;
+}
+{
+    annotations = Annotations() 
+    type = Type(annotations)
+    { return type; }
+}
+
+Pair<NodeList<Parameter>, ReceiverParameter> Parameters():
+{
+	NodeList<Parameter> ret = emptyList();
+	Parameter par;
+	ReceiverParameter rp = null;
+}
+{
+    "("
+    [ 
+        ( LOOKAHEAD(ReceiverParameter())
+            rp = ReceiverParameter()
+            |
+            par = Parameter() { ret = add(ret, par); }
+        ) 
+        ( "," par = Parameter() { ret = add(ret, par); } )* 
+    ]
+    ")"
+    { return new Pair(ret, rp); }
+}
+
+NodeList<Parameter> LambdaParameters():
+{
+  NodeList<Parameter> ret = null;
+  Parameter par;
+}
+{
+    par = Parameter() { ret = add(ret, par); } ( "," par = Parameter() { ret = add(ret, par); } )*
+    { return ret;  }
+}
+
+NodeList<Parameter> InferredLambdaParameters():
+{
+    NodeList<Parameter> ret = null;
+    Pair<SimpleName, List<ArrayBracketPair>> id;
+}
+{
+    id = VariableDeclaratorId() 	{ ret = add(ret, new Parameter(range(id.a, id.a), EnumSet.noneOf(Modifier.class), emptyList(), new UnknownType(), false, emptyList(), id.a));}
+    (
+        "," id = VariableDeclaratorId()  { ret = add(ret, new Parameter(range(id.a, id.a), EnumSet.noneOf(Modifier.class), emptyList(), new UnknownType(), false, emptyList(), id.a)); }
+    )*
+    { return ret;  }
+}
+
+Parameter Parameter():
+{
+	ModifierHolder modifier;
+	Type partialType;
+	boolean isVarArg = false;
+	Pair<SimpleName, List<ArrayBracketPair>> id;
+	NodeList<AnnotationExpr> varArgAnnotations = emptyList();
+}
+{
+    modifier = Modifiers() partialType = Type(emptyList()) [ varArgAnnotations = Annotations() "..." { isVarArg = true;} ] 
+    id = VariableDeclaratorId()
+    {
+        JavaToken begin = orIfInvalid(modifier.begin, partialType);
+        return new Parameter(range(begin, token()), modifier.modifiers, modifier.annotations, juggleArrayType(partialType, id.b), isVarArg, varArgAnnotations, id.a);
+    }
+}
+
+ReceiverParameter ReceiverParameter():
+{
+	Type partialType;
+	Name id;
+	NodeList<AnnotationExpr> annotations = emptyList();
+}
+{
+    annotations = Annotations()
+    partialType = Type(emptyList()) 
+    id = ReceiverParameterId()
+    {
+        return new ReceiverParameter(range(partialType, token()), annotations, partialType, id);
+    }
+}
+
+Name ReceiverParameterId():
+{
+	Name ret = null;
+	NodeList<AnnotationExpr> annotations;
+}
+{
+    [ LOOKAHEAD(Name()) ret = Name() "."] annotations=Annotations() "this" 
+    { return new Name(tokenRange(), ret, token.image, annotations); }
+}
+
+ConstructorDeclaration ConstructorDeclaration(ModifierHolder modifier):
+{
+	RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(emptyList());
+	SimpleName name;
+	Pair<NodeList<Parameter>, ReceiverParameter> parameters = new Pair<NodeList<Parameter>, ReceiverParameter>(emptyList(), null);
+	NodeList<ReferenceType> throws_ = emptyList();
+	ExplicitConstructorInvocationStmt exConsInv = null;
+	NodeList<Statement> stmts = emptyList();
+    JavaToken begin = modifier.begin;
+	JavaToken blockBegin = INVALID;
+	ReferenceType throwType;
+}
+{
+  [ typeParameters = TypeParameters() { begin = orIfInvalid(begin, typeParameters.range.getBegin()); } ]
+  // Modifiers matched in the caller
+  name = SimpleName() { begin = orIfInvalid(begin, typeParameters.range.getBegin()); begin = orIfInvalid(begin, token()); } parameters = Parameters() [ "throws" throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); }
+  ("," throwType = AnnotatedReferenceType() { throws_ = add(throws_, throwType); })* ]
+  "{" { blockBegin=token(); }
+    [ LOOKAHEAD(ExplicitConstructorInvocation()) exConsInv = ExplicitConstructorInvocation() ]
+    stmts = Statements()
+  "}"
+
+  {
+  	if (exConsInv != null) {
+  		stmts = prepend(stmts, exConsInv);
+  	}
+  	return new ConstructorDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, typeParameters.list, name, parameters.a, throws_, new BlockStmt(range(blockBegin, token()), stmts), parameters.b);
+  }
+}
+
+ExplicitConstructorInvocationStmt ExplicitConstructorInvocation():
+{
+	boolean isThis = false;
+	NodeList<Expression> args;
+	Expression expr = null;
+	RangedList<Type> typeArgs = new RangedList<Type>(null);
+	JavaToken begin = INVALID;
+}
+{
+  (
+	  LOOKAHEAD([ TypeArguments() ] <THIS> "(")
+	  [ typeArgs = TypeArguments() { begin=typeArgs.range.getBegin(); } ]
+	  <THIS> { begin = orIfInvalid(begin, token()); isThis = true; }
+	  args = Arguments() ";"
+	|
+	  [
+	    LOOKAHEAD( PrimaryExpressionWithoutSuperSuffix() "." )
+	  	expr = PrimaryExpressionWithoutSuperSuffix() "."
+	  	{ begin = orIfInvalid(begin, expr); }
+	  ]
+	  [ typeArgs = TypeArguments() { begin = orIfInvalid(begin, typeArgs.range.getBegin()); } ]
+	  <SUPER> {begin = orIfInvalid(begin, token());}
+	  args = Arguments() ";"
+  )
+  { return new ExplicitConstructorInvocationStmt(range(begin, token()),typeArgs.list, isThis, expr, args); }
+}
+
+NodeList<Statement> Statements():
+{
+	NodeList<Statement> ret = emptyList();
+	Statement stmt;
+}
+{
+	( LOOKAHEAD(2) stmt = BlockStatement() { ret = add(ret, stmt); } )*
+	{ return ret; }
+}
+
+InitializerDeclaration InitializerDeclaration():
+{
+	BlockStmt body;
+	JavaToken begin = INVALID;
+	boolean isStatic = false;
+}
+{
+  [ "static" { isStatic = true; begin=token();} ] 
+  body = Block() {begin = orIfInvalid(begin, body);}
+  { return new InitializerDeclaration(range(begin, token()), isStatic, body); }
+}
+
+
+/*
+ * Type, name and expression syntax follows.
+ */
+
+Type Type(NodeList<AnnotationExpr> annotations):
+{
+	Type ret;
+}
+{
+ (
+   LOOKAHEAD(2) ret = ReferenceType(annotations)
+ |
+   ret = PrimitiveType(annotations )
+ )
+ { return ret; }
+}
+
+ReferenceType ReferenceType(NodeList<AnnotationExpr> annotations):
+{
+	Type type;
+	ArrayBracketPair arrayBracketPair;
+	List<ArrayBracketPair> arrayBracketPairs = new ArrayList(0);
+}
+{
+  (
+   type = PrimitiveType(annotations) ( LOOKAHEAD(Annotations() "[") arrayBracketPair = ArrayBracketPair(Origin.TYPE) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )+
+  |
+   type = ClassOrInterfaceType(annotations)  ( LOOKAHEAD(Annotations() "[") arrayBracketPair = ArrayBracketPair(Origin.TYPE) { arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair); } )*
+  )
+  { return (ReferenceType)wrapInArrayTypes(type, arrayBracketPairs); }
+}
+
+ArrayBracketPair ArrayBracketPair(Origin origin):
+{
+	NodeList<AnnotationExpr> annotations;
+    JavaToken begin = INVALID;
+}
+{
+    annotations = Annotations()
+    "[" { begin = orIfInvalid(begin, token()); } "]"
+    { return new ArrayBracketPair(range(begin, token()), origin, annotations); }
+}
+
+IntersectionType IntersectionType(NodeList<AnnotationExpr> annotations):
+{
+	JavaToken begin = INVALID;
+	ReferenceType elementType;
+	NodeList<ReferenceType> elements = emptyList();
+}
+{
+    elementType = ReferenceType(annotations) { begin = orIfInvalid(begin, elementType); elements = add(elements, elementType); }
+    "&" (elementType = AnnotatedReferenceType() { elements = add(elements, elementType); } )+
+    { return new IntersectionType(range(begin, token()), elements); }
+}
+
+ClassOrInterfaceType AnnotatedClassOrInterfaceType():
+{
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+	ClassOrInterfaceType cit;
+}
+{
+    annotations = Annotations()
+    cit = ClassOrInterfaceType(annotations)
+    { return cit; }
+}
+
+ClassOrInterfaceType ClassOrInterfaceType(NodeList<AnnotationExpr> firstAnnotations):
+{
+	ClassOrInterfaceType ret;
+	SimpleName name;
+	RangedList<Type> typeArgs = new RangedList<Type>(null);
+	JavaToken begin;
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+  name = SimpleName() {begin=token();}
+  [ LOOKAHEAD(2) typeArgs = TypeArguments() ]
+  {
+      ret = new ClassOrInterfaceType(range(begin, token()), null, name, typeArgs.list, firstAnnotations);
+      typeArgs = new RangedList<Type>(null);
+  }
+  (
+	  LOOKAHEAD(2) "." annotations = Annotations()  name = SimpleName()
+	  [ LOOKAHEAD(2) typeArgs = TypeArguments() ]
+	  {
+	    ret = new ClassOrInterfaceType(range(begin, token()), ret, name, typeArgs.list, annotations);
+        typeArgs = new RangedList<Type>(null);
+      }
+  )*
+  { return ret; }
+}
+
+RangedList<Type> TypeArguments():
+{
+	RangedList<Type> ret = new RangedList<Type>(new NodeList<Type>());
+	Type type;
+}
+{
+   (
+     "<" { ret.beginAt(token()); }
+     (type = TypeArgument() { ret.add(type); } ( "," type = TypeArgument() { ret.add(type); } )*)?
+     ">" { ret.endAt(token()); }
+   )
+   { return ret; }
+}
+
+Type TypeArgument():
+{
+	Type ret;
+	NodeList<AnnotationExpr> annotations;
+}
+{
+ annotations = Annotations() 
+ (
+   ret = Type(annotations)
+ |
+   ret = Wildcard(annotations)
+ )
+ { return ret; }
+}
+
+WildcardType Wildcard(NodeList<AnnotationExpr> firstAnnotations):
+{
+	ReferenceType ext = null;
+	ReferenceType sup = null;
+	JavaToken begin;
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+   "?" {begin=token();}
+   [
+		"extends" annotations = Annotations() ext = ReferenceType(annotations)
+	|
+		"super" annotations = Annotations() sup = ReferenceType(annotations)
+   ]
+   { 
+     return new WildcardType(range(begin, token()), ext, sup, firstAnnotations);
+   }
+}
+
+PrimitiveType PrimitiveType(NodeList<AnnotationExpr> annotations):
+{
+	PrimitiveType ret;
+}
+{
+(
+  "boolean" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.BOOLEAN, annotations); }
+|
+  "char" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.CHAR, annotations); }
+|
+  "byte" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.BYTE, annotations); }
+|
+  "short" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.SHORT, annotations); }
+|
+  "int" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.INT, annotations); }
+|
+  "long" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.LONG, annotations); }
+|
+  "float" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.FLOAT, annotations); }
+|
+  "double" { ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.DOUBLE, annotations); }
+)
+{ return ret; }
+}
+
+Type ResultType(NodeList<AnnotationExpr> annotations):
+{
+	Type ret;
+}
+{
+  (
+	  "void" { ret = new VoidType(tokenRange()); }
+	|
+	  ret = Type(annotations)
+  )
+  { return ret; }
+}
+
+Name Name():
+/*
+ * A lookahead is required below since "Name" can be followed
+ * by a ".*" when used in the context of an "ImportDeclaration".
+ */
+{
+	Name ret;
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+  annotations=Annotations() Identifier() { ret = new Name(tokenRange(), null, token.image, annotations); }
+  ( LOOKAHEAD("." Annotations() Identifier()) 
+  "." annotations=Annotations() Identifier() { ret = new Name(range(ret, token()), ret, token.image, annotations); } )*
+  { return ret; }
+}
+
+SimpleName SimpleName():
+{
+    SimpleName ret;
+}
+{
+  Identifier() { ret = new SimpleName(tokenRange(), token.image); }
+  { return ret; }
+}
+
+
+String Identifier():
+{
+    String ret;
+}
+{
+    // Make sure the module info keywords don't interfere with normal Java parsing by matching them as normal identifiers.
+    (<MODULE> | <REQUIRES> | <TO> | <WITH> | <OPEN> | <OPENS> | <USES> | <EXPORTS> | <PROVIDES> | <TRANSITIVE> |
+    // Make sure older Java versions parse
+    <ENUM> | <STRICTFP> |
+    // An actual plain old identifier
+    <IDENTIFIER>) { ret = token.image; setTokenKind(IDENTIFIER);}
+    { return ret; }
+}
+
+/*
+ * Expression syntax follows.
+ */
+
+Expression Expression():
+/*
+ * This expansion has been written this way instead of:
+ *   Assignment() | ConditionalExpression()
+ * for performance reasons.
+ * However, it is a weakening of the grammar for it allows the LHS of
+ * assignments to be any conditional expression whereas it can only be
+ * a primary expression. This is caught by a validation after parsing.
+ */
+{
+	Expression ret;
+	AssignExpr.Operator op;
+	Expression value;
+	Statement lambdaBody = null;
+	RangedList<Type> typeArgs = new RangedList<Type>(null);
+}
+{
+    ret = ConditionalExpression()
+    [
+        ( LOOKAHEAD(2)
+            op = AssignmentOperator() value = Expression() { ret = new AssignExpr(range(ret, token()), ret, value, op); }
+        |
+            "->" lambdaBody = LambdaBody()
+            {
+                if (ret instanceof CastExpr) {
+                    ret = generateLambda(ret, lambdaBody);
+                } else if (ret instanceof ConditionalExpr) {
+                    ConditionalExpr ce = (ConditionalExpr) ret;
+                    if(ce.getElseExpr() != null) {
+                        ce.setElseExpr(generateLambda(ce.getElseExpr(), lambdaBody));
+                    }
+                } else {
+                    ret = generateLambda(ret, lambdaBody);
+                }
+            }
+        |
+            "::"  [typeArgs = TypeArguments() ] (Identifier() | "new") { ret = new MethodReferenceExpr(range(ret, token()), ret, typeArgs.list, token.image); }
+        )
+    ]
+    
+    { return ret; }
+}
+
+AssignExpr.Operator AssignmentOperator():
+{
+	AssignExpr.Operator ret;
+}
+{
+  (
+      "="    { ret = AssignExpr.Operator.ASSIGN; }
+    | "*="   { ret = AssignExpr.Operator.MULTIPLY; }
+    | "/="   { ret = AssignExpr.Operator.DIVIDE; }
+    | "%="   { ret = AssignExpr.Operator.REMAINDER; }
+    | "+="   { ret = AssignExpr.Operator.PLUS; }
+    | "-="   { ret = AssignExpr.Operator.MINUS; }
+    | "<<="  { ret = AssignExpr.Operator.LEFT_SHIFT; }
+    | ">>="  { ret = AssignExpr.Operator.SIGNED_RIGHT_SHIFT; }
+    | ">>>=" { ret = AssignExpr.Operator.UNSIGNED_RIGHT_SHIFT; }
+    | "&="   { ret = AssignExpr.Operator.BINARY_AND; }
+    | "^="   { ret = AssignExpr.Operator.XOR; }
+    | "|="   { ret = AssignExpr.Operator.BINARY_OR; }
+  )
+  { return ret; }
+}
+
+Expression ConditionalExpression():
+{
+	Expression ret;
+	Expression left;
+	Expression right;
+}
+{
+  ret = ConditionalOrExpression()
+  [ "?" left = Expression() ":" right = ConditionalExpression() { ret = new ConditionalExpr(range(ret, token()), ret, left, right); } ]
+  { return ret; }
+}
+
+Expression ConditionalOrExpression():
+{
+	Expression ret;
+	Expression right;
+}
+{
+  ret = ConditionalAndExpression() ( "||" right = ConditionalAndExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.OR); } )*
+  { return ret; }
+}
+
+Expression ConditionalAndExpression():
+{
+	Expression ret;
+	Expression right;
+}
+{
+  ret = InclusiveOrExpression() ( "&&" right = InclusiveOrExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.AND); } )*
+  { return ret; }
+}
+
+Expression InclusiveOrExpression():
+{
+	Expression ret;
+	Expression right;
+}
+{
+  ret = ExclusiveOrExpression() ( "|" right = ExclusiveOrExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.BINARY_OR); } )*
+  { return ret; }
+}
+
+Expression ExclusiveOrExpression():
+{
+	Expression ret;
+	Expression right;
+}
+{
+  ret = AndExpression() ( "^" right = AndExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.XOR); } )*
+  { return ret; }
+}
+
+Expression AndExpression():
+{
+	Expression ret;
+	Expression right;
+}
+{
+  ret = EqualityExpression() ( "&" right = EqualityExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, BinaryExpr.Operator.BINARY_AND); } )*
+  { return ret; }
+}
+
+Expression EqualityExpression():
+{
+	Expression ret;
+	Expression right;
+	BinaryExpr.Operator op;
+}
+{
+  ret = InstanceOfExpression()
+  (
+    ( "==" { op = BinaryExpr.Operator.EQUALS; } |
+      "!=" { op = BinaryExpr.Operator.NOT_EQUALS; }
+    ) right = InstanceOfExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+  )*
+  { return ret; }
+}
+
+Expression InstanceOfExpression():
+{
+	Expression ret;
+	ReferenceType type;
+	NodeList<AnnotationExpr> annotations;
+}
+{
+    ret = RelationalExpression() [ "instanceof" type = AnnotatedReferenceType() {
+        ret = new InstanceOfExpr(range(ret, token()), ret, type); 
+    } ]
+    { return ret; }
+}
+
+Expression RelationalExpression():
+{
+	Expression ret;
+	Expression right;
+	BinaryExpr.Operator op;
+}
+{
+  ret = ShiftExpression()
+  (
+  	( "<"  { op = BinaryExpr.Operator.LESS; } |
+  	  ">"  { op = BinaryExpr.Operator.GREATER; } |
+  	  "<=" { op = BinaryExpr.Operator.LESS_EQUALS; } |
+  	  ">=" { op = BinaryExpr.Operator.GREATER_EQUALS; }
+  	) right = ShiftExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+  )*
+  { return ret; }
+}
+
+Expression ShiftExpression():
+{
+	Expression ret;
+	Expression right;
+	BinaryExpr.Operator op;
+}
+{
+  ret = AdditiveExpression()
+  (
+  	( "<<"             { op = BinaryExpr.Operator.LEFT_SHIFT; } |
+  	  RSIGNEDSHIFT()   { op = BinaryExpr.Operator.SIGNED_RIGHT_SHIFT; } |
+  	  RUNSIGNEDSHIFT() { op = BinaryExpr.Operator.UNSIGNED_RIGHT_SHIFT; }
+  	) right = AdditiveExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+  )*
+  { return ret; }
+}
+
+Expression AdditiveExpression():
+{
+	Expression ret;
+	Expression right;
+	BinaryExpr.Operator op;
+}
+{
+  ret = MultiplicativeExpression()
+  (
+  	( "+" { op = BinaryExpr.Operator.PLUS; } |
+  	  "-" { op = BinaryExpr.Operator.MINUS; }
+  	) right = MultiplicativeExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+  )*
+  { return ret; }
+}
+
+Expression MultiplicativeExpression():
+{
+	Expression ret;
+	Expression right;
+	BinaryExpr.Operator op;
+}
+{
+  ret = UnaryExpression()
+  (
+  	( "*" { op = BinaryExpr.Operator.MULTIPLY; } |
+  	  "/" { op = BinaryExpr.Operator.DIVIDE; } |
+  	  "%" { op = BinaryExpr.Operator.REMAINDER; }
+  	) right = UnaryExpression() { ret = new BinaryExpr(range(ret, token()), ret, right, op); }
+  )*
+  { return ret; }
+}
+
+Expression UnaryExpression():
+{
+	Expression ret;
+	UnaryExpr.Operator op;
+	JavaToken begin = INVALID;
+}
+{
+  (
+	  ret = PreIncrementExpression()
+	|
+	  ret = PreDecrementExpression()
+	|
+	  ( "+" { op = UnaryExpr.Operator.PLUS; begin=token();} |
+	    "-" { op = UnaryExpr.Operator.MINUS; begin=token();}
+	  ) ret = UnaryExpression()
+	  {
+        ret = new UnaryExpr(range(begin, token()), ret, op);
+	  }
+	|
+	  ret = UnaryExpressionNotPlusMinus()
+  )
+  { return ret; }
+}
+
+Expression PreIncrementExpression():
+{
+	Expression ret;
+	JavaToken begin = INVALID;
+}
+{
+  "++" {begin=token();} ret = UnaryExpression() { ret = new UnaryExpr(range(begin, token()), ret, UnaryExpr.Operator.PREFIX_INCREMENT); }
+  { return ret; }
+}
+
+Expression PreDecrementExpression():
+{
+	Expression ret;
+	JavaToken begin;
+}
+{
+  "--" {begin=token();} ret = UnaryExpression() { ret = new UnaryExpr(range(begin, token()), ret, UnaryExpr.Operator.PREFIX_DECREMENT); }
+  { return ret; }
+}
+
+Expression UnaryExpressionNotPlusMinus():
+{
+	Expression ret;
+	UnaryExpr.Operator op;
+	JavaToken begin = INVALID;
+}
+{
+  (
+	  ( "~" { op = UnaryExpr.Operator.BITWISE_COMPLEMENT; begin=token(); } |
+	    "!" { op = UnaryExpr.Operator.LOGICAL_COMPLEMENT;     begin=token(); }
+	  ) ret = UnaryExpression() { ret = new UnaryExpr(range(begin, token()), ret, op); }
+	|
+	  LOOKAHEAD( CastExpression() )
+	  ret = CastExpression()
+	|
+      ret = PostfixExpression()
+  )
+  { return ret; }
+}
+
+Expression PostfixExpression():
+{
+	Expression ret;
+	UnaryExpr.Operator op;
+}
+{
+  ret = PrimaryExpression()
+  [
+  	LOOKAHEAD(2)
+    ( "++" { op = UnaryExpr.Operator.POSTFIX_INCREMENT; } |
+      "--" { op = UnaryExpr.Operator.POSTFIX_DECREMENT; }
+    ) { ret = new UnaryExpr(range(ret, token()), ret, op); }
+  ]
+  { return ret; }
+}
+
+Expression CastExpression():
+{
+	Expression ret;
+	ReferenceType referenceType;
+	PrimitiveType primitiveType;
+	JavaToken begin = INVALID;
+	NodeList<AnnotationExpr> annotations;
+	NodeList<ReferenceType> typesOfMultiCast = emptyList();
+}
+{
+  "(" {begin=token();}
+  annotations = Annotations() 
+  (
+  	  LOOKAHEAD(2)
+  	  primitiveType = PrimitiveType(annotations) ")" ret = UnaryExpression() { ret = new CastExpr(range(begin, token()), primitiveType, ret); }
+  	|
+  	  referenceType = ReferenceType(annotations) { typesOfMultiCast = add(typesOfMultiCast, referenceType); }
+  	  ( "&" referenceType = AnnotatedReferenceType() {
+  	    typesOfMultiCast = add(typesOfMultiCast, referenceType);
+  	    }
+  	  )*
+  	  ")" ret = UnaryExpressionNotPlusMinus() {
+  	    if (typesOfMultiCast.size() > 1) {
+  	        ret = new CastExpr(range(begin, token()), new IntersectionType(range(typesOfMultiCast.get(0), typesOfMultiCast.get(typesOfMultiCast.size() -1)), typesOfMultiCast), ret);
+  	    } else {
+  	        ret = new CastExpr(range(begin, token()), referenceType, ret);
+  	    }
+  	  }
+ )
+  { return ret; }
+}
+
+
+
+Expression PrimaryExpression():
+{
+	Expression ret;
+}
+{
+  ret = PrimaryPrefix() ( LOOKAHEAD(2) ret = PrimarySuffix(ret) )*
+  { return ret; }
+}
+
+Expression PrimaryExpressionWithoutSuperSuffix():
+{
+	Expression ret;
+}
+{
+  ret = PrimaryPrefix() ( LOOKAHEAD( PrimarySuffixWithoutSuper(null) ) ret = PrimarySuffixWithoutSuper(ret) )*
+  { return ret; }
+}
+
+Expression PrimaryPrefix():
+{
+	Expression ret = null;
+	SimpleName name;
+	RangedList<Type> typeArgs = new RangedList<Type>(null);
+	NodeList<Expression> args = emptyList();
+	NodeList<Parameter> params = emptyList();
+	boolean hasArgs = false;
+	boolean isLambda = false;
+	Type type;
+	JavaToken begin;
+	Parameter p = null;
+	SimpleName id = null;
+}
+{
+  (
+	  ret = Literal()
+	|
+	  <THIS> { ret = new ThisExpr(tokenRange(), null); }
+	|
+	  <SUPER> { ret = new SuperExpr(tokenRange(), null); }
+	  (
+	     "."
+	  [ typeArgs = TypeArguments() ]
+	  name = SimpleName()
+	  [ args = Arguments() {hasArgs=true;} ]
+	  	{
+			if (hasArgs) {
+	  			ret = new MethodCallExpr(range(ret, token()), ret, typeArgs.list, name, args);
+			} else {
+	  			ret = new FieldAccessExpr(range(ret, token()), ret, emptyList(), name);
+			}
+	  	}
+	 |
+		"::" [typeArgs = TypeArguments() ] (Identifier() | "new")
+		{
+		  ret = new MethodReferenceExpr(range(ret, token()), ret, typeArgs.list, token.image);
+		}
+	  )
+	|
+        "(" {begin=token();}
+        (
+            ")" { ret = new LambdaExpr(range(begin, token()), params, new BlockStmt(), true); }
+        | LOOKAHEAD(Parameter())
+            params = LambdaParameters() ")" { ret = new LambdaExpr(range(begin, token()), params, new BlockStmt(), true); }
+        | LOOKAHEAD(VariableDeclaratorId() ",")
+            params = InferredLambdaParameters() ")" { ret = new LambdaExpr(range(begin, token()), params, new BlockStmt(), true); }
+        |
+            // This could still be a lambda expression, but this is handled after matching -> elsewhere
+            ret = Expression() ")" { ret = new EnclosedExpr(range(begin, token()), ret); }
+        )
+	|
+	  ret = AllocationExpression(null)
+	|
+	  LOOKAHEAD( ResultType() "." "class" )
+	  type = ResultType(emptyList())  "." "class" { ret = new ClassExpr(range(type, token()), type); }
+
+	| LOOKAHEAD (AnnotatedType() "::" )
+	  type = AnnotatedType() "::" [typeArgs = TypeArguments() ] (Identifier() | "new")
+		{
+		  ret = new TypeExpr(range(type, type), type);
+		  ret = new MethodReferenceExpr(range(ret, token()), ret, typeArgs.list, token.image);
+		}
+
+	|
+	  	name = SimpleName() { begin=token(); }
+	  	[ args = Arguments() { hasArgs=true; } ]
+	  	{
+	  		if (hasArgs) {
+	  			ret = new MethodCallExpr(range(begin, token()), null, null, name, args);
+			} else {
+	  			ret = new NameExpr(name);
+			}
+	  	}
+  )
+  { return ret; }
+}
+
+Expression PrimarySuffix(Expression scope):
+{
+	Expression ret;
+}
+{
+  (
+  	LOOKAHEAD(2)
+	ret = PrimarySuffixWithoutSuper(scope)
+	|
+  	"." "super" { ret = new SuperExpr(range(scope, token()), scope); }
+  )
+  { return ret; }
+}
+
+Expression PrimarySuffixWithoutSuper(Expression scope):
+{
+	Expression ret;
+	RangedList<Type> typeArgs = new RangedList<Type>(null);
+	NodeList<Expression> args = emptyList();
+	boolean hasArgs = false;
+	SimpleName name;
+}
+{
+  (
+  	"."
+  	(
+		"this" { ret = new ThisExpr(range(scope, token()), scope); }
+	  |
+	  	ret = AllocationExpression(scope)
+	  |
+	  	LOOKAHEAD( [ TypeArguments() ] Identifier() )
+	  	[ typeArgs = TypeArguments() ]
+	  	name = SimpleName()
+	  	[ args = Arguments() {hasArgs=true;} ]
+	  	{
+			if (hasArgs) {
+	  			ret = new MethodCallExpr(range(scope, token()), scope, typeArgs.list, name, args);
+			} else {
+	  			ret =  new FieldAccessExpr(range(scope, token()), scope, typeArgs.list, name);
+			}
+	  	}
+	)
+	|
+	  "["ret = Expression() "]" { ret = new ArrayAccessExpr(range(scope, token()), scope, ret); }
+  )
+  { return ret; }
+}
+
+Expression Literal():
+{
+	Expression ret;
+}
+{
+  (
+	  <INTEGER_LITERAL> {
+	  		ret = new IntegerLiteralExpr(tokenRange(), token.image);
+	  }
+	|
+	  <LONG_LITERAL> {
+	  		ret = new LongLiteralExpr(tokenRange(), token.image);
+	  }
+	|
+	  <FLOATING_POINT_LITERAL> {
+	  		ret = new DoubleLiteralExpr(tokenRange(), token.image);
+	  }
+	|
+	  <CHARACTER_LITERAL> {
+	  	ret = new CharLiteralExpr(tokenRange(), token.image.substring(1, token.image.length()-1));
+	  }
+	|
+	  <STRING_LITERAL> {
+	  	ret = new StringLiteralExpr(tokenRange(), token.image.substring(1, token.image.length()-1));
+	  }
+	|
+	  ret = BooleanLiteral()
+	|
+	  ret = NullLiteral()
+  )
+  { return ret; }
+}
+
+Expression BooleanLiteral():
+{
+	Expression ret;
+}
+{
+  (
+	  "true" { ret = new BooleanLiteralExpr(tokenRange(), true); }
+	|
+	  "false" { ret = new BooleanLiteralExpr(tokenRange(), false); }
+  )
+  { return ret; }
+}
+
+Expression NullLiteral():
+{}
+{
+  "null"
+  { return new NullLiteralExpr(tokenRange()); }
+}
+
+NodeList<Expression> Arguments():
+{
+	NodeList<Expression> ret = emptyList();
+}
+{
+  "(" [ ret = ArgumentList() ] ")"
+  { return ret; }
+}
+
+NodeList<Expression> ArgumentList():
+{
+	NodeList<Expression> ret = emptyList();
+	Expression expr;
+}
+{
+  expr = Expression() { ret.add(expr); } ( "," expr = Expression() { ret.add(expr); } )*
+  { return ret; }
+}
+
+Expression AllocationExpression(Expression scope):
+{
+	Expression ret;
+	Type type;
+	RangedList<Type> typeArgs = new RangedList<Type>(null);
+	NodeList<BodyDeclaration<?>> anonymousBody = null;
+	NodeList<Expression> args;
+	JavaToken begin = INVALID;
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+}
+{
+    "new" { if(scope==null) {begin=token();} else {begin = orIfInvalid(begin, scope);} }
+    
+    annotations = Annotations() 
+    (
+        type = PrimitiveType(annotations)
+        ret = ArrayCreation(begin, type)
+    |
+        [ typeArgs = TypeArguments() ]
+        type = AnnotatedClassOrInterfaceType()
+        (
+            ret = ArrayCreation(begin, type)
+        |
+            args = Arguments() [ LOOKAHEAD(2) anonymousBody = ClassOrInterfaceBody() ]
+            { ret = new ObjectCreationExpr(range(begin, token()), scope, (ClassOrInterfaceType) type, typeArgs.list, args, anonymousBody); }
+        )
+    )
+    { return ret; }
+}
+
+ArrayCreationExpr ArrayCreation(JavaToken begin, Type type):
+{
+	Expression expr = null;
+	ArrayInitializerExpr arrayInitializerExpr = null;
+	NodeList<Expression> inits = emptyList();
+	List<NodeList<AnnotationExpr>> accum = new ArrayList<NodeList<AnnotationExpr>>();
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+	JavaToken arrayCreationLevelStart = INVALID;
+	List<TokenRange> levelRanges = new ArrayList<TokenRange>();
+}
+{ 
+    ( LOOKAHEAD(2)
+        annotations = Annotations()
+        "[" { arrayCreationLevelStart = annotations.isEmpty() ? token() : orIfInvalid(arrayCreationLevelStart, annotations.get(0)); }
+        (expr = Expression())? { accum = add(accum, annotations); inits = add(inits, expr); annotations=null; expr=null; } 
+        "]" { levelRanges.add(range(arrayCreationLevelStart, token())); }
+    )+ 
+    (arrayInitializerExpr = ArrayInitializer())? 
+    {  
+        return juggleArrayCreation(range(begin, token()), levelRanges, type, inits, accum, arrayInitializerExpr);
+    }
+}
+
+/*
+ * Statement syntax follows.
+ */
+
+Statement Statement():
+{
+	Statement ret;
+}
+{
+    try {
+        ( LOOKAHEAD(2)
+            ret = LabeledStatement()
+        |
+            ret = AssertStatement()
+        |
+            ret = Block()
+        |
+            ret = EmptyStatement()
+        |
+            ret = StatementExpression()
+        |
+            ret = SwitchStatement()
+        |
+            ret = IfStatement()
+        |
+            ret = WhileStatement()
+        |
+            ret = DoStatement()
+        |
+            ret = ForStatement()
+        |
+            ret = BreakStatement()
+        |
+            ret = ContinueStatement()
+        |
+            ret = ReturnStatement()
+        |
+            ret = ThrowStatement()
+        |
+            ret = SynchronizedStatement()
+        |
+            ret = TryStatement()
+        )
+        { return ret; }
+    } catch (ParseException e) {
+        TokenRange errorRange = recover(SEMICOLON, e);
+        return new UnparsableStmt(errorRange);
+    }
+}
+
+AssertStmt AssertStatement():
+{
+	Expression check;
+	Expression msg = null;
+	JavaToken begin;
+}
+{
+  "assert" {begin=token();} check = Expression() [ ":" msg = Expression() ] ";"
+  { return new AssertStmt(range(begin, token()), check, msg);  }
+}
+
+LabeledStmt LabeledStatement():
+{
+	SimpleName label;
+	Statement stmt;
+	JavaToken begin;
+}
+{
+  label = SimpleName() {begin=token();} ":" stmt = Statement()
+  { return new LabeledStmt(range(begin, token()), label, stmt); }
+}
+
+BlockStmt Block():
+{
+	NodeList<Statement> stmts = emptyList();
+	JavaToken begin;
+}
+{
+    "{" {begin=token();}
+    try {
+        stmts = Statements()
+        "}"
+        { return new BlockStmt(range(begin, token()), stmts); }
+    } catch (ParseException e) {
+        recover(RBRACE, e);
+        BlockStmt block = new BlockStmt(range(begin, token()), new NodeList<Statement>());
+        block.setParsed(UNPARSABLE);
+        return block;
+    }
+}
+
+/*
+ * Classes inside body statements can only be abstract or final. The semantic must check it.
+ */
+Statement BlockStatement():
+{
+	Statement ret;
+	Expression expr;
+	ClassOrInterfaceDeclaration typeDecl;
+	ModifierHolder modifier;
+}
+{
+    try {
+        ( LOOKAHEAD( Modifiers() ("class" | "interface") )
+            modifier = Modifiers()
+            typeDecl = ClassOrInterfaceDeclaration(modifier) { ret = new LocalClassDeclarationStmt(range(typeDecl, token()), typeDecl); }
+        | LOOKAHEAD(VariableDeclarationExpression() )
+            expr = VariableDeclarationExpression() ";"
+            { ret = new ExpressionStmt(range(expr, token()), expr); } 
+        |
+            ret = Statement()
+        )
+        { return ret; }
+    } catch (ParseException e) {
+        TokenRange errorRange = recover(SEMICOLON, e);
+        return new UnparsableStmt(errorRange);
+    }
+}
+
+VariableDeclarationExpr VariableDeclarationExpression():
+{
+	ModifierHolder modifier;
+	Type partialType;
+	NodeList<VariableDeclarator> variables = new NodeList<VariableDeclarator>();
+	VariableDeclarator var;
+}
+{
+    modifier = Modifiers() partialType = Type(emptyList()) var = VariableDeclarator(partialType) { variables.add(var); } ( "," var = VariableDeclarator(partialType) { variables.add(var); } )*
+    {
+        JavaToken begin=orIfInvalid(modifier.begin, partialType);
+        return new VariableDeclarationExpr(range(begin, token()), modifier.modifiers, modifier.annotations, variables);
+    }
+}
+
+EmptyStmt EmptyStatement():
+{}
+{
+    ";"
+    { return new EmptyStmt(tokenRange()); }
+}
+
+Statement LambdaBody():
+{
+    Expression expr;
+    Statement n = null;
+}
+{
+    (
+        expr = Expression() { n = new ExpressionStmt(range(expr, token()), expr); }
+        |  
+        n = Block()
+    )
+    { return n; }
+}
+
+ExpressionStmt StatementExpression():
+/*
+ * The last expansion of this production accepts more than the legal
+ * Java expansions for StatementExpression.  This expansion does not
+ * use PostfixExpression for performance reasons.
+ */
+{
+	Expression expr;
+	AssignExpr.Operator op;
+	Expression value;
+	RangedList<Type> typeArgs = new RangedList<Type>(null);
+	Statement lambdaBody;
+}
+{
+    ( LOOKAHEAD(2)
+        expr = PreIncrementExpression()
+        |
+        expr = PreDecrementExpression()
+        |
+        expr = PrimaryExpression()
+        [
+            "++" { expr = new UnaryExpr(range(expr, token()), expr, UnaryExpr.Operator.POSTFIX_INCREMENT);  }
+            |
+            "--" { expr = new UnaryExpr(range(expr, token()), expr, UnaryExpr.Operator.POSTFIX_DECREMENT);  }
+            |
+            op = AssignmentOperator() value = Expression() { expr = new AssignExpr(range(expr, token()), expr, value, op); }
+        ]
+    )
+    ";"
+    { return new ExpressionStmt(range(expr, token()), expr); }
+}
+
+SwitchStmt SwitchStatement():
+{
+	Expression selector;
+	SwitchEntryStmt entry;
+	NodeList<SwitchEntryStmt> entries = emptyList();
+	JavaToken begin;
+}
+{
+  "switch" {begin=token();} "(" selector = Expression() ")" "{"
+    ( entry = SwitchEntry() { entries = add(entries, entry); } )*
+  "}"
+
+  { return new SwitchStmt(range(begin, token()), selector, entries); }
+}
+
+SwitchEntryStmt SwitchEntry():
+{
+	Expression label = null;
+	NodeList<Statement> stmts;
+	JavaToken begin;
+}
+{
+  (
+	  "case" {begin=token();} label = Expression()
+	|
+	  "default" {begin=token();}
+  )
+  ":" stmts = Statements()
+
+  { return new SwitchEntryStmt(range(begin, token()),label, stmts); }
+}
+
+IfStmt IfStatement():
+/*
+ * The disambiguating algorithm of JavaCC automatically binds dangling
+ * else's to the innermost if statement.  The LOOKAHEAD specification
+ * is to tell JavaCC that we know what we are doing.
+ */
+{
+	Expression condition;
+	Statement thenStmt;
+	Statement elseStmt = null;
+	JavaToken begin;
+}
+{
+  "if" {begin=token();} "(" condition = Expression() ")" {} thenStmt = Statement() [ LOOKAHEAD(1) "else" {} elseStmt = Statement() ]
+  { 
+      return new IfStmt(range(begin, token()), condition, thenStmt, elseStmt);
+  }
+}
+
+WhileStmt WhileStatement():
+{
+	Expression condition;
+	Statement body;
+	JavaToken begin;
+}
+{
+  "while" {begin=token();} "(" condition = Expression() ")" body = Statement()
+  { return new WhileStmt(range(begin, token()),condition, body); }
+}
+
+DoStmt DoStatement():
+{
+	Expression condition;
+	Statement body;
+	JavaToken begin;
+}
+{
+  "do" {begin=token();} body = Statement() "while" "(" condition = Expression() ")" ";"
+  { return new DoStmt(range(begin, token()),body, condition); }
+}
+
+Statement ForStatement():
+{
+	VariableDeclarationExpr varExpr = null;
+	Expression expr = null;
+	NodeList<Expression> init = emptyList();
+	NodeList<Expression> update = emptyList();
+	Statement body;
+	JavaToken begin;
+}
+{
+  "for" {begin=token();} "("
+
+  (
+      LOOKAHEAD(VariableDeclarationExpression() ":")
+      varExpr = VariableDeclarationExpression() ":" expr = Expression()
+    |
+     [ init = ForInit() ] ";" [ expr = Expression() ] ";" [ update = ForUpdate() ]
+  )
+
+  ")" body = Statement()
+
+  {
+  	if (varExpr != null) {
+  		return new ForeachStmt(range(begin, token()),varExpr, expr, body);
+  	}
+	return new ForStmt(range(begin, token()),init, expr, update, body);
+  }
+}
+
+NodeList<Expression> ForInit():
+{
+	NodeList<Expression> ret;
+	Expression expr;
+}
+{
+  (
+	  LOOKAHEAD( Modifiers() Type() Identifier() )
+	  expr = VariableDeclarationExpression() { ret = new NodeList<Expression>(); ret.add(expr); }
+	|
+	  ret = ExpressionList()
+  )
+  { return ret; }
+}
+
+NodeList<Expression> ExpressionList():
+{
+	NodeList<Expression> ret = new NodeList<Expression>();
+	Expression expr;
+}
+{
+  expr = Expression() { ret.add(expr); } ( "," expr = Expression()  { ret.add(expr); } )*
+
+  { return ret; }
+}
+
+NodeList<Expression> ForUpdate():
+{
+	NodeList<Expression> ret;
+}
+{
+  ret = ExpressionList()
+
+  { return ret; }
+}
+
+BreakStmt BreakStatement():
+{
+	SimpleName label = null;
+	JavaToken begin;
+}
+{
+  "break" {begin=token();} [ label = SimpleName() ] ";"
+  { return new BreakStmt(range(begin, token()), label); }
+}
+
+ContinueStmt ContinueStatement():
+{
+	SimpleName label = null;
+	JavaToken begin;
+}
+{
+  "continue" {begin=token();} [ label = SimpleName() ] ";"
+  { return new ContinueStmt(range(begin, token()), label); }
+}
+
+ReturnStmt ReturnStatement():
+{
+	Expression expr = null;
+	JavaToken begin;
+}
+{
+  "return" {begin=token();} [ expr = Expression() ] ";"
+  { return new ReturnStmt(range(begin, token()),expr); }
+}
+
+ThrowStmt ThrowStatement():
+{
+	Expression expr;
+	JavaToken begin;
+}
+{
+  "throw" {begin=token();} expr = Expression() ";"
+  { return new ThrowStmt(range(begin, token()),expr); }
+}
+
+SynchronizedStmt SynchronizedStatement():
+{
+	Expression expr;
+	BlockStmt body;
+	JavaToken begin;
+}
+{
+  "synchronized" {begin=token();} "(" expr = Expression() ")" body = Block()
+  { return new SynchronizedStmt(range(begin, token()),expr, body); }
+}
+
+TryStmt TryStatement():
+{
+	NodeList<Expression> resources = emptyList();
+	BlockStmt tryBlock;
+	BlockStmt finallyBlock = null;
+	NodeList<CatchClause> catchs = emptyList();
+	BlockStmt catchBlock;
+	ModifierHolder exceptModifier;
+	ReferenceType exceptionType;
+	NodeList<ReferenceType> exceptionTypes = emptyList();
+	Pair<SimpleName, List<ArrayBracketPair>> exceptId;
+	JavaToken begin;
+	JavaToken catchBegin;
+	JavaToken typesBegin;
+	JavaToken paramEnd;
+	Type type;
+}
+{
+  "try" {begin=token();}
+  (resources = ResourceSpecification())?
+  tryBlock = Block()
+  (
+        LOOKAHEAD(2)
+  		(
+  			"catch" {catchBegin=token();}
+  			"(" { typesBegin=token(); }
+  			exceptModifier = Modifiers() exceptionType = ReferenceType(emptyList()) { exceptionTypes.add(exceptionType); }
+  			( "|" exceptionType = AnnotatedReferenceType() { exceptionTypes.add(exceptionType); } )*
+  			exceptId = VariableDeclaratorId() { paramEnd = token(); }
+  			")"
+  			 
+  			catchBlock = Block()
+  			{
+  			    if (exceptionTypes.size() > 1) {
+  			        type = new UnionType(range(exceptionTypes.get(0), exceptionTypes.get(exceptionTypes.size() - 1)), exceptionTypes);
+  			    } else {
+  			        type = (Type)exceptionTypes.get(0);
+  			    }
+				Parameter catchType = new Parameter(range(type, paramEnd), exceptModifier.modifiers, exceptModifier.annotations, type, false, emptyList(), exceptId.a);
+  			    catchs = add(catchs, new CatchClause(range(catchBegin, token()), catchType, catchBlock));
+  			    exceptionTypes = emptyList(); }
+  		)*
+  		[ "finally" finallyBlock = Block() ]
+  	|
+  		"finally" finallyBlock = Block()
+  )
+  { return new TryStmt(range(begin, token()), resources, tryBlock, catchs, finallyBlock); }
+}
+
+
+NodeList<Expression> ResourceSpecification() :
+{
+  NodeList<Expression> variables;
+}
+{
+  "("
+  variables = Resources()
+  (LOOKAHEAD(2) ";")?
+  ")"
+  { return variables; }
+}
+
+
+NodeList<Expression> Resources() :
+{
+	NodeList<Expression> expressions = new NodeList<Expression>();
+	Expression expr;
+}
+{
+    expr = Resource() {expressions.add(expr);} (LOOKAHEAD(2) ";" expr = Resource() {expressions.add(expr);})*
+    { return expressions; }
+}
+
+Expression Resource() :
+{
+	Expression expr;
+}
+{
+    ( LOOKAHEAD( Modifiers() partialType = Type() VariableDeclarator(partialType))
+        /*this is a bit more lenient than we need to be, eg allowing access modifiers like private*/
+        expr = VariableDeclarationExpression()
+    |
+        expr = PrimaryExpression()
+    )
+    { return expr; }
+}
+
+
+/* We use productions to match >>>, >> and > so that we can keep the
+ * type declaration syntax with generics clean
+ */
+
+void RUNSIGNEDSHIFT():
+{}
+{
+  ( LOOKAHEAD({ getToken(1).kind == GT &&
+                getToken(1).realKind == RUNSIGNEDSHIFT} )
+   ">" ">" ">"
+  )
+}
+
+void RSIGNEDSHIFT():
+{}
+{
+  ( LOOKAHEAD({ getToken(1).kind == GT &&
+                getToken(1).realKind == RSIGNEDSHIFT} )
+  ">" ">"
+  )
+}
+
+/* Annotation syntax follows. */
+
+NodeList<AnnotationExpr> Annotations():
+{
+	NodeList<AnnotationExpr> annotations = new NodeList<AnnotationExpr>();
+	AnnotationExpr annotation;
+}
+{
+   (LOOKAHEAD("@") annotation = Annotation()  {annotations = add(annotations, annotation);} )*
+   { return annotations; }
+}
+
+AnnotationExpr Annotation():
+{
+	AnnotationExpr ret;
+	Name name;
+	NodeList<MemberValuePair> pairs = emptyList();
+	JavaToken begin;
+	Expression memberVal;
+}
+{
+    "@" { begin=token(); } name = Name()
+    (
+        LOOKAHEAD( "(" ( Identifier() "=" | ")" ))
+        "(" [ pairs = MemberValuePairs() ] ")"
+        { ret = new NormalAnnotationExpr(range(begin, token()), name, pairs); }
+    |
+        LOOKAHEAD( "(" )
+        "(" memberVal = MemberValue() ")"
+        { ret = new SingleMemberAnnotationExpr(range(begin, token()), name, memberVal); }
+    |
+        { ret = new MarkerAnnotationExpr(range(begin, token()), name); }
+    )
+    { return ret; }
+}
+
+NodeList<MemberValuePair> MemberValuePairs():
+{
+	NodeList<MemberValuePair> ret = new NodeList<MemberValuePair>();
+	MemberValuePair pair;
+}
+{
+   pair = MemberValuePair() { ret.add(pair); } ( "," pair = MemberValuePair() { ret.add(pair); } )*
+   { return ret; }
+}
+
+MemberValuePair MemberValuePair():
+{
+	SimpleName name;
+	Expression value;
+	JavaToken begin;
+}
+{
+    name = SimpleName() { begin=token();} "=" value = MemberValue()
+    { return new MemberValuePair(range(begin, token()),name, value); }
+}
+
+Expression MemberValue():
+{
+	Expression ret;
+}
+{
+  ( LOOKAHEAD("@")
+	   ret = Annotation()
+	 |
+	   ret = MemberValueArrayInitializer()
+	 |
+	   ret = ConditionalExpression()
+  )
+  { return ret; }
+}
+
+Expression  MemberValueArrayInitializer():
+{
+	NodeList<Expression> ret = emptyList();
+	Expression member;
+	JavaToken begin;
+}
+{
+  "{" {begin=token();}
+  (	member = MemberValue() { ret.add(member); } ( LOOKAHEAD(2) "," member = MemberValue() { ret.add(member); } )*  )? [ "," ]
+  "}"
+  { return new ArrayInitializerExpr(range(begin, token()),ret); }
+}
+
+
+/* Annotation Types. */
+
+AnnotationDeclaration AnnotationTypeDeclaration(ModifierHolder modifier):
+{
+	SimpleName name;
+    NodeList<BodyDeclaration<?>> members = emptyList();
+	JavaToken begin = modifier.begin;
+}
+{
+  "@" { begin=orIfInvalid(begin, token()); }
+  "interface" name = SimpleName() members = AnnotationTypeBody()
+  { 
+      return new AnnotationDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, name, members);
+  }
+}
+
+NodeList<BodyDeclaration<?>> AnnotationTypeBody():
+{
+	NodeList<BodyDeclaration<?>> ret = emptyList();
+	BodyDeclaration member;
+}
+{
+    "{" ( 
+        member = AnnotationBodyDeclaration() { ret = addWhenNotNull(ret, member); }
+    |
+        ";"
+    )* "}"
+    { return ret; }
+}
+
+BodyDeclaration<?> AnnotationBodyDeclaration():
+{
+   ModifierHolder modifier;
+   BodyDeclaration ret;
+}
+{
+  (
+    modifier = Modifiers()
+    (
+	   LOOKAHEAD(Type() Identifier() "(")
+	   ret = AnnotationTypeMemberDeclaration(modifier)
+	  |
+	   ret = ClassOrInterfaceDeclaration(modifier)
+	  | LOOKAHEAD("enum")
+	   ret = EnumDeclaration(modifier)
+	  |
+	   ret = AnnotationTypeDeclaration(modifier)
+	  |
+	   ret = FieldDeclaration(modifier)
+    )
+  )
+  { return ret; }
+}
+
+AnnotationMemberDeclaration AnnotationTypeMemberDeclaration(ModifierHolder modifier):
+{
+	Type type;
+	SimpleName name;
+	Expression defaultVal = null;
+}
+{
+  type = Type(emptyList()) name = SimpleName() "(" ")" [ defaultVal = DefaultValue() ] ";"
+
+  {
+	JavaToken begin = orIfInvalid(modifier.begin, type);
+    return new AnnotationMemberDeclaration(range(begin, token()), modifier.modifiers, modifier.annotations, type, name, defaultVal);
+  }
+}
+
+Expression DefaultValue():
+{
+	Expression ret;
+}
+{
+  "default" ret = MemberValue()
+  { return ret; }
+}
+
+/* Module syntax follows */
+
+
+ModuleStmt ModuleStmt():
+{
+    ModifierHolder modifiers;
+    Name name;
+    Name tmpName;
+    NodeList<Name> names=emptyList();
+    Type type;
+    Type tmpType;
+    NodeList<Type> types=emptyList();
+    JavaToken begin;
+    ModuleStmt stmt=new ModuleRequiresStmt();
+    JavaToken transitiveExceptionalToken;
+}
+{
+    (
+        // This is a hack for the edge case "requires transitive;" which is supposed to mean "require the module named 'transitive'" 
+        LOOKAHEAD(<REQUIRES> <TRANSITIVE> ";")
+        <REQUIRES> {begin=token();} <TRANSITIVE> {transitiveExceptionalToken=token(); setTokenKind(IDENTIFIER);} ";" {stmt=new ModuleRequiresStmt(range(begin, token()), EnumSet.noneOf(Modifier.class), new Name(range(transitiveExceptionalToken, transitiveExceptionalToken), null, transitiveExceptionalToken.getText(), new NodeList<AnnotationExpr>()));}
+    |
+        <REQUIRES> {begin=token();} modifiers=Modifiers() name=Name() ";" {stmt=new ModuleRequiresStmt(range(begin, token()), modifiers.modifiers, name);}
+    |
+        <EXPORTS> {begin=token();} name=Name() [<TO> tmpName=Name() {names.add(tmpName);} ("," tmpName=Name(){names.add(tmpName);} )* ] ";" {stmt=new ModuleExportsStmt(range(begin, token()), name, names);}
+    |
+        <OPENS> {begin=token();} name=Name() [<TO> tmpName=Name() {names.add(tmpName);} ("," tmpName=Name(){names.add(tmpName);} )* ] ";" {stmt=new ModuleOpensStmt(range(begin, token()), name, names);}
+    |
+        <USES> { begin=token();} type=Type(emptyList()) ";" {stmt=new ModuleUsesStmt(range(begin, token()), type);}
+    |
+        <PROVIDES> { begin=token();} type=Type(emptyList()) <WITH> tmpType=Type(emptyList()) {types.add(tmpType);} ("," tmpType=Type(emptyList()) {types.add(tmpType);}  )* ";" {stmt=new ModuleProvidesStmt(range(begin, token()), type, types);}
+    )
+    { return stmt; }
+}
+
+ModuleDeclaration ModuleDeclaration(ModifierHolder modifier):
+{
+    NodeList<ModuleStmt> statements = new NodeList<ModuleStmt>();
+    boolean open=false;
+    ModuleStmt st;
+    Name name;
+    JavaToken begin = modifier.begin;
+}
+{
+    [ <OPEN> {open=true; begin = orIfInvalid(begin, token());} ]
+    <MODULE> { begin = orIfInvalid(begin, token()); }
+    name = Name() "{"
+    ( st = ModuleStmt() { statements = add(statements, st); } )*
+    "}"
+    { return new ModuleDeclaration(range(begin, token()), modifier.annotations, name, open, statements); }
+}
+
+/* Rules for matching partial inputs.
+These rules are needed to properly terminate them -
+if we simply use the usual rules, they will ignore everything in the provider
+after they matched their desired input, which will lead to unexpected behaviour
+*/
+
+
+BlockStmt BlockParseStart():
+{ BlockStmt ret; }
+{ ret = Block() <EOF> { return ret; } }
+
+Statement BlockStatementParseStart():
+{ Statement ret; }
+{ (LOOKAHEAD(3) ret = BlockStatement()|ret = ExplicitConstructorInvocation()) <EOF> { return ret; } }
+
+ImportDeclaration ImportDeclarationParseStart():
+{ ImportDeclaration ret; }
+{ ret = ImportDeclaration() <EOF> { return ret; } }
+
+Expression ExpressionParseStart():
+{ Expression ret; }
+{ ret = Expression() <EOF> { return ret; } }
+
+AnnotationExpr AnnotationParseStart():
+{ AnnotationExpr ret; }
+{ ret = Annotation() <EOF> { return ret; } }
+
+BodyDeclaration<?> AnnotationBodyDeclarationParseStart():
+{ BodyDeclaration<?> ret; }
+{ ret = AnnotationBodyDeclaration() <EOF> { return ret; } }
+
+BodyDeclaration<?> ClassOrInterfaceBodyDeclarationParseStart():
+{ BodyDeclaration<?> ret; }
+{ ret = ClassOrInterfaceBodyDeclaration() <EOF> { return ret; } }
+
+ClassOrInterfaceType ClassOrInterfaceTypeParseStart():
+{ ClassOrInterfaceType ret; }
+{ ret = AnnotatedClassOrInterfaceType() <EOF> { return ret; } }
+
+Type ResultTypeParseStart():
+{ NodeList<AnnotationExpr> annotations; Type ret; }
+{ annotations = Annotations() ret = ResultType(annotations) <EOF> { return ret; } }
+
+VariableDeclarationExpr VariableDeclarationExpressionParseStart():
+{ VariableDeclarationExpr ret; }
+{ ret = VariableDeclarationExpression() <EOF> { return ret; } }
+
+ExplicitConstructorInvocationStmt ExplicitConstructorInvocationParseStart():
+{ ExplicitConstructorInvocationStmt ret; }
+{ ret = ExplicitConstructorInvocation() <EOF> { return ret; } }
+
+Name NameParseStart():
+{ Name ret; }
+{ ret = Name() <EOF> { return ret; } }
+
+SimpleName SimpleNameParseStart():
+{ SimpleName ret; }
+{ ret = SimpleName() <EOF> { return ret; } }
+
+Parameter ParameterParseStart():
+{ Parameter ret; }
+{ ret = Parameter() <EOF> { return ret; } }
+
+PackageDeclaration PackageDeclarationParseStart():
+{ PackageDeclaration ret; }
+{ ret = PackageDeclaration() <EOF> { return ret; } }
diff --git a/javaparser-metamodel-generator/javaparser-metamodel-generator.iml b/javaparser-metamodel-generator/javaparser-metamodel-generator.iml
new file mode 100644
index 0000000..1f0ec62
--- /dev/null
+++ b/javaparser-metamodel-generator/javaparser-metamodel-generator.iml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="javaparser-core" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-metamodel-generator/pom.xml b/javaparser-metamodel-generator/pom.xml
new file mode 100644
index 0000000..7a1e498
--- /dev/null
+++ b/javaparser-metamodel-generator/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>javaparser-parent</artifactId>
+        <groupId>com.github.javaparser</groupId>
+        <version>3.5.16-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-metamodel-generator</artifactId>
+    <description>The tool that generates the code in the javaparser-metamodel module</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <!-- no need to release this module -->
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>run-metamodel-generator</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>generate-javaparser-metamodel</id>
+                                <phase>test</phase>
+                                <goals>
+                                    <goal>java</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <classpathScope>test</classpathScope>
+                            <mainClass>com.github.javaparser.generator.metamodel.MetaModelGenerator</mainClass>
+                            <arguments>
+                                <argument>${project.basedir}</argument>
+                            </arguments>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/AstTypeAnalysis.java b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/AstTypeAnalysis.java
new file mode 100644
index 0000000..1801f2d
--- /dev/null
+++ b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/AstTypeAnalysis.java
@@ -0,0 +1,56 @@
+package com.github.javaparser.generator.metamodel;
+
+import com.github.javaparser.ast.NodeList;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.EnumSet;
+import java.util.Optional;
+
+import static java.lang.reflect.Modifier.isAbstract;
+
+/**
+ * A hacky thing that collects flags we need from AST types to generate the metamodel.
+ */
+public class AstTypeAnalysis {
+    public final boolean isAbstract;
+    public boolean isOptional = false;
+    public boolean isEnumSet = false;
+    public boolean isNodeList = false;
+    public boolean isSelfType = false;
+    public Class<?> innerType;
+
+    AstTypeAnalysis(Type type) {
+        if (type instanceof Class<?>) {
+            TypeVariable<? extends Class<?>>[] typeParameters = ((Class<?>) type).getTypeParameters();
+            if (typeParameters.length > 0) {
+                isSelfType = true;
+            }
+        } else {
+            while (type instanceof ParameterizedType) {
+                ParameterizedType t = (ParameterizedType) type;
+                Type currentOuterType = t.getRawType();
+                if (currentOuterType == NodeList.class) {
+                    isNodeList = true;
+                }
+                if (currentOuterType == Optional.class) {
+                    isOptional = true;
+                }
+                if (currentOuterType == EnumSet.class) {
+                    isEnumSet = true;
+                }
+
+                if (t.getActualTypeArguments()[0] instanceof WildcardType) {
+                    type = t.getRawType();
+                    isSelfType = true;
+                    break;
+                }
+                type = t.getActualTypeArguments()[0];
+            }
+        }
+        innerType = (Class<?>) type;
+        isAbstract = isAbstract(innerType.getModifiers());
+    }
+}
diff --git a/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/InitializeConstructorParametersStatementsGenerator.java b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/InitializeConstructorParametersStatementsGenerator.java
new file mode 100644
index 0000000..d50c0ed
--- /dev/null
+++ b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/InitializeConstructorParametersStatementsGenerator.java
@@ -0,0 +1,58 @@
+package com.github.javaparser.generator.metamodel;
+
+import com.github.javaparser.ast.AllFieldsConstructor;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.stmt.Statement;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+
+import static com.github.javaparser.JavaParser.parseStatement;
+import static com.github.javaparser.generator.metamodel.MetaModelGenerator.nodeMetaModelFieldName;
+import static com.github.javaparser.generator.metamodel.MetaModelGenerator.propertyMetaModelFieldName;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+
+class InitializeConstructorParametersStatementsGenerator {
+    void generate(Class<? extends Node> nodeClass, NodeList<Statement> initializeConstructorParametersStatements) {
+        if (nodeClass == Node.class) {
+            return;
+        }
+        Constructor<?> constructor = findAllFieldsConstructor(nodeClass);
+        for (java.lang.reflect.Parameter parameter : constructor.getParameters()) {
+            Field field = findFieldInClass(nodeClass, parameter.getName());
+
+            String addFieldStatement = f("%s.getConstructorParameters().add(%s.%s);",
+                    nodeMetaModelFieldName(nodeClass),
+                    nodeMetaModelFieldName(field.getDeclaringClass()),
+                    propertyMetaModelFieldName(field));
+
+            initializeConstructorParametersStatements.add(parseStatement(addFieldStatement));
+        }
+    }
+
+    private Field findFieldInClass(Class<?> nodeClass, String name) {
+        Class<?> searchClass = nodeClass;
+        do {
+            for (Field field : searchClass.getDeclaredFields()) {
+                if (field.getName().equals(name)) {
+                    return field;
+                }
+            }
+            searchClass = searchClass.getSuperclass();
+        } while (searchClass != null);
+        throw new AssertionError(f("Couldn't find constructor parameter %s as a field, class %s", name, nodeClass.getSimpleName()));
+    }
+
+    private Constructor<?> findAllFieldsConstructor(Class<? extends Node> nodeClass) {
+        for (Constructor<?> constructor : nodeClass.getDeclaredConstructors()) {
+            for (Annotation annotation : constructor.getAnnotations()) {
+                if (annotation.annotationType() == AllFieldsConstructor.class) {
+                    return constructor;
+                }
+            }
+        }
+        throw new AssertionError(f("Node class %s has no constructor annotated with @AllFieldsConstructor", nodeClass.getSimpleName()));
+    }
+}
diff --git a/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/InitializePropertyMetaModelsStatementsGenerator.java b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/InitializePropertyMetaModelsStatementsGenerator.java
new file mode 100644
index 0000000..be1ff54
--- /dev/null
+++ b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/InitializePropertyMetaModelsStatementsGenerator.java
@@ -0,0 +1,79 @@
+package com.github.javaparser.generator.metamodel;
+
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.metamodel.NonEmptyProperty;
+import com.github.javaparser.metamodel.OptionalProperty;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import static com.github.javaparser.JavaParser.parseStatement;
+import static com.github.javaparser.ast.Modifier.PUBLIC;
+import static com.github.javaparser.generator.metamodel.MetaModelGenerator.isNode;
+import static com.github.javaparser.generator.metamodel.MetaModelGenerator.nodeMetaModelName;
+import static com.github.javaparser.utils.CodeGenerationUtils.*;
+import static com.github.javaparser.utils.Utils.decapitalize;
+
+class InitializePropertyMetaModelsStatementsGenerator {
+    void generate(Field field, ClassOrInterfaceDeclaration nodeMetaModelClass, String nodeMetaModelFieldName, NodeList<Statement> initializePropertyMetaModelsStatements) throws NoSuchMethodException {
+        final AstTypeAnalysis fieldTypeAnalysis = new AstTypeAnalysis(field.getGenericType());
+
+        final Class<?> fieldType = fieldTypeAnalysis.innerType;
+        final String typeName = fieldType.getTypeName().replace('$', '.');
+        final String propertyMetaModelFieldName = field.getName() + "PropertyMetaModel";
+        nodeMetaModelClass.addField("PropertyMetaModel", propertyMetaModelFieldName, PUBLIC);
+        final String propertyInitializer = f("new PropertyMetaModel(%s, \"%s\", %s.class, %s, %s, %s, %s, %s, %s)",
+                nodeMetaModelFieldName,
+                field.getName(),
+                typeName,
+                optionalOf(decapitalize(nodeMetaModelName(fieldType)), isNode(fieldType)),
+                isOptional(field),
+                isNonEmpty(field),
+                fieldTypeAnalysis.isNodeList,
+                fieldTypeAnalysis.isEnumSet,
+                fieldTypeAnalysis.isSelfType);
+        final String fieldSetting = f("%s.%s=%s;", nodeMetaModelFieldName, propertyMetaModelFieldName, propertyInitializer);
+        final String fieldAddition = f("%s.getDeclaredPropertyMetaModels().add(%s.%s);", nodeMetaModelFieldName, nodeMetaModelFieldName, propertyMetaModelFieldName);
+
+        initializePropertyMetaModelsStatements.add(parseStatement(fieldSetting));
+        initializePropertyMetaModelsStatements.add(parseStatement(fieldAddition));
+    }
+
+    void generateDerivedProperty(Method method, ClassOrInterfaceDeclaration nodeMetaModelClass, String nodeMetaModelFieldName, NodeList<Statement> initializePropertyMetaModelsStatements) {
+        final AstTypeAnalysis returnTypeAnalysis = new AstTypeAnalysis(method.getGenericReturnType());
+
+        final Class<?> innermostReturnType = returnTypeAnalysis.innerType;
+        final String typeName = innermostReturnType.getTypeName().replace('$', '.');
+        final String propertyMetaModelFieldName = getterToPropertyName(method.getName()) + "PropertyMetaModel";
+        nodeMetaModelClass.addField("PropertyMetaModel", propertyMetaModelFieldName, PUBLIC);
+        final String propertyInitializer = f("new PropertyMetaModel(%s, \"%s\", %s.class, %s, %s, %s, %s, %s, %s)",
+                nodeMetaModelFieldName,
+                getterToPropertyName(method.getName()),
+                typeName,
+                optionalOf(decapitalize(nodeMetaModelName(innermostReturnType)), isNode(innermostReturnType)),
+                returnTypeAnalysis.isOptional,
+                isNonEmpty(method),
+                returnTypeAnalysis.isNodeList,
+                returnTypeAnalysis.isEnumSet,
+                returnTypeAnalysis.isSelfType);
+        final String fieldSetting = f("%s.%s=%s;", nodeMetaModelFieldName, propertyMetaModelFieldName, propertyInitializer);
+        final String fieldAddition = f("%s.getDerivedPropertyMetaModels().add(%s.%s);", nodeMetaModelFieldName, nodeMetaModelFieldName, propertyMetaModelFieldName);
+
+        initializePropertyMetaModelsStatements.add(parseStatement(fieldSetting));
+        initializePropertyMetaModelsStatements.add(parseStatement(fieldAddition));
+    }
+
+    private boolean isNonEmpty(Field field) {
+        return field.isAnnotationPresent(NonEmptyProperty.class);
+    }
+
+    private boolean isNonEmpty(Method method) {
+        return method.isAnnotationPresent(NonEmptyProperty.class);
+    }
+
+    private boolean isOptional(Field field) {
+        return field.isAnnotationPresent(OptionalProperty.class);
+    }
+}
diff --git a/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/MetaModelGenerator.java b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/MetaModelGenerator.java
new file mode 100644
index 0000000..43d9112
--- /dev/null
+++ b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/MetaModelGenerator.java
@@ -0,0 +1,207 @@
+package com.github.javaparser.generator.metamodel;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.printer.PrettyPrinter;
+import com.github.javaparser.printer.PrettyPrinterConfiguration;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.decapitalize;
+
+public class MetaModelGenerator {
+    static final String BASE_NODE_META_MODEL = "BaseNodeMetaModel";
+    private static List<Class<? extends Node>> ALL_NODE_CLASSES = new ArrayList<Class<? extends Node>>() {{
+        /* Base classes go first, so we don't have to do any sorting to make sure
+         generated classes can refer to their base generated classes without
+         being afraid those are not initialized yet. */
+        add(Node.class);
+
+        add(BodyDeclaration.class);
+        add(CallableDeclaration.class);
+        add(Statement.class);
+        add(Expression.class);
+        add(Type.class);
+
+        add(AnnotationExpr.class);
+        add(TypeDeclaration.class);
+        add(ReferenceType.class);
+
+        add(LiteralExpr.class);
+        add(LiteralStringValueExpr.class);
+        add(StringLiteralExpr.class);
+
+        add(ModuleDeclaration.class);
+        add(ModuleStmt.class);
+
+        //
+        add(ArrayCreationLevel.class);
+        add(CompilationUnit.class);
+        add(PackageDeclaration.class);
+
+        add(AnnotationDeclaration.class);
+        add(AnnotationMemberDeclaration.class);
+        add(ClassOrInterfaceDeclaration.class);
+        add(ConstructorDeclaration.class);
+        add(EnumConstantDeclaration.class);
+        add(EnumDeclaration.class);
+        add(FieldDeclaration.class);
+        add(InitializerDeclaration.class);
+        add(MethodDeclaration.class);
+        add(Parameter.class);
+        add(ReceiverParameter.class);
+        add(VariableDeclarator.class);
+
+        add(Comment.class);
+        add(BlockComment.class);
+        add(JavadocComment.class);
+        add(LineComment.class);
+
+        add(ArrayAccessExpr.class);
+        add(ArrayCreationExpr.class);
+        add(ArrayInitializerExpr.class);
+        add(AssignExpr.class);
+        add(BinaryExpr.class);
+        add(BooleanLiteralExpr.class);
+        add(CastExpr.class);
+        add(CharLiteralExpr.class);
+        add(ClassExpr.class);
+        add(ConditionalExpr.class);
+        add(DoubleLiteralExpr.class);
+        add(EnclosedExpr.class);
+        add(FieldAccessExpr.class);
+        add(InstanceOfExpr.class);
+        add(IntegerLiteralExpr.class);
+        add(LambdaExpr.class);
+        add(LongLiteralExpr.class);
+        add(MarkerAnnotationExpr.class);
+        add(MemberValuePair.class);
+        add(MethodCallExpr.class);
+        add(MethodReferenceExpr.class);
+        add(NameExpr.class);
+        add(Name.class);
+        add(NormalAnnotationExpr.class);
+        add(NullLiteralExpr.class);
+        add(ObjectCreationExpr.class);
+        add(SimpleName.class);
+        add(SingleMemberAnnotationExpr.class);
+        add(SuperExpr.class);
+        add(ThisExpr.class);
+        add(TypeExpr.class);
+        add(UnaryExpr.class);
+        add(VariableDeclarationExpr.class);
+
+        add(ImportDeclaration.class);
+
+        add(AssertStmt.class);
+        add(BlockStmt.class);
+        add(BreakStmt.class);
+        add(CatchClause.class);
+        add(ContinueStmt.class);
+        add(DoStmt.class);
+        add(EmptyStmt.class);
+        add(ExplicitConstructorInvocationStmt.class);
+        add(ExpressionStmt.class);
+        add(ForeachStmt.class);
+        add(ForStmt.class);
+        add(IfStmt.class);
+        add(LabeledStmt.class);
+        add(ReturnStmt.class);
+        add(SwitchEntryStmt.class);
+        add(SwitchStmt.class);
+        add(SynchronizedStmt.class);
+        add(ThrowStmt.class);
+        add(TryStmt.class);
+        add(LocalClassDeclarationStmt.class);
+        add(WhileStmt.class);
+        add(UnparsableStmt.class);
+
+        add(ArrayType.class);
+        add(ClassOrInterfaceType.class);
+        add(IntersectionType.class);
+        add(PrimitiveType.class);
+        add(TypeParameter.class);
+        add(UnionType.class);
+        add(UnknownType.class);
+        add(VoidType.class);
+        add(WildcardType.class);
+        add(VarType.class);
+
+        add(ModuleRequiresStmt.class);
+        add(ModuleExportsStmt.class);
+        add(ModuleProvidesStmt.class);
+        add(ModuleUsesStmt.class);
+        add(ModuleOpensStmt.class);
+    }};
+
+    static String METAMODEL_PACKAGE = "com.github.javaparser.metamodel";
+
+    public static void main(String[] args) throws IOException, NoSuchMethodException {
+        if (args.length != 1) {
+            throw new RuntimeException("Need 1 parameter: the JavaParser source checkout root directory.");
+        }
+        final Path root = Paths.get(args[0], "..", "javaparser-core", "src", "main", "java");
+        final SourceRoot sourceRoot = new SourceRoot(root);
+        sourceRoot.setPrinter(new PrettyPrinter(new PrettyPrinterConfiguration().setEndOfLineCharacter("\n"))::print);
+
+        new MetaModelGenerator().run(sourceRoot);
+
+        sourceRoot.saveAll();
+    }
+
+    private void run(SourceRoot sourceRoot) throws IOException, NoSuchMethodException {
+        final CompilationUnit javaParserMetaModel = sourceRoot.parse(METAMODEL_PACKAGE, "JavaParserMetaModel.java");
+
+        generateNodeMetaModels(javaParserMetaModel, sourceRoot);
+    }
+
+    private void generateNodeMetaModels(CompilationUnit javaParserMetaModelCu, SourceRoot sourceRoot) throws NoSuchMethodException {
+        final ClassOrInterfaceDeclaration metaModelCoid = javaParserMetaModelCu.getClassByName("JavaParserMetaModel").get();
+        final NodeList<Statement> initializeNodeMetaModelsStatements = metaModelCoid.getMethodsByName("initializeNodeMetaModels").get(0).getBody().get().getStatements();
+        final NodeList<Statement> initializePropertyMetaModelsStatements = metaModelCoid.getMethodsByName("initializePropertyMetaModels").get(0).getBody().get().getStatements();
+        final NodeList<Statement> initializeConstructorParametersStatements = metaModelCoid.getMethodsByName("initializeConstructorParameters").get(0).getBody().get().getStatements();
+        initializeNodeMetaModelsStatements.clear();
+        initializePropertyMetaModelsStatements.clear();
+        initializeConstructorParametersStatements.clear();
+
+        metaModelCoid.getFields().stream().filter(f -> f.getVariable(0).getNameAsString().endsWith("MetaModel")).forEach(Node::remove);
+        final NodeMetaModelGenerator nodeMetaModelGenerator = new NodeMetaModelGenerator();
+        for (Class<? extends Node> nodeClass : ALL_NODE_CLASSES) {
+            nodeMetaModelGenerator.generate(nodeClass, metaModelCoid, initializeNodeMetaModelsStatements, initializePropertyMetaModelsStatements, initializeConstructorParametersStatements, sourceRoot);
+        }
+
+        initializeNodeMetaModelsStatements.sort(Comparator.comparing(Node::toString));
+    }
+
+    static boolean isNode(Class<?> c) {
+        return Node.class.isAssignableFrom(c);
+    }
+
+    static String nodeMetaModelName(Class<?> c) {
+        return c.getSimpleName() + "MetaModel";
+    }
+
+    static String propertyMetaModelFieldName(Field field) {
+        return field.getName() + "PropertyMetaModel";
+    }
+
+    static String nodeMetaModelFieldName(Class<?> nodeClass) {
+        return decapitalize(nodeMetaModelName(nodeClass));
+    }
+
+}
diff --git a/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/NodeMetaModelGenerator.java b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/NodeMetaModelGenerator.java
new file mode 100644
index 0000000..96f92ab
--- /dev/null
+++ b/javaparser-metamodel-generator/src/main/java/com/github/javaparser/generator/metamodel/NodeMetaModelGenerator.java
@@ -0,0 +1,117 @@
+package com.github.javaparser.generator.metamodel;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.metamodel.DerivedProperty;
+import com.github.javaparser.metamodel.InternalProperty;
+import com.github.javaparser.utils.SourceRoot;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.ast.Modifier.*;
+import static com.github.javaparser.generator.metamodel.MetaModelGenerator.*;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.CodeGenerationUtils.optionalOf;
+import static com.github.javaparser.utils.Utils.decapitalize;
+
+public class NodeMetaModelGenerator {
+    private final InitializePropertyMetaModelsStatementsGenerator initializePropertyMetaModelsStatementsGenerator = new InitializePropertyMetaModelsStatementsGenerator();
+    private final InitializeConstructorParametersStatementsGenerator initializeConstructorParametersStatementsGenerator = new InitializeConstructorParametersStatementsGenerator();
+
+    public void generate(Class<? extends Node> nodeClass, ClassOrInterfaceDeclaration metaModelCoid, NodeList<Statement> initializeNodeMetaModelsStatements, NodeList<Statement> initializePropertyMetaModelsStatements, NodeList<Statement> initializeConstructorParametersStatements, SourceRoot sourceRoot) throws NoSuchMethodException {
+        final String className = nodeMetaModelName(nodeClass);
+        final String nodeMetaModelFieldName = decapitalize(className);
+        metaModelCoid.getFieldByName(nodeMetaModelFieldName).ifPresent(Node::remove);
+
+        final FieldDeclaration nodeField = metaModelCoid.addField(className, nodeMetaModelFieldName, PUBLIC, STATIC, FINAL);
+
+        final Class<?> superclass = nodeClass.getSuperclass();
+        final String superNodeMetaModel = nodeMetaModelName(superclass);
+
+        boolean isRootNode = !isNode(superclass);
+        nodeField.getVariable(0).setInitializer(parseExpression(f("new %s(%s)",
+                className,
+                optionalOf(decapitalize(superNodeMetaModel), !isRootNode))));
+
+        initializeNodeMetaModelsStatements.add(parseStatement(f("nodeMetaModels.add(%s);", nodeMetaModelFieldName)));
+
+        final CompilationUnit classMetaModelJavaFile = new CompilationUnit(METAMODEL_PACKAGE);
+        classMetaModelJavaFile.addImport("java.util.Optional");
+        sourceRoot.add(METAMODEL_PACKAGE, className + ".java", classMetaModelJavaFile);
+        final ClassOrInterfaceDeclaration nodeMetaModelClass = classMetaModelJavaFile.addClass(className, PUBLIC);
+        if (isRootNode) {
+            nodeMetaModelClass.addExtendedType(BASE_NODE_META_MODEL);
+        } else {
+            nodeMetaModelClass.addExtendedType(superNodeMetaModel);
+        }
+
+        final AstTypeAnalysis typeAnalysis = new AstTypeAnalysis(nodeClass);
+
+        final ConstructorDeclaration classMMConstructor = nodeMetaModelClass
+                .addConstructor()
+                .addParameter("Optional<" + BASE_NODE_META_MODEL + ">", "super" + BASE_NODE_META_MODEL);
+        classMMConstructor
+                .getBody()
+                .addStatement(parseExplicitConstructorInvocationStmt(f("super(super%s, %s.class, \"%s\", \"%s\", %s, %s);",
+                        BASE_NODE_META_MODEL,
+                        nodeClass.getName(),
+                        nodeClass.getSimpleName(),
+                        nodeClass.getPackage().getName(),
+                        typeAnalysis.isAbstract,
+                        typeAnalysis.isSelfType)));
+
+        if (typeAnalysis.isAbstract) {
+            classMetaModelJavaFile.addImport(Node.class);
+            nodeMetaModelClass.addMember(parseBodyDeclaration(f(
+                    "protected %s(Optional<BaseNodeMetaModel> superNodeMetaModel, Class<? extends Node> type, String name, String packageName, boolean isAbstract, boolean hasWildcard) {" +
+                            "super(superNodeMetaModel, type, name, packageName, isAbstract, hasWildcard);" +
+                            " }",
+                    className)));
+        }
+
+        final List<Field> fields = new ArrayList<>(Arrays.asList(nodeClass.getDeclaredFields()));
+        fields.sort(Comparator.comparing(Field::getName));
+        for (Field field : fields) {
+            if (fieldShouldBeIgnored(field)) {
+                continue;
+            }
+
+            initializePropertyMetaModelsStatementsGenerator.generate(field, nodeMetaModelClass, nodeMetaModelFieldName, initializePropertyMetaModelsStatements);
+        }
+        final List<Method> methods = new ArrayList<>(Arrays.asList(nodeClass.getMethods()));
+        methods.sort(Comparator.comparing(Method::getName));
+        for (Method method : methods) {
+            if (method.isAnnotationPresent(DerivedProperty.class)) {
+                initializePropertyMetaModelsStatementsGenerator.generateDerivedProperty(method, nodeMetaModelClass, nodeMetaModelFieldName, initializePropertyMetaModelsStatements);
+            }
+        }
+
+        initializeConstructorParametersStatementsGenerator.generate(nodeClass, initializeConstructorParametersStatements);
+
+        moveStaticInitializeToTheEndOfTheClassBecauseWeNeedTheFieldsToInitializeFirst(metaModelCoid);
+    }
+
+    private void moveStaticInitializeToTheEndOfTheClassBecauseWeNeedTheFieldsToInitializeFirst(ClassOrInterfaceDeclaration metaModelCoid) {
+        for (BodyDeclaration<?> m : metaModelCoid.getMembers()) {
+            if (m instanceof InitializerDeclaration) {
+                m.remove();
+                metaModelCoid.addMember(m);
+                return;
+            }
+        }
+    }
+
+    private boolean fieldShouldBeIgnored(Field reflectionField) {
+        return java.lang.reflect.Modifier.isStatic(reflectionField.getModifiers()) ||
+                reflectionField.isAnnotationPresent(InternalProperty.class);
+    }
+}
diff --git a/javaparser-parent.iml b/javaparser-parent.iml
new file mode 100644
index 0000000..880f417
--- /dev/null
+++ b/javaparser-parent.iml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="Osmorc" name="OSGi">
+      <configuration manifestGenerationMode="Manually" manifestLocation="javaparser-bdd-testing/target/classes/META-INF/MANIFEST.MF" jarfileLocation="javaparser-parent.jar" outputPathType="CompilerOutputPath" bndFileLocation="" bundlorFileLocation="" bundleActivator="" bundleSymbolicName="" bundleVersion="1.0.0" ignoreFilePattern="" useProjectDefaultManifestFileLocation="false" alwaysRebuildBundleJAR="false" doNotSynchronizeWithMaven="false">
+        <additionalProperties />
+        <additionalJARContents />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-symbol-solver-core/.gitignore b/javaparser-symbol-solver-core/.gitignore
new file mode 100644
index 0000000..b114bf5
--- /dev/null
+++ b/javaparser-symbol-solver-core/.gitignore
@@ -0,0 +1,5 @@
+target
+build
+/.classpath
+/.project
+.settings
diff --git a/javaparser-symbol-solver-core/javaparser-symbol-solver-core.iml b/javaparser-symbol-solver-core/javaparser-symbol-solver-core.iml
new file mode 100644
index 0000000..b1e3807
--- /dev/null
+++ b/javaparser-symbol-solver-core/javaparser-symbol-solver-core.iml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="javaparser-symbol-solver-logic" />
+    <orderEntry type="library" name="Maven: org.javassist:javassist:3.22.0-GA" level="project" />
+    <orderEntry type="module" module-name="javaparser-symbol-solver-model" />
+    <orderEntry type="module" module-name="javaparser-core" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:23.4-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.0.18" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-symbol-solver-core/pom.xml b/javaparser-symbol-solver-core/pom.xml
new file mode 100644
index 0000000..97ff664
--- /dev/null
+++ b/javaparser-symbol-solver-core/pom.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+      <artifactId>javaparser-parent</artifactId>
+      <groupId>com.github.javaparser</groupId>
+      <version>3.5.16-SNAPSHOT</version>
+  </parent>    
+  <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-symbol-solver-core</artifactId>
+    <packaging>jar</packaging>
+    <description>A Symbol Solver for Java, built on top of JavaParser (core)</description>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
+            <distribution>repo</distribution>
+        </license>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <build.timestamp>${maven.build.timestamp}</build.timestamp>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-symbol-solver-logic</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-symbol-solver-model</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>animal-sniffer-maven-plugin</artifactId>
+                <configuration>
+                    <signature>
+                        <!-- Make sure only the API of this JDK is used -->
+                        <groupId>org.codehaus.mojo.signature</groupId>
+                        <artifactId>java18</artifactId>
+                        <version>1.0</version>
+                    </signature>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>animal-sniffer</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>enforce-versions</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <!-- Make sure a compiler of this version is used -->
+                                    <version>${java.version}</version>
+                                </requireJavaVersion>
+                                <enforceBytecodeVersion>
+                                    <!-- Make sure the dependencies are compiled for our Java version -->
+                                    <maxJdkVersion>${java.version}</maxJdkVersion>
+                                </enforceBytecodeVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>extra-enforcer-rules</artifactId>
+                        <version>1.0-beta-6</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <!-- Set JPMS module name -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Automatic-Module-Name>com.github.javaparser.symbolsolver.core</Automatic-Module-Name>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java
new file mode 100644
index 0000000..77550c7
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/JavaSymbolSolver.java
@@ -0,0 +1,184 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.resolution.SymbolResolver;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.*;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * This implementation of the SymbolResolver wraps the functionalities of the library to make them easily usable
+ * from JavaParser nodes.
+ *
+ * An instance of this class should be created once and then injected in all the CompilationUnit for which we
+ * want to enable symbol resolution. To do so the method inject can be used.
+ *
+ * @author Federico Tomassetti
+ */
+public class JavaSymbolSolver implements SymbolResolver {
+
+    private TypeSolver typeSolver;
+
+    public JavaSymbolSolver(TypeSolver typeSolver) {
+        this.typeSolver = typeSolver;
+    }
+
+    /**
+     * Register this SymbolResolver into a CompilationUnit, so that symbol resolution becomes available to
+     * all nodes part of the CompilationUnit.
+     */
+    public void inject(CompilationUnit destination) {
+        destination.setData(Node.SYMBOL_RESOLVER_KEY, this);
+    }
+
+    @Override
+    public <T> T resolveDeclaration(Node node, Class<T> resultClass) {
+        if (node instanceof MethodDeclaration) {
+            return resultClass.cast(new JavaParserMethodDeclaration((MethodDeclaration)node, typeSolver));
+        }
+        if (node instanceof ClassOrInterfaceDeclaration) {
+            ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver);
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof EnumDeclaration) {
+            ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver);
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof EnumConstantDeclaration) {
+            ResolvedEnumDeclaration enumDeclaration = node.findParent(EnumDeclaration.class).get().resolve().asEnum();
+            ResolvedEnumConstantDeclaration resolved = enumDeclaration.getEnumConstants().stream().filter(c -> ((JavaParserEnumConstantDeclaration)c).getWrappedNode() == node).findFirst().get();
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof ConstructorDeclaration) {
+            ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)node;
+            ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration)node.getParentNode().get();
+            ResolvedClassDeclaration resolvedClass = resolveDeclaration(classOrInterfaceDeclaration, ResolvedClassDeclaration.class).asClass();
+            ResolvedConstructorDeclaration resolved =  resolvedClass.getConstructors().stream().filter(c -> ((JavaParserConstructorDeclaration)c).getWrappedNode() == constructorDeclaration).findFirst().get();
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof AnnotationDeclaration) {
+            ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver);
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof AnnotationMemberDeclaration) {
+            ResolvedAnnotationDeclaration annotationDeclaration = node.findParent(AnnotationDeclaration.class).get().resolve();
+            ResolvedAnnotationMemberDeclaration resolved = annotationDeclaration.getAnnotationMembers().stream().filter(c -> ((JavaParserAnnotationMemberDeclaration)c).getWrappedNode() == node).findFirst().get();
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof FieldDeclaration) {
+            FieldDeclaration fieldDeclaration = (FieldDeclaration)node;
+            if (fieldDeclaration.getVariables().size() != 1) {
+                throw new RuntimeException("Cannot resolve a Field Declaration including multiple variable declarators. Resolve the single variable declarators");
+            }
+            ResolvedFieldDeclaration resolved = new JavaParserFieldDeclaration(fieldDeclaration.getVariable(0), typeSolver);
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof VariableDeclarator) {
+            ResolvedFieldDeclaration resolved = new JavaParserFieldDeclaration((VariableDeclarator)node, typeSolver);
+            if (resultClass.isInstance(resolved)) {
+                return resultClass.cast(resolved);
+            }
+        }
+        if (node instanceof MethodCallExpr) {
+            SymbolReference<ResolvedMethodDeclaration> result = JavaParserFacade.get(typeSolver).solve((MethodCallExpr)node);
+            if (result.isSolved()) {
+                if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
+                    return resultClass.cast(result.getCorrespondingDeclaration());
+                }
+            } else {
+                throw new UnsolvedSymbolException("We are unable to find the method declaration corresponding to " + node);
+            }
+        }
+        if (node instanceof NameExpr) {
+            SymbolReference<? extends ResolvedValueDeclaration> result = JavaParserFacade.get(typeSolver).solve((NameExpr) node);
+            if (result.isSolved()) {
+                if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
+                    return resultClass.cast(result.getCorrespondingDeclaration());
+                }
+            } else {
+                throw new UnsolvedSymbolException("We are unable to find the value declaration corresponding to " + node);
+            }
+        }
+        if (node instanceof ThisExpr) {
+            SymbolReference<ResolvedTypeDeclaration> result = JavaParserFacade.get(typeSolver).solve((ThisExpr) node);
+            if (result.isSolved()) {
+                if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
+                    return resultClass.cast(result.getCorrespondingDeclaration());
+                }
+            } else {
+                throw new UnsolvedSymbolException("We are unable to find the type declaration corresponding to " + node);
+            }
+        }
+        if (node instanceof ExplicitConstructorInvocationStmt) {
+            SymbolReference<ResolvedConstructorDeclaration> result = JavaParserFacade.get(typeSolver).solve((ExplicitConstructorInvocationStmt) node);
+            if (result.isSolved()) {
+                if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
+                    return resultClass.cast(result.getCorrespondingDeclaration());
+                }
+            } else {
+                throw new UnsolvedSymbolException("We are unable to find the constructor declaration corresponding to " + node);
+            }
+        }
+        if (node instanceof Parameter) {
+            if (ResolvedParameterDeclaration.class.equals(resultClass)) {
+                Parameter parameter = (Parameter)node;
+                CallableDeclaration callableDeclaration = node.findParent(CallableDeclaration.class).get();
+                ResolvedMethodLikeDeclaration resolvedMethodLikeDeclaration;
+                if (callableDeclaration.isConstructorDeclaration()) {
+                    resolvedMethodLikeDeclaration = callableDeclaration.asConstructorDeclaration().resolve();
+                } else {
+                    resolvedMethodLikeDeclaration = callableDeclaration.asMethodDeclaration().resolve();
+                }
+                for (int i=0;i<resolvedMethodLikeDeclaration.getNumberOfParams();i++) {
+                    if (resolvedMethodLikeDeclaration.getParam(i).getName().equals(parameter.getNameAsString())) {
+                        return resultClass.cast(resolvedMethodLikeDeclaration.getParam(i));
+                    }
+                }
+            }
+        }
+        throw new UnsupportedOperationException("Unable to find the declaration of type " + resultClass.getSimpleName()
+                + " from " + node.getClass().getSimpleName());
+    }
+
+    @Override
+    public <T> T toResolvedType(Type javaparserType, Class<T> resultClass) {
+        ResolvedType resolvedType = JavaParserFacade.get(typeSolver).convertToUsage(javaparserType, javaparserType);
+        if (resultClass.isInstance(resolvedType)) {
+            return resultClass.cast(resolvedType);
+        }
+        throw new UnsupportedOperationException("Unable to get the resolved type of class "
+                + resultClass.getSimpleName() + " from " + javaparserType);
+    }
+
+    @Override
+    public ResolvedType calculateType(Expression expression) {
+        return JavaParserFacade.get(typeSolver).getType(expression);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java
new file mode 100644
index 0000000..8d2c07b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/SourceFileInfoExtractor.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * It prints information extracted from a source file. It is mainly intended as an example usage of JavaSymbolSolver.
+ *
+ * @author Federico Tomassetti
+ */
+public class SourceFileInfoExtractor {
+
+    private TypeSolver typeSolver;
+
+    private int ok = 0;
+    private int ko = 0;
+    private int unsupported = 0;
+    private boolean printFileName = true;
+    private PrintStream out = System.out;
+    private PrintStream err = System.err;
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    private boolean verbose = false;
+
+    public void setPrintFileName(boolean printFileName) {
+        this.printFileName = printFileName;
+    }
+
+    public void clear() {
+        ok = 0;
+        ko = 0;
+        unsupported = 0;
+    }
+
+    public void setOut(PrintStream out) {
+        this.out = out;
+    }
+
+    public void setErr(PrintStream err) {
+        this.err = err;
+    }
+
+    public int getOk() {
+        return ok;
+
+    }
+
+    public int getUnsupported() {
+        return unsupported;
+    }
+
+    public int getKo() {
+        return ko;
+    }
+
+    private void solveTypeDecl(ClassOrInterfaceDeclaration node) {
+        ResolvedTypeDeclaration typeDeclaration = JavaParserFacade.get(typeSolver).getTypeDeclaration(node);
+        if (typeDeclaration.isClass()) {
+            out.println("\n[ Class " + typeDeclaration.getQualifiedName() + " ]");
+            for (ResolvedReferenceType sc : typeDeclaration.asClass().getAllSuperClasses()) {
+                out.println("  superclass: " + sc.getQualifiedName());
+            }
+            for (ResolvedReferenceType sc : typeDeclaration.asClass().getAllInterfaces()) {
+                out.println("  interface: " + sc.getQualifiedName());
+            }
+        }
+    }
+
+    private void solve(Node node) {
+        if (node instanceof ClassOrInterfaceDeclaration) {
+            solveTypeDecl((ClassOrInterfaceDeclaration) node);
+        } else if (node instanceof Expression) {
+            if ((requireParentNode(node) instanceof ImportDeclaration) || (requireParentNode(node) instanceof Expression)
+                    || (requireParentNode(node) instanceof MethodDeclaration)
+                    || (requireParentNode(node) instanceof PackageDeclaration)) {
+                // skip
+            } else if ((requireParentNode(node) instanceof Statement) || (requireParentNode(node) instanceof VariableDeclarator)) {
+                try {
+                    ResolvedType ref = JavaParserFacade.get(typeSolver).getType(node);
+                    out.println("  Line " + node.getRange().get().begin.line + ") " + node + " ==> " + ref.describe());
+                    ok++;
+                } catch (UnsupportedOperationException upe) {
+                    unsupported++;
+                    err.println(upe.getMessage());
+                    throw upe;
+                } catch (RuntimeException re) {
+                    ko++;
+                    err.println(re.getMessage());
+                    throw re;
+                }
+            }
+        }
+    }
+
+    private void solveMethodCalls(Node node) {
+        if (node instanceof MethodCallExpr) {
+            out.println("  Line " + node.getBegin().get().line + ") " + node + " ==> " + toString((MethodCallExpr) node));
+        }
+        for (Node child : node.getChildNodes()) {
+            solveMethodCalls(child);
+        }
+    }
+
+    private String toString(MethodCallExpr node) {
+        try {
+            return toString(JavaParserFacade.get(typeSolver).solve(node));
+        } catch (Exception e) {
+            if (verbose) {
+                System.err.println("Error resolving call at L" + node.getBegin().get().line + ": " + node);
+                e.printStackTrace();
+            }
+            return "ERROR";
+        }
+    }
+
+    private String toString(SymbolReference<ResolvedMethodDeclaration> methodDeclarationSymbolReference) {
+        if (methodDeclarationSymbolReference.isSolved()) {
+            return methodDeclarationSymbolReference.getCorrespondingDeclaration().getQualifiedSignature();
+        } else {
+            return "UNSOLVED";
+        }
+    }
+
+    private List<Node> collectAllNodes(Node node) {
+        List<Node> nodes = new LinkedList<>();
+        collectAllNodes(node, nodes);
+        nodes.sort((n1, n2) -> n1.getBegin().get().compareTo(n2.getBegin().get()));
+        return nodes;
+    }
+
+    private void collectAllNodes(Node node, List<Node> nodes) {
+        nodes.add(node);
+        node.getChildNodes().forEach(c -> collectAllNodes(c, nodes));
+    }
+
+    public void solve(File file) throws IOException, ParseException {
+        if (file.isDirectory()) {
+            for (File f : file.listFiles()) {
+                solve(f);
+            }
+        } else {
+            if (file.getName().endsWith(".java")) {
+                if (printFileName) {
+                    out.println("- parsing " + file.getAbsolutePath());
+                }
+                CompilationUnit cu = JavaParser.parse(file);
+                List<Node> nodes = collectAllNodes(cu);
+                nodes.forEach(n -> solve(n));
+            }
+        }
+    }
+
+    public void solveMethodCalls(File file) throws IOException, ParseException {
+        if (file.isDirectory()) {
+            for (File f : file.listFiles()) {
+                solveMethodCalls(f);
+            }
+        } else {
+            if (file.getName().endsWith(".java")) {
+                if (printFileName) {
+                    out.println("- parsing " + file.getAbsolutePath());
+                }
+                CompilationUnit cu = JavaParser.parse(file);
+                solveMethodCalls(cu);
+            }
+        }
+    }
+
+    public void setTypeSolver(TypeSolver typeSolver) {
+        this.typeSolver = typeSolver;
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/Context.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/Context.java
new file mode 100644
index 0000000..93b754b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/Context.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.core.resolution;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Context is very similar to scope.
+ * In the context we look for solving symbols.
+ *
+ * @author Federico Tomassetti
+ */
+public interface Context {
+
+    Context getParent();
+
+    /* Type resolution */
+
+    default Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+        return Optional.empty();
+    }
+
+    default SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        Context parent = getParent();
+        if (parent == null) {
+            return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+        } else {
+            return parent.solveType(name, typeSolver);
+        }
+    }
+
+    /* Symbol resolution */
+
+    SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver);
+
+    default Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        SymbolReference<? extends ResolvedValueDeclaration> ref = solveSymbol(name, typeSolver);
+        if (ref.isSolved()) {
+            Value value = Value.from(ref.getCorrespondingDeclaration());
+            return Optional.of(value);
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    /* Constructor resolution */
+
+    /**
+     * We find the method declaration which is the best match for the given name and list of typeParametersValues.
+     */
+    default SymbolReference<ResolvedConstructorDeclaration> solveConstructor(List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        throw new IllegalArgumentException("Constructor resolution is available only on Class Context");
+    }
+
+    /* Methods resolution */
+
+    /**
+     * We find the method declaration which is the best match for the given name and list of typeParametersValues.
+     */
+    SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver);
+
+    /**
+     * Similar to solveMethod but we return a MethodUsage. A MethodUsage corresponds to a MethodDeclaration plus the
+     * resolved type variables.
+     */
+    default Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        SymbolReference<ResolvedMethodDeclaration> methodSolved = solveMethod(name, argumentsTypes, false, typeSolver);
+        if (methodSolved.isSolved()) {
+            ResolvedMethodDeclaration methodDeclaration = methodSolved.getCorrespondingDeclaration();
+            MethodUsage methodUsage = ContextHelper.resolveTypeVariables(this, methodDeclaration, argumentsTypes);//methodDeclaration.resolveTypeVariables(this, argumentsTypes);
+            return Optional.of(methodUsage);
+        } else {
+            return Optional.empty();
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/ContextHelper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/ContextHelper.java
new file mode 100644
index 0000000..f314052
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/core/resolution/ContextHelper.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.core.resolution;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistMethodDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodDeclaration;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+class ContextHelper {
+
+    private ContextHelper() {
+        // prevent instantiation
+    }
+
+    static MethodUsage resolveTypeVariables(Context context, ResolvedMethodDeclaration methodDeclaration, List<ResolvedType> parameterTypes) {
+        if (methodDeclaration instanceof JavaParserMethodDeclaration) {
+            return ((JavaParserMethodDeclaration) methodDeclaration).resolveTypeVariables(context, parameterTypes);
+        } else if (methodDeclaration instanceof JavassistMethodDeclaration) {
+            return ((JavassistMethodDeclaration) methodDeclaration).resolveTypeVariables(context, parameterTypes);
+        } else if (methodDeclaration instanceof JavaParserEnumDeclaration.ValuesMethod) {
+            return ((JavaParserEnumDeclaration.ValuesMethod) methodDeclaration).resolveTypeVariables(context, parameterTypes);
+        } else if (methodDeclaration instanceof ReflectionMethodDeclaration) {
+            return ((ReflectionMethodDeclaration) methodDeclaration).resolveTypeVariables(context, parameterTypes);
+        } else {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java
new file mode 100644
index 0000000..5d00635
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.declarations.common;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.logic.InferenceContext;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class MethodDeclarationCommonLogic {
+
+    private ResolvedMethodDeclaration methodDeclaration;
+    private TypeSolver typeSolver;
+
+    public MethodDeclarationCommonLogic(ResolvedMethodDeclaration methodDeclaration, TypeSolver typeSolver) {
+        this.methodDeclaration = methodDeclaration;
+        this.typeSolver = typeSolver;
+    }
+
+    public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
+        ResolvedType returnType = replaceTypeParams(methodDeclaration.getReturnType(), typeSolver, context);
+        List<ResolvedType> params = new ArrayList<>();
+        for (int i = 0; i < methodDeclaration.getNumberOfParams(); i++) {
+            ResolvedType replaced = replaceTypeParams(methodDeclaration.getParam(i).getType(), typeSolver, context);
+            params.add(replaced);
+        }
+
+        // We now look at the type parameter for the method which we can derive from the parameter types
+        // and then we replace them in the return type
+        // Map<TypeParameterDeclaration, Type> determinedTypeParameters = new HashMap<>();
+        InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
+        for (int i = 0; i < methodDeclaration.getNumberOfParams() - (methodDeclaration.hasVariadicParameter() ? 1 : 0); i++) {
+            ResolvedType formalParamType = methodDeclaration.getParam(i).getType();
+            ResolvedType actualParamType = parameterTypes.get(i);
+            inferenceContext.addPair(formalParamType, actualParamType);
+        }
+
+        returnType = inferenceContext.resolve(inferenceContext.addSingle(returnType));
+
+        return new MethodUsage(methodDeclaration, params, returnType);
+    }
+
+    private ResolvedType replaceTypeParams(ResolvedType type, TypeSolver typeSolver, Context context) {
+        if (type.isTypeVariable()) {
+            ResolvedTypeParameterDeclaration typeParameter = type.asTypeParameter();
+            if (typeParameter.declaredOnType()) {
+                Optional<ResolvedType> typeParam = typeParamByName(typeParameter.getName(), typeSolver, context);
+                if (typeParam.isPresent()) {
+                    type = typeParam.get();
+                }
+            }
+        }
+
+        if (type.isReferenceType()) {
+            type.asReferenceType().transformTypeParameters(tp -> replaceTypeParams(tp, typeSolver, context));
+        }
+
+        return type;
+    }
+
+    protected Optional<ResolvedType> typeParamByName(String name, TypeSolver typeSolver, Context context) {
+        return methodDeclaration.getTypeParameters().stream().filter(tp -> tp.getName().equals(name)).map(tp -> toType(tp)).findFirst();
+    }
+
+    protected ResolvedType toType(ResolvedTypeParameterDeclaration typeParameterDeclaration) {
+        return new ResolvedTypeVariable(typeParameterDeclaration);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/Navigator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/Navigator.java
new file mode 100644
index 0000000..dc3ea62
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/Navigator.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * This class can be used to easily retrieve nodes from a JavaParser AST.
+ *
+ * @author Federico Tomassetti
+ */
+public final class Navigator {
+
+    private Navigator() {
+        // prevent instantiation
+    }
+
+    /**
+     * @deprecated use Node.getParentNode
+     */
+    @Deprecated
+    public static Node getParentNode(Node node) {
+        return node.getParentNode().orElse(null);
+    }
+
+    public static Node requireParentNode(Node node) {
+        return node.getParentNode().orElseThrow(() -> new IllegalStateException("Parent not found, the node does not appear to be inserted in a correct AST"));
+    }
+
+    public static Optional<TypeDeclaration<?>> findType(CompilationUnit cu, String qualifiedName) {
+        if (cu.getTypes().isEmpty()) {
+            return Optional.empty();
+        }
+
+        final String typeName = getOuterTypeName(qualifiedName);
+        Optional<TypeDeclaration<?>> type = cu.getTypes().stream().filter((t) -> t.getName().getId().equals(typeName)).findFirst();
+
+        final String innerTypeName = getInnerTypeName(qualifiedName);
+        if (type.isPresent() && !innerTypeName.isEmpty()) {
+            return findType(type.get(), innerTypeName);
+        }
+        return type;
+    }
+
+    public static Optional<TypeDeclaration<?>> findType(TypeDeclaration<?> td, String qualifiedName) {
+        final String typeName = getOuterTypeName(qualifiedName);
+
+        Optional<TypeDeclaration<?>> type = Optional.empty();
+        for (Node n : td.getMembers()) {
+            if (n instanceof TypeDeclaration && ((TypeDeclaration<?>) n).getName().getId().equals(typeName)) {
+                type = Optional.of((TypeDeclaration<?>) n);
+                break;
+            }
+        }
+        final String innerTypeName = getInnerTypeName(qualifiedName);
+        if (type.isPresent() && !innerTypeName.isEmpty()) {
+            return findType(type.get(), innerTypeName);
+        }
+        return type;
+    }
+
+    public static ClassOrInterfaceDeclaration demandClass(CompilationUnit cu, String qualifiedName) {
+        ClassOrInterfaceDeclaration cd = demandClassOrInterface(cu, qualifiedName);
+        if (cd.isInterface()) {
+            throw new IllegalStateException("Type is not a class");
+        }
+        return cd;
+    }
+
+    public static EnumDeclaration demandEnum(CompilationUnit cu, String qualifiedName) {
+        Optional<TypeDeclaration<?>> res = findType(cu, qualifiedName);
+        if (!res.isPresent()) {
+            throw new IllegalStateException("No type found");
+        }
+        if (!(res.get() instanceof EnumDeclaration)) {
+            throw new IllegalStateException("Type is not an enum");
+        }
+        return (EnumDeclaration) res.get();
+    }
+
+    public static MethodDeclaration demandMethod(TypeDeclaration<?> cd, String name) {
+        MethodDeclaration found = null;
+        for (BodyDeclaration<?> bd : cd.getMembers()) {
+            if (bd instanceof MethodDeclaration) {
+                MethodDeclaration md = (MethodDeclaration) bd;
+                if (md.getNameAsString().equals(name)) {
+                    if (found != null) {
+                        throw new IllegalStateException("Ambiguous getName");
+                    }
+                    found = md;
+                }
+            }
+        }
+        if (found == null) {
+            throw new IllegalStateException("No method called " + name);
+        }
+        return found;
+    }
+
+    public static VariableDeclarator demandField(ClassOrInterfaceDeclaration cd, String name) {
+        for (BodyDeclaration<?> bd : cd.getMembers()) {
+            if (bd instanceof FieldDeclaration) {
+                FieldDeclaration fd = (FieldDeclaration) bd;
+                for (VariableDeclarator vd : fd.getVariables()) {
+                    if (vd.getName().getId().equals(name)) {
+                        return vd;
+                    }
+                }
+            }
+        }
+        throw new IllegalStateException("No field with given name");
+    }
+
+    public static Optional<NameExpr> findNameExpression(Node node, String name) {
+        return node.findFirst(NameExpr.class, n -> n.getNameAsString().equals(name));
+    }
+
+    public static Optional<SimpleName> findSimpleName(Node node, String name) {
+        return node.findFirst(SimpleName.class, n -> n.asString().equals(name));
+    }
+
+
+    public static Optional<MethodCallExpr> findMethodCall(Node node, String methodName) {
+        return node.findFirst(MethodCallExpr.class, n -> n.getNameAsString().equals(methodName));
+    }
+
+    public static Optional<VariableDeclarator> demandVariableDeclaration(Node node, String name) {
+        return node.findFirst(VariableDeclarator.class, n -> n.getNameAsString().equals(name));
+    }
+
+    public static ClassOrInterfaceDeclaration demandClassOrInterface(CompilationUnit compilationUnit, String qualifiedName) {
+        return findType(compilationUnit, qualifiedName)
+                .map(res -> res.toClassOrInterfaceDeclaration().orElseThrow(() -> new IllegalStateException("Type is not a class or an interface, it is " + res.getClass().getCanonicalName())))
+                .orElseThrow(() -> new IllegalStateException("No type named '" + qualifiedName + "'found"));
+    }
+
+    // TODO should be demand or requireSwitch
+    public static SwitchStmt findSwitch(Node node) {
+        return findSwitchHelper(node).orElseThrow(IllegalArgumentException::new);
+    }
+
+    public static <N extends Node> N findNodeOfGivenClass(Node node, Class<N> clazz) {
+        return node.findFirst(clazz).orElseThrow(IllegalArgumentException::new);
+    }
+
+    /**
+     * @deprecated use Node.findAll instead
+     */
+    @Deprecated
+    public static <N extends Node> List<N> findAllNodesOfGivenClass(Node node, Class<N> clazz) {
+        return node.findAll(clazz);
+    }
+
+    // TODO should be demand or require...
+    public static ReturnStmt findReturnStmt(MethodDeclaration method) {
+        return findNodeOfGivenClass(method, ReturnStmt.class);
+    }
+
+    /**
+     * @deprecated use Node.findParent instead
+     */
+    @Deprecated
+    public static <N extends Node> Optional<N> findAncestor(Node node, Class<N> clazz) {
+        return node.findParent(clazz);
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private static String getOuterTypeName(String qualifiedName) {
+        return qualifiedName.split("\\.", 2)[0];
+    }
+
+    private static String getInnerTypeName(String qualifiedName) {
+        if (qualifiedName.contains(".")) {
+            return qualifiedName.split("\\.", 2)[1];
+        }
+        return "";
+    }
+
+    private static Optional<SwitchStmt> findSwitchHelper(Node node) {
+        // TODO can be replaced by findFirst with the correct algorithm.
+        if (node instanceof SwitchStmt) {
+            return Optional.of((SwitchStmt) node);
+        }
+        for (Node child : node.getChildNodes()) {
+            Optional<SwitchStmt> resChild = findSwitchHelper(child);
+            if (resChild.isPresent()) {
+                return resChild;
+            }
+        }
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java
new file mode 100644
index 0000000..16ef202
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparser/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+/**
+ * This package contains utility to use JavaParser.
+ */
+package com.github.javaparser.symbolsolver.javaparser;
\ No newline at end of file
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java
new file mode 100644
index 0000000..499ef3b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter.java
@@ -0,0 +1,475 @@
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+public class DefaultVisitorAdapter implements GenericVisitor<ResolvedType, Boolean> {
+    @Override
+    public ResolvedType visit(CompilationUnit node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(PackageDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(TypeParameter node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(LineComment node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(BlockComment node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ClassOrInterfaceDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(EnumDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(EnumConstantDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(AnnotationDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(AnnotationMemberDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(FieldDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(VariableDeclarator node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ConstructorDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(MethodDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(Parameter node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(InitializerDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(JavadocComment node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ClassOrInterfaceType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(PrimitiveType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ArrayType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ArrayCreationLevel node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(IntersectionType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(UnionType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(VoidType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(WildcardType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(UnknownType node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ArrayAccessExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ArrayCreationExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ArrayInitializerExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(AssignExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(BinaryExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(CastExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ClassExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ConditionalExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(EnclosedExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(FieldAccessExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(InstanceOfExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(StringLiteralExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(IntegerLiteralExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(LongLiteralExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(CharLiteralExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(DoubleLiteralExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(BooleanLiteralExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(NullLiteralExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(MethodCallExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(NameExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ObjectCreationExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ThisExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(SuperExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(UnaryExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(VariableDeclarationExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(MarkerAnnotationExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(SingleMemberAnnotationExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(NormalAnnotationExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(MemberValuePair node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ExplicitConstructorInvocationStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(LocalClassDeclarationStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(AssertStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(BlockStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(LabeledStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(EmptyStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ExpressionStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(SwitchStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(SwitchEntryStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(BreakStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ReturnStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(IfStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(WhileStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ContinueStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(DoStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ForeachStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ForStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ThrowStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(SynchronizedStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(TryStmt node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(CatchClause node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(LambdaExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(MethodReferenceExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(TypeExpr node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(NodeList node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(Name node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(SimpleName node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ImportDeclaration node, Boolean aBoolean) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ModuleDeclaration node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ModuleRequiresStmt node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ModuleExportsStmt node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ModuleProvidesStmt node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ModuleUsesStmt node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ModuleOpensStmt node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(UnparsableStmt node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(ReceiverParameter node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(VarType node, Boolean arg) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java
new file mode 100644
index 0000000..f73dd98
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade.java
@@ -0,0 +1,562 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.FieldAccessContext;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.*;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.*;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * Class to be used by final users to solve symbols for JavaParser ASTs.
+ *
+ * @author Federico Tomassetti
+ */
+public class JavaParserFacade {
+
+    private static Logger logger = Logger.getLogger(JavaParserFacade.class.getCanonicalName());
+
+    static {
+        logger.setLevel(Level.INFO);
+        ConsoleHandler consoleHandler = new ConsoleHandler();
+        consoleHandler.setLevel(Level.INFO);
+        logger.addHandler(consoleHandler);
+    }
+
+    private static Map<TypeSolver, JavaParserFacade> instances = new WeakHashMap<>();
+    private TypeSolver typeSolver;
+    private SymbolSolver symbolSolver;
+    private Map<Node, ResolvedType> cacheWithLambdasSolved = new IdentityHashMap<>();
+    private Map<Node, ResolvedType> cacheWithoutLambdasSolved = new IdentityHashMap<>();
+    private TypeExtractor typeExtractor;
+
+    private JavaParserFacade(TypeSolver typeSolver) {
+        this.typeSolver = typeSolver.getRoot();
+        this.symbolSolver = new SymbolSolver(typeSolver);
+        this.typeExtractor = new TypeExtractor(typeSolver, this);
+    }
+
+    public TypeSolver getTypeSolver() {
+        return typeSolver;
+    }
+
+    public SymbolSolver getSymbolSolver() {
+        return symbolSolver;
+    }
+
+    public static JavaParserFacade get(TypeSolver typeSolver) {
+        return instances.computeIfAbsent(typeSolver, JavaParserFacade::new);
+    }
+
+    /**
+     * This method is used to clear internal caches for the sake of releasing memory.
+     */
+    public static void clearInstances() {
+        instances.clear();
+    }
+
+    protected static ResolvedType solveGenericTypes(ResolvedType type, Context context, TypeSolver typeSolver) {
+        if (type.isTypeVariable()) {
+            return context.solveGenericType(type.describe(), typeSolver).orElse(type);
+        }
+        if (type.isWildcard()) {
+            if (type.asWildcard().isExtends() || type.asWildcard().isSuper()) {
+                ResolvedWildcard wildcardUsage = type.asWildcard();
+                ResolvedType boundResolved = solveGenericTypes(wildcardUsage.getBoundedType(), context, typeSolver);
+                if (wildcardUsage.isExtends()) {
+                    return ResolvedWildcard.extendsBound(boundResolved);
+                } else {
+                    return ResolvedWildcard.superBound(boundResolved);
+                }
+            }
+        }
+        return type;
+    }
+
+    public SymbolReference<? extends ResolvedValueDeclaration> solve(NameExpr nameExpr) {
+        return symbolSolver.solveSymbol(nameExpr.getName().getId(), nameExpr);
+    }
+
+    public SymbolReference<? extends ResolvedValueDeclaration> solve(SimpleName nameExpr) {
+        return symbolSolver.solveSymbol(nameExpr.getId(), nameExpr);
+    }
+
+    public SymbolReference<? extends ResolvedValueDeclaration> solve(Expression expr) {
+        return expr.toNameExpr().map(this::solve).orElseThrow(() -> new IllegalArgumentException(expr.getClass().getCanonicalName()));
+    }
+
+    public SymbolReference<ResolvedMethodDeclaration> solve(MethodCallExpr methodCallExpr) {
+        return solve(methodCallExpr, true);
+    }
+
+    public SymbolReference<ResolvedConstructorDeclaration> solve(ObjectCreationExpr objectCreationExpr) {
+        return solve(objectCreationExpr, true);
+    }
+
+    public SymbolReference<ResolvedConstructorDeclaration> solve(ExplicitConstructorInvocationStmt explicitConstructorInvocationStmt) {
+        return solve(explicitConstructorInvocationStmt, true);
+    }
+
+    public SymbolReference<ResolvedConstructorDeclaration> solve(ExplicitConstructorInvocationStmt explicitConstructorInvocationStmt, boolean solveLambdas) {
+        List<ResolvedType> argumentTypes = new LinkedList<>();
+        List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();
+
+        solveArguments(explicitConstructorInvocationStmt, explicitConstructorInvocationStmt.getArguments(), solveLambdas, argumentTypes, placeholders);
+
+        Optional<ClassOrInterfaceDeclaration> optAncestor = explicitConstructorInvocationStmt.getAncestorOfType(ClassOrInterfaceDeclaration.class);
+        if (!optAncestor.isPresent()) {
+            return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+        }
+        ClassOrInterfaceDeclaration classNode = optAncestor.get();
+        ResolvedTypeDeclaration typeDecl = null;
+        if (!explicitConstructorInvocationStmt.isThis()) {
+            ResolvedType classDecl = JavaParserFacade.get(typeSolver).convert(classNode.getExtendedTypes(0), classNode);
+            if (classDecl.isReferenceType()) {
+                typeDecl = classDecl.asReferenceType().getTypeDeclaration();
+            }
+        } else {
+            SymbolReference<ResolvedTypeDeclaration> sr = JavaParserFactory.getContext(classNode, typeSolver).solveType(classNode.getNameAsString(), typeSolver);
+            if (sr.isSolved()) {
+                typeDecl = sr.getCorrespondingDeclaration();
+            }
+        }
+        if (typeDecl == null) {
+            return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+        }
+        SymbolReference<ResolvedConstructorDeclaration> res = ConstructorResolutionLogic.findMostApplicable(((ResolvedClassDeclaration) typeDecl).getConstructors(), argumentTypes, typeSolver);
+        for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
+            placeholder.setMethod(res);
+        }
+        return res;
+    }
+
+    public SymbolReference<ResolvedTypeDeclaration> solve(ThisExpr node) {
+        // If 'this' is prefixed by a class eg. MyClass.this
+        if (node.getClassExpr().isPresent()) {
+            // Get the class name
+            String className = node.getClassExpr().get().toString();
+            // Attempt to resolve using a typeSolver
+            SymbolReference<ResolvedReferenceTypeDeclaration> clazz = typeSolver.tryToSolveType(className);
+            if (clazz.isSolved()) {
+                return SymbolReference.solved(clazz.getCorrespondingDeclaration());
+            }
+            // Attempt to resolve locally in Compilation unit
+            Optional<CompilationUnit> cu = node.getAncestorOfType(CompilationUnit.class);
+            if (cu.isPresent()) {
+                Optional<ClassOrInterfaceDeclaration> classByName = cu.get().getClassByName(className);
+                if (classByName.isPresent()) {
+                    return SymbolReference.solved(getTypeDeclaration(classByName.get()));
+                }
+            }
+        }
+        return SymbolReference.solved(getTypeDeclaration(findContainingTypeDeclOrObjectCreationExpr(node)));
+    }
+
+    /**
+     * Given a constructor call find out to which constructor declaration it corresponds.
+     */
+    public SymbolReference<ResolvedConstructorDeclaration> solve(ObjectCreationExpr objectCreationExpr, boolean solveLambdas) {
+        List<ResolvedType> argumentTypes = new LinkedList<>();
+        List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();
+
+        solveArguments(objectCreationExpr, objectCreationExpr.getArguments(), solveLambdas, argumentTypes, placeholders);
+
+        ResolvedType classDecl = JavaParserFacade.get(typeSolver).convert(objectCreationExpr.getType(), objectCreationExpr);
+        if (!classDecl.isReferenceType()) {
+            return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+        }
+        SymbolReference<ResolvedConstructorDeclaration> res = ConstructorResolutionLogic.findMostApplicable(((ResolvedClassDeclaration) classDecl.asReferenceType().getTypeDeclaration()).getConstructors(), argumentTypes, typeSolver);
+        for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
+            placeholder.setMethod(res);
+        }
+        return res;
+    }
+
+    private void solveArguments(Node node, NodeList<Expression> args, boolean solveLambdas, List<ResolvedType> argumentTypes,
+                                List<LambdaArgumentTypePlaceholder> placeholders) {
+        int i = 0;
+        for (Expression parameterValue : args) {
+            if (parameterValue instanceof LambdaExpr || parameterValue instanceof MethodReferenceExpr) {
+                LambdaArgumentTypePlaceholder placeholder = new LambdaArgumentTypePlaceholder(i);
+                argumentTypes.add(placeholder);
+                placeholders.add(placeholder);
+            } else {
+                try {
+                    argumentTypes.add(JavaParserFacade.get(typeSolver).getType(parameterValue, solveLambdas));
+                } catch (com.github.javaparser.resolution.UnsolvedSymbolException e) {
+                    throw e;
+                } catch (Exception e) {
+                    throw new RuntimeException(String.format("Unable to calculate the type of a parameter of a method call. Method call: %s, Parameter: %s",
+                            node, parameterValue), e);
+                }
+            }
+            i++;
+        }
+    }
+
+    /**
+     * Given a method call find out to which method declaration it corresponds.
+     */
+    public SymbolReference<ResolvedMethodDeclaration> solve(MethodCallExpr methodCallExpr, boolean solveLambdas) {
+        List<ResolvedType> argumentTypes = new LinkedList<>();
+        List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();
+
+        solveArguments(methodCallExpr, methodCallExpr.getArguments(), solveLambdas, argumentTypes, placeholders);
+
+        SymbolReference<ResolvedMethodDeclaration> res = JavaParserFactory.getContext(methodCallExpr, typeSolver).solveMethod(methodCallExpr.getName().getId(), argumentTypes, false, typeSolver);
+        for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
+            placeholder.setMethod(res);
+        }
+        return res;
+    }
+
+    public SymbolReference<ResolvedAnnotationDeclaration> solve(AnnotationExpr annotationExpr) {
+        Context context = JavaParserFactory.getContext(annotationExpr, typeSolver);
+        SymbolReference<ResolvedTypeDeclaration> typeDeclarationSymbolReference = context.solveType(annotationExpr.getNameAsString(), typeSolver);
+        ResolvedAnnotationDeclaration annotationDeclaration = (ResolvedAnnotationDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration();
+        if (typeDeclarationSymbolReference.isSolved()) {
+            return SymbolReference.solved(annotationDeclaration);
+        } else {
+            return SymbolReference.unsolved(ResolvedAnnotationDeclaration.class);
+        }
+    }
+
+    public SymbolReference<ResolvedFieldDeclaration> solve(FieldAccessExpr fieldAccessExpr) {
+        return ((FieldAccessContext) JavaParserFactory.getContext(fieldAccessExpr, typeSolver)).solveField(fieldAccessExpr.getName().getId(), typeSolver);
+    }
+
+    public ResolvedType getType(Node node) {
+        return getType(node, true);
+    }
+
+    public ResolvedType getType(Node node, boolean solveLambdas) {
+        if (solveLambdas) {
+            if (!cacheWithLambdasSolved.containsKey(node)) {
+                ResolvedType res = getTypeConcrete(node, solveLambdas);
+
+                cacheWithLambdasSolved.put(node, res);
+
+                boolean secondPassNecessary = false;
+                if (node instanceof MethodCallExpr) {
+                    MethodCallExpr methodCallExpr = (MethodCallExpr) node;
+                    for (Node arg : methodCallExpr.getArguments()) {
+                        if (!cacheWithLambdasSolved.containsKey(arg)) {
+                            getType(arg, true);
+                            secondPassNecessary = true;
+                        }
+                    }
+                }
+                if (secondPassNecessary) {
+                    cacheWithLambdasSolved.remove(node);
+                    cacheWithLambdasSolved.put(node, getType(node, true));
+                }
+                logger.finer("getType on " + node + " -> " + res);
+            }
+            return cacheWithLambdasSolved.get(node);
+        } else {
+            Optional<ResolvedType> res = find(cacheWithLambdasSolved, node);
+            if (res.isPresent()) {
+                return res.get();
+            }
+            res = find(cacheWithoutLambdasSolved, node);
+            if (!res.isPresent()) {
+                ResolvedType resType = getTypeConcrete(node, solveLambdas);
+                cacheWithoutLambdasSolved.put(node, resType);
+                logger.finer("getType on " + node + " (no solveLambdas) -> " + res);
+                return resType;
+            }
+            return res.get();
+        }
+    }
+
+    private Optional<ResolvedType> find(Map<Node, ResolvedType> map, Node node) {
+        if (map.containsKey(node)) {
+            return Optional.of(map.get(node));
+        }
+        if (node instanceof LambdaExpr) {
+            return find(map, (LambdaExpr) node);
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    /**
+     * For some reasons LambdaExprs are duplicate and the equals method is not implemented correctly.
+     */
+    private Optional<ResolvedType> find(Map<Node, ResolvedType> map, LambdaExpr lambdaExpr) {
+        for (Node key : map.keySet()) {
+            if (key instanceof LambdaExpr) {
+                LambdaExpr keyLambdaExpr = (LambdaExpr) key;
+                if (keyLambdaExpr.toString().equals(lambdaExpr.toString()) && requireParentNode(keyLambdaExpr) == requireParentNode(lambdaExpr)) {
+                    return Optional.of(map.get(keyLambdaExpr));
+                }
+            }
+        }
+        return Optional.empty();
+    }
+
+    protected MethodUsage toMethodUsage(MethodReferenceExpr methodReferenceExpr) {
+        if (!(methodReferenceExpr.getScope() instanceof TypeExpr)) {
+            throw new UnsupportedOperationException();
+        }
+        TypeExpr typeExpr = (TypeExpr) methodReferenceExpr.getScope();
+        if (!(typeExpr.getType() instanceof com.github.javaparser.ast.type.ClassOrInterfaceType)) {
+            throw new UnsupportedOperationException(typeExpr.getType().getClass().getCanonicalName());
+        }
+        ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) typeExpr.getType();
+        SymbolReference<ResolvedTypeDeclaration> typeDeclarationSymbolReference = JavaParserFactory.getContext(classOrInterfaceType, typeSolver).solveType(classOrInterfaceType.getName().getId(), typeSolver);
+        if (!typeDeclarationSymbolReference.isSolved()) {
+            throw new UnsupportedOperationException();
+        }
+        List<MethodUsage> methodUsages = ((ResolvedReferenceTypeDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration()).getAllMethods().stream().filter(it -> it.getName().equals(methodReferenceExpr.getIdentifier())).collect(Collectors.toList());
+        switch (methodUsages.size()) {
+            case 0:
+                throw new UnsupportedOperationException();
+            case 1:
+                return methodUsages.get(0);
+            default:
+                throw new UnsupportedOperationException();
+        }
+    }
+
+    protected ResolvedType getBinaryTypeConcrete(Node left, Node right, boolean solveLambdas) {
+        ResolvedType leftType = getTypeConcrete(left, solveLambdas);
+        ResolvedType rightType = getTypeConcrete(right, solveLambdas);
+        if (rightType.isAssignableBy(leftType)) {
+            return rightType;
+        }
+        return leftType;
+    }
+
+
+    /**
+     * Should return more like a TypeApplication: a TypeDeclaration and possible typeParametersValues or array
+     * modifiers.
+     */
+    private ResolvedType getTypeConcrete(Node node, boolean solveLambdas) {
+        if (node == null) throw new IllegalArgumentException();
+        return node.accept(typeExtractor, solveLambdas);
+    }
+
+    protected com.github.javaparser.ast.body.TypeDeclaration<?> findContainingTypeDecl(Node node) {
+        if (node instanceof ClassOrInterfaceDeclaration) {
+            return (ClassOrInterfaceDeclaration) node;
+        }
+        if (node instanceof EnumDeclaration) {
+            return (EnumDeclaration) node;
+        }
+        return findContainingTypeDecl(requireParentNode(node));
+
+    }
+
+    protected Node findContainingTypeDeclOrObjectCreationExpr(Node node) {
+        if (node instanceof ClassOrInterfaceDeclaration) {
+            return node;
+        }
+        if (node instanceof EnumDeclaration) {
+            return node;
+        }
+        Node parent = requireParentNode(node);
+        if (parent instanceof ObjectCreationExpr && !((ObjectCreationExpr) parent).getArguments().contains(node)) {
+            return parent;
+        }
+        return findContainingTypeDeclOrObjectCreationExpr(parent);
+    }
+
+    public ResolvedType convertToUsageVariableType(VariableDeclarator var) {
+        return get(typeSolver).convertToUsage(var.getType(), var);
+    }
+
+    public ResolvedType convertToUsage(com.github.javaparser.ast.type.Type type, Node context) {
+        if (type.isUnknownType()) {
+            throw new IllegalArgumentException("Inferred lambda parameter type");
+        }
+        return convertToUsage(type, JavaParserFactory.getContext(context, typeSolver));
+    }
+
+    public ResolvedType convertToUsage(com.github.javaparser.ast.type.Type type) {
+        return convertToUsage(type, type);
+    }
+
+    // This is an hack around an issue in JavaParser
+    private String qName(ClassOrInterfaceType classOrInterfaceType) {
+        String name = classOrInterfaceType.getName().getId();
+        if (classOrInterfaceType.getScope().isPresent()) {
+            return qName(classOrInterfaceType.getScope().get()) + "." + name;
+        }
+        return name;
+    }
+
+    protected ResolvedType convertToUsage(com.github.javaparser.ast.type.Type type, Context context) {
+        if (context == null) {
+            throw new NullPointerException("Context should not be null");
+        }
+        if (type instanceof ClassOrInterfaceType) {
+            ClassOrInterfaceType classOrInterfaceType = (ClassOrInterfaceType) type;
+            String name = qName(classOrInterfaceType);
+            SymbolReference<ResolvedTypeDeclaration> ref = context.solveType(name, typeSolver);
+            if (!ref.isSolved()) {
+                throw new UnsolvedSymbolException(name);
+            }
+            ResolvedTypeDeclaration typeDeclaration = ref.getCorrespondingDeclaration();
+            List<ResolvedType> typeParameters = Collections.emptyList();
+            if (classOrInterfaceType.getTypeArguments().isPresent()) {
+                typeParameters = classOrInterfaceType.getTypeArguments().get().stream().map((pt) -> convertToUsage(pt, context)).collect(Collectors.toList());
+            }
+            if (typeDeclaration.isTypeParameter()) {
+                if (typeDeclaration instanceof ResolvedTypeParameterDeclaration) {
+                    return new ResolvedTypeVariable((ResolvedTypeParameterDeclaration) typeDeclaration);
+                } else {
+                    JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) typeDeclaration;
+                    return new ResolvedTypeVariable(javaParserTypeVariableDeclaration.asTypeParameter());
+                }
+            } else {
+                return new ReferenceTypeImpl((ResolvedReferenceTypeDeclaration) typeDeclaration, typeParameters, typeSolver);
+            }
+        } else if (type instanceof com.github.javaparser.ast.type.PrimitiveType) {
+            return ResolvedPrimitiveType.byName(((com.github.javaparser.ast.type.PrimitiveType) type).getType().name());
+        } else if (type instanceof WildcardType) {
+            WildcardType wildcardType = (WildcardType) type;
+            if (wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) {
+                return ResolvedWildcard.extendsBound(convertToUsage(wildcardType.getExtendedType().get(), context)); // removed (ReferenceTypeImpl)
+            } else if (!wildcardType.getExtendedType().isPresent() && wildcardType.getSuperType().isPresent()) {
+                return ResolvedWildcard.superBound(convertToUsage(wildcardType.getSuperType().get(), context)); // removed (ReferenceTypeImpl)
+            } else if (!wildcardType.getExtendedType().isPresent() && !wildcardType.getSuperType().isPresent()) {
+                return ResolvedWildcard.UNBOUNDED;
+            } else {
+                throw new UnsupportedOperationException(wildcardType.toString());
+            }
+        } else if (type instanceof com.github.javaparser.ast.type.VoidType) {
+            return ResolvedVoidType.INSTANCE;
+        } else if (type instanceof com.github.javaparser.ast.type.ArrayType) {
+            com.github.javaparser.ast.type.ArrayType jpArrayType = (com.github.javaparser.ast.type.ArrayType) type;
+            return new ResolvedArrayType(convertToUsage(jpArrayType.getComponentType(), context));
+        } else if (type instanceof UnionType) {
+            UnionType unionType = (UnionType) type;
+            return new ResolvedUnionType(unionType.getElements().stream().map(el -> convertToUsage(el, context)).collect(Collectors.toList()));
+        } else if (type instanceof VarType) {
+            Node parent = type.getParentNode().get();
+            if (!(parent instanceof VariableDeclarator)) {
+                throw new IllegalStateException("Trying to resolve a `var` which is not in a variable declaration.");
+            }
+            final VariableDeclarator variableDeclarator = (VariableDeclarator) parent;
+            return variableDeclarator.getInitializer()
+                    .map(Expression::calculateResolvedType)
+                    .orElseThrow(() -> new IllegalStateException("Cannot resolve `var` which has no initializer."));
+        } else {
+            throw new UnsupportedOperationException(type.getClass().getCanonicalName());
+        }
+    }
+
+
+    public ResolvedType convert(Type type, Node node) {
+        return convert(type, JavaParserFactory.getContext(node, typeSolver));
+    }
+
+    public ResolvedType convert(com.github.javaparser.ast.type.Type type, Context context) {
+        return convertToUsage(type, context);
+    }
+
+    public MethodUsage solveMethodAsUsage(MethodCallExpr call) {
+        List<ResolvedType> params = new ArrayList<>();
+        if (call.getArguments() != null) {
+            for (Expression param : call.getArguments()) {
+                //getTypeConcrete(Node node, boolean solveLambdas)
+                try {
+                    params.add(getType(param, false));
+                } catch (Exception e) {
+                    throw new RuntimeException(String.format("Error calculating the type of parameter %s of method call %s", param, call), e);
+                }
+                //params.add(getTypeConcrete(param, false));
+            }
+        }
+        Context context = JavaParserFactory.getContext(call, typeSolver);
+        Optional<MethodUsage> methodUsage = context.solveMethodAsUsage(call.getName().getId(), params, typeSolver);
+        if (!methodUsage.isPresent()) {
+            throw new RuntimeException("Method '" + call.getName() + "' cannot be resolved in context "
+                    + call + " (line: " + call.getRange().map(r -> "" + r.begin.line).orElse("??") + ") " + context + ". Parameter types: " + params);
+        }
+        return methodUsage.get();
+    }
+
+    public ResolvedReferenceTypeDeclaration getTypeDeclaration(Node node) {
+        if (node instanceof TypeDeclaration) {
+            return getTypeDeclaration((TypeDeclaration) node);
+        } else if (node instanceof ObjectCreationExpr) {
+            return new JavaParserAnonymousClassDeclaration((ObjectCreationExpr) node, typeSolver);
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    public ResolvedReferenceTypeDeclaration getTypeDeclaration(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) {
+        return JavaParserFactory.toTypeDeclaration(classOrInterfaceDeclaration, typeSolver);
+    }
+
+    /**
+     * "this" inserted in the given point, which type would have?
+     */
+    public ResolvedType getTypeOfThisIn(Node node) {
+        // TODO consider static methods
+        if (node instanceof ClassOrInterfaceDeclaration) {
+            return new ReferenceTypeImpl(getTypeDeclaration((ClassOrInterfaceDeclaration) node), typeSolver);
+        } else if (node instanceof EnumDeclaration) {
+            JavaParserEnumDeclaration enumDeclaration = new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver);
+            return new ReferenceTypeImpl(enumDeclaration, typeSolver);
+        } else if (node instanceof ObjectCreationExpr && ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) {
+            JavaParserAnonymousClassDeclaration anonymousDeclaration = new JavaParserAnonymousClassDeclaration((ObjectCreationExpr) node, typeSolver);
+            return new ReferenceTypeImpl(anonymousDeclaration, typeSolver);
+        }
+        return getTypeOfThisIn(requireParentNode(node));
+    }
+
+    public ResolvedReferenceTypeDeclaration getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?> typeDeclaration) {
+        return JavaParserFactory.toTypeDeclaration(typeDeclaration, typeSolver);
+    }
+
+    public ResolvedType classToResolvedType(Class<?> clazz) {
+        if (clazz.isPrimitive()) {
+            return ResolvedPrimitiveType.byName(clazz.getName());
+        }
+        return new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java
new file mode 100644
index 0000000..8bd3496
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.*;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.FieldSymbolDeclarator;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.NoSymbolDeclarator;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.ParameterSymbolDeclarator;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarators.VariableSymbolDeclarator;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserFactory {
+
+    public static Context getContext(Node node, TypeSolver typeSolver) {
+        if (node == null) {
+            throw new NullPointerException("Node should not be null");
+        } else if (node instanceof CompilationUnit) {
+            return new CompilationUnitContext((CompilationUnit) node, typeSolver);
+        } else if (node instanceof ForeachStmt) {
+            return new ForechStatementContext((ForeachStmt) node, typeSolver);
+        } else if (node instanceof ForStmt) {
+            return new ForStatementContext((ForStmt) node, typeSolver);
+        } else if (node instanceof LambdaExpr) {
+            return new LambdaExprContext((LambdaExpr) node, typeSolver);
+        } else if (node instanceof MethodDeclaration) {
+            return new MethodContext((MethodDeclaration) node, typeSolver);
+        } else if (node instanceof ConstructorDeclaration) {
+            return new ConstructorContext((ConstructorDeclaration) node, typeSolver);
+        } else if (node instanceof ClassOrInterfaceDeclaration) {
+            return new ClassOrInterfaceDeclarationContext((ClassOrInterfaceDeclaration) node, typeSolver);
+        } else if (node instanceof MethodCallExpr) {
+            return new MethodCallExprContext((MethodCallExpr) node, typeSolver);
+        } else if (node instanceof EnumDeclaration) {
+            return new EnumDeclarationContext((EnumDeclaration) node, typeSolver);
+        } else if (node instanceof FieldAccessExpr) {
+            return new FieldAccessContext((FieldAccessExpr) node, typeSolver);
+        } else if (node instanceof SwitchEntryStmt) {
+            return new SwitchEntryContext((SwitchEntryStmt) node, typeSolver);
+        } else if (node instanceof TryStmt) {
+            return new TryWithResourceContext((TryStmt) node, typeSolver);
+        } else if (node instanceof Statement) {
+            return new StatementContext<>((Statement) node, typeSolver);
+        } else if (node instanceof CatchClause) {
+            return new CatchClauseContext((CatchClause) node, typeSolver);
+        } else if (node instanceof ObjectCreationExpr &&
+            ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) {
+            return new AnonymousClassDeclarationContext((ObjectCreationExpr) node, typeSolver);
+        } else {
+            if (node instanceof NameExpr) {
+                // to resolve a name when in a fieldAccess context, we can get to the grand parent to prevent a infinite loop if the name is the same as the field (ie x.x)
+                if (node.getParentNode().isPresent() && node.getParentNode().get() instanceof FieldAccessExpr && node.getParentNode().get().getParentNode().isPresent()) {
+                    return getContext(node.getParentNode().get().getParentNode().get(), typeSolver);
+                }
+            }
+            final Node parentNode = requireParentNode(node);
+            if (parentNode instanceof ObjectCreationExpr && node == ((ObjectCreationExpr) parentNode).getType()) {
+                return getContext(requireParentNode(parentNode), typeSolver);
+            }
+            if (parentNode == null) {
+                throw new IllegalStateException("The AST node does not appear to be inserted in a propert AST, therefore we cannot resolve symbols correctly");
+            }
+            return getContext(parentNode, typeSolver);
+        }
+    }
+
+    public static SymbolDeclarator getSymbolDeclarator(Node node, TypeSolver typeSolver) {
+        if (node instanceof FieldDeclaration) {
+            return new FieldSymbolDeclarator((FieldDeclaration) node, typeSolver);
+        } else if (node instanceof Parameter) {
+            return new ParameterSymbolDeclarator((Parameter) node, typeSolver);
+        } else if (node instanceof ExpressionStmt) {
+            ExpressionStmt expressionStmt = (ExpressionStmt) node;
+            if (expressionStmt.getExpression() instanceof VariableDeclarationExpr) {
+                return new VariableSymbolDeclarator((VariableDeclarationExpr) (expressionStmt.getExpression()), typeSolver);
+            } else {
+                return new NoSymbolDeclarator<>(expressionStmt, typeSolver);
+            }
+        } else if (node instanceof IfStmt) {
+            return new NoSymbolDeclarator<>((IfStmt) node, typeSolver);
+        } else if (node instanceof ForeachStmt) {
+            ForeachStmt foreachStmt = (ForeachStmt) node;
+            return new VariableSymbolDeclarator(foreachStmt.getVariable(), typeSolver);
+        } else {
+            return new NoSymbolDeclarator<>(node, typeSolver);
+        }
+    }
+    
+    public static ResolvedReferenceTypeDeclaration toTypeDeclaration(Node node, TypeSolver typeSolver) {
+        if (node instanceof ClassOrInterfaceDeclaration) {
+            if (((ClassOrInterfaceDeclaration) node).isInterface()) {
+                return new JavaParserInterfaceDeclaration((ClassOrInterfaceDeclaration) node, typeSolver);
+            } else {
+                return new JavaParserClassDeclaration((ClassOrInterfaceDeclaration) node, typeSolver);
+            }
+        } else if (node instanceof TypeParameter) {
+            return new JavaParserTypeParameter((TypeParameter) node, typeSolver);
+        } else if (node instanceof EnumDeclaration) {
+            return new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver);
+        } else if (node instanceof AnnotationDeclaration) {
+            return new JavaParserAnnotationDeclaration((AnnotationDeclaration) node, typeSolver);
+        } else {
+            throw new IllegalArgumentException(node.getClass().getCanonicalName());
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java
new file mode 100644
index 0000000..c0e35bf
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+
+/**
+ * Placeholder used to represent a lambda argument type while it is being
+ * calculated.
+ *
+ * @author Federico Tomassetti
+ */
+public class LambdaArgumentTypePlaceholder implements ResolvedType {
+
+    private int pos;
+    private SymbolReference<? extends ResolvedMethodLikeDeclaration> method;
+
+    public LambdaArgumentTypePlaceholder(int pos) {
+        this.pos = pos;
+    }
+
+    @Override
+    public boolean isArray() {
+        return false;
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return false;
+    }
+
+    @Override
+    public boolean isReferenceType() {
+        return false;
+    }
+
+    @Override
+    public String describe() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isTypeVariable() {
+        return false;
+    }
+
+    public void setMethod(SymbolReference<? extends ResolvedMethodLikeDeclaration> method) {
+        this.method = method;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java
new file mode 100644
index 0000000..44c8d27
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor.java
@@ -0,0 +1,517 @@
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.logic.InferenceContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+import static com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes;
+
+public class TypeExtractor extends DefaultVisitorAdapter {
+
+    private static Logger logger = Logger.getLogger(TypeExtractor.class.getCanonicalName());
+
+    static {
+        logger.setLevel(Level.INFO);
+        ConsoleHandler consoleHandler = new ConsoleHandler();
+        consoleHandler.setLevel(Level.INFO);
+        logger.addHandler(consoleHandler);
+    }
+
+    private TypeSolver typeSolver;
+    private JavaParserFacade facade;
+
+    public TypeExtractor(TypeSolver typeSolver, JavaParserFacade facade) {
+        this.typeSolver = typeSolver;
+        this.facade = facade;
+    }
+
+    @Override
+    public ResolvedType visit(VariableDeclarator node, Boolean solveLambdas) {
+        if (requireParentNode(node) instanceof FieldDeclaration) {
+            return facade.convertToUsageVariableType(node);
+        } else if (requireParentNode(node) instanceof VariableDeclarationExpr) {
+            return facade.convertToUsageVariableType(node);
+        }
+        throw new UnsupportedOperationException(requireParentNode(node).getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(Parameter node, Boolean solveLambdas) {
+        if (node.getType() instanceof UnknownType) {
+            throw new IllegalStateException("Parameter has unknown type: " + node);
+        }
+        return facade.convertToUsage(node.getType(), node);
+    }
+
+
+    @Override
+    public ResolvedType visit(ArrayAccessExpr node, Boolean solveLambdas) {
+        ResolvedType arrayUsageType = node.getName().accept(this, solveLambdas);
+        if (arrayUsageType.isArray()) {
+            return ((ResolvedArrayType) arrayUsageType).getComponentType();
+        }
+        return arrayUsageType;
+    }
+
+    @Override
+    public ResolvedType visit(ArrayCreationExpr node, Boolean solveLambdas) {
+        ResolvedType res = facade.convertToUsage(node.getElementType(), JavaParserFactory.getContext(node, typeSolver));
+        for (int i = 0; i < node.getLevels().size(); i++) {
+            res = new ResolvedArrayType(res);
+        }
+        return res;
+    }
+
+    @Override
+    public ResolvedType visit(ArrayInitializerExpr node, Boolean solveLambdas) {
+        throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedType visit(AssignExpr node, Boolean solveLambdas) {
+        return node.getTarget().accept(this, solveLambdas);
+    }
+
+    @Override
+    public ResolvedType visit(BinaryExpr node, Boolean solveLambdas) {
+        switch (node.getOperator()) {
+            case PLUS:
+            case MINUS:
+            case DIVIDE:
+            case MULTIPLY:
+                return facade.getBinaryTypeConcrete(node.getLeft(), node.getRight(), solveLambdas);
+            case LESS_EQUALS:
+            case LESS:
+            case GREATER:
+            case GREATER_EQUALS:
+            case EQUALS:
+            case NOT_EQUALS:
+            case OR:
+            case AND:
+                return ResolvedPrimitiveType.BOOLEAN;
+            case BINARY_AND:
+            case BINARY_OR:
+            case SIGNED_RIGHT_SHIFT:
+            case UNSIGNED_RIGHT_SHIFT:
+            case LEFT_SHIFT:
+            case REMAINDER:
+            case XOR:
+                return node.getLeft().accept(this, solveLambdas);
+            default:
+                throw new UnsupportedOperationException("Operator " + node.getOperator().name());
+        }
+    }
+
+    @Override
+    public ResolvedType visit(CastExpr node, Boolean solveLambdas) {
+        return facade.convertToUsage(node.getType(), JavaParserFactory.getContext(node, typeSolver));
+    }
+
+    @Override
+    public ResolvedType visit(ClassExpr node, Boolean solveLambdas) {
+        // This implementation does not regard the actual type argument of the ClassExpr.
+        com.github.javaparser.ast.type.Type astType = node.getType();
+        ResolvedType jssType = facade.convertToUsage(astType, node.getType());
+        return new ReferenceTypeImpl(new ReflectionClassDeclaration(Class.class, typeSolver), ImmutableList.of(jssType), typeSolver);
+    }
+
+    @Override
+    public ResolvedType visit(ConditionalExpr node, Boolean solveLambdas) {
+        return node.getThenExpr().accept(this, solveLambdas);
+    }
+
+    @Override
+    public ResolvedType visit(EnclosedExpr node, Boolean solveLambdas) {
+        return node.getInner().accept(this, solveLambdas);
+    }
+
+    /**
+     * Java Parser can't differentiate between packages, internal types, and fields.
+     * All three are lumped together into FieldAccessExpr. We need to differentiate them.
+     */
+    private ResolvedType solveDotExpressionType(ResolvedReferenceTypeDeclaration parentType, FieldAccessExpr node) {
+        // Fields and internal type declarations cannot have the same name.
+        // Thus, these checks will always be mutually exclusive.
+        if (parentType.hasField(node.getName().getId())) {
+            return parentType.getField(node.getName().getId()).getType();
+        } else if (parentType.hasInternalType(node.getName().getId())) {
+            return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId()), typeSolver);
+        } else {
+            throw new UnsolvedSymbolException(node.getName().getId());
+        }
+    }
+
+    @Override
+    public ResolvedType visit(FieldAccessExpr node, Boolean solveLambdas) {
+        // We should understand if this is a static access
+        if (node.getScope() instanceof NameExpr ||
+                node.getScope() instanceof FieldAccessExpr) {
+            Expression staticValue = node.getScope();
+            SymbolReference<ResolvedTypeDeclaration> typeAccessedStatically = JavaParserFactory.getContext(node, typeSolver).solveType(staticValue.toString(), typeSolver);
+            if (typeAccessedStatically.isSolved()) {
+                // TODO here maybe we have to substitute type typeParametersValues
+                return solveDotExpressionType(
+                        typeAccessedStatically.getCorrespondingDeclaration().asReferenceType(), node);
+            }
+        } else if (node.getScope() instanceof ThisExpr) {
+            // If we are accessing through a 'this' expression, first resolve the type
+            // corresponding to 'this'
+            SymbolReference<ResolvedTypeDeclaration> solve = facade.solve((ThisExpr) node.getScope());
+            // If found get it's declaration and get the field in there
+            if (solve.isSolved()) {
+                ResolvedTypeDeclaration correspondingDeclaration = solve.getCorrespondingDeclaration();
+                if (correspondingDeclaration instanceof ResolvedReferenceTypeDeclaration) {
+                    return solveDotExpressionType(correspondingDeclaration.asReferenceType(), node);
+                }
+            }
+
+        } else if (node.getScope().toString().indexOf('.') > 0) {
+            // try to find fully qualified name
+            SymbolReference<ResolvedReferenceTypeDeclaration> sr = typeSolver.tryToSolveType(node.getScope().toString());
+            if (sr.isSolved()) {
+                return solveDotExpressionType(sr.getCorrespondingDeclaration(), node);
+            }
+        }
+        Optional<Value> value = Optional.empty();
+        try {
+            value = new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node);
+        } catch (com.github.javaparser.resolution.UnsolvedSymbolException use) {
+            // This node may have a package name as part of its fully qualified name.
+            // We should solve for the type declaration inside this package.
+            SymbolReference<ResolvedReferenceTypeDeclaration> sref = typeSolver.tryToSolveType(node.toString());
+            if (sref.isSolved()) {
+                return new ReferenceTypeImpl(sref.getCorrespondingDeclaration(), typeSolver);
+            }
+        }
+        if (value.isPresent()) {
+            return value.get().getType();
+        }
+        throw new com.github.javaparser.resolution.UnsolvedSymbolException(node.getName().getId());
+    }
+
+    @Override
+    public ResolvedType visit(InstanceOfExpr node, Boolean solveLambdas) {
+        return ResolvedPrimitiveType.BOOLEAN;
+    }
+
+    @Override
+    public ResolvedType visit(StringLiteralExpr node, Boolean solveLambdas) {
+        return new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(String.class.getCanonicalName()), typeSolver);
+    }
+
+    @Override
+    public ResolvedType visit(IntegerLiteralExpr node, Boolean solveLambdas) {
+        return ResolvedPrimitiveType.INT;
+    }
+
+    @Override
+    public ResolvedType visit(LongLiteralExpr node, Boolean solveLambdas) {
+        return ResolvedPrimitiveType.LONG;
+    }
+
+    @Override
+    public ResolvedType visit(CharLiteralExpr node, Boolean solveLambdas) {
+        return ResolvedPrimitiveType.CHAR;
+    }
+
+    @Override
+    public ResolvedType visit(DoubleLiteralExpr node, Boolean solveLambdas) {
+        if (node.getValue().toLowerCase().endsWith("f")) {
+            return ResolvedPrimitiveType.FLOAT;
+        }
+        return ResolvedPrimitiveType.DOUBLE;
+    }
+
+    @Override
+    public ResolvedType visit(BooleanLiteralExpr node, Boolean solveLambdas) {
+        return ResolvedPrimitiveType.BOOLEAN;
+    }
+
+    @Override
+    public ResolvedType visit(NullLiteralExpr node, Boolean solveLambdas) {
+        return NullType.INSTANCE;
+    }
+
+    @Override
+    public ResolvedType visit(MethodCallExpr node, Boolean solveLambdas) {
+        logger.finest("getType on method call " + node);
+        // first solve the method
+        MethodUsage ref = facade.solveMethodAsUsage(node);
+        logger.finest("getType on method call " + node + " resolved to " + ref);
+        logger.finest("getType on method call " + node + " return type is " + ref.returnType());
+        return ref.returnType();
+        // the type is the return type of the method
+    }
+
+    @Override
+    public ResolvedType visit(NameExpr node, Boolean solveLambdas) {
+        logger.finest("getType on name expr " + node);
+        Optional<Value> value = new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node);
+        if (!value.isPresent()) {
+            throw new com.github.javaparser.resolution.UnsolvedSymbolException("Solving " + node, node.getName().getId());
+        } else {
+            return value.get().getType();
+        }
+    }
+
+    @Override
+    public ResolvedType visit(ObjectCreationExpr node, Boolean solveLambdas) {
+        return facade.convertToUsage(node.getType(), node);
+    }
+
+    @Override
+    public ResolvedType visit(ThisExpr node, Boolean solveLambdas) {
+        // If 'this' is prefixed by a class eg. MyClass.this
+        if (node.getClassExpr().isPresent()) {
+            // Get the class name
+            String className = node.getClassExpr().get().toString();
+            // Attempt to resolve using a typeSolver
+            SymbolReference<ResolvedReferenceTypeDeclaration> clazz = typeSolver.tryToSolveType(className);
+            if (clazz.isSolved()) {
+                return new ReferenceTypeImpl(clazz.getCorrespondingDeclaration(), typeSolver);
+            }
+            // Attempt to resolve locally in Compilation unit
+            Optional<CompilationUnit> cu = node.getAncestorOfType(CompilationUnit.class);
+            if (cu.isPresent()) {
+                Optional<ClassOrInterfaceDeclaration> classByName = cu.get().getClassByName(className);
+                if (classByName.isPresent()) {
+                    return new ReferenceTypeImpl(facade.getTypeDeclaration(classByName.get()), typeSolver);
+                }
+            }
+
+        }
+        return new ReferenceTypeImpl(facade.getTypeDeclaration(facade.findContainingTypeDeclOrObjectCreationExpr(node)), typeSolver);
+    }
+
+    @Override
+    public ResolvedType visit(SuperExpr node, Boolean solveLambdas) {
+        ResolvedTypeDeclaration typeOfNode = facade.getTypeDeclaration(facade.findContainingTypeDecl(node));
+        if (typeOfNode instanceof ResolvedClassDeclaration) {
+            return ((ResolvedClassDeclaration) typeOfNode).getSuperClass();
+        } else {
+            throw new UnsupportedOperationException(node.getClass().getCanonicalName());
+        }
+    }
+
+    @Override
+    public ResolvedType visit(UnaryExpr node, Boolean solveLambdas) {
+        switch (node.getOperator()) {
+            case MINUS:
+            case PLUS:
+                return node.getExpression().accept(this, solveLambdas);
+            case LOGICAL_COMPLEMENT:
+                return ResolvedPrimitiveType.BOOLEAN;
+            case POSTFIX_DECREMENT:
+            case PREFIX_DECREMENT:
+            case POSTFIX_INCREMENT:
+            case PREFIX_INCREMENT:
+                return node.getExpression().accept(this, solveLambdas);
+            default:
+                throw new UnsupportedOperationException(node.getOperator().name());
+        }
+    }
+
+    @Override
+    public ResolvedType visit(VariableDeclarationExpr node, Boolean solveLambdas) {
+        if (node.getVariables().size() != 1) {
+            throw new UnsupportedOperationException();
+        }
+        return facade.convertToUsageVariableType(node.getVariables().get(0));
+    }
+
+
+    @Override
+    public ResolvedType visit(LambdaExpr node, Boolean solveLambdas) {
+        if (requireParentNode(node) instanceof MethodCallExpr) {
+            MethodCallExpr callExpr = (MethodCallExpr) requireParentNode(node);
+            int pos = JavaParserSymbolDeclaration.getParamPos(node);
+            SymbolReference<ResolvedMethodDeclaration> refMethod = facade.solve(callExpr);
+            if (!refMethod.isSolved()) {
+                throw new com.github.javaparser.resolution.UnsolvedSymbolException(requireParentNode(node).toString(), callExpr.getName().getId());
+            }
+            logger.finest("getType on lambda expr " + refMethod.getCorrespondingDeclaration().getName());
+            if (solveLambdas) {
+
+                // The type parameter referred here should be the java.util.stream.Stream.T
+                ResolvedType result = refMethod.getCorrespondingDeclaration().getParam(pos).getType();
+
+                if (callExpr.getScope().isPresent()) {
+                    Expression scope = callExpr.getScope().get();
+
+                    // If it is a static call we should not try to get the type of the scope
+                    boolean staticCall = false;
+                    if (scope instanceof NameExpr) {
+                        NameExpr nameExpr = (NameExpr) scope;
+                        try {
+                            SymbolReference<ResolvedTypeDeclaration> type = JavaParserFactory.getContext(nameExpr, typeSolver).solveType(nameExpr.getName().getId(), typeSolver);
+                            if (type.isSolved()) {
+                                staticCall = true;
+                            }
+                        } catch (Exception e) {
+
+                        }
+                    }
+
+                    if (!staticCall) {
+                        ResolvedType scopeType = facade.getType(scope);
+                        if (scopeType.isReferenceType()) {
+                            result = scopeType.asReferenceType().useThisTypeParametersOnTheGivenType(result);
+                        }
+                    }
+                }
+
+                // We need to replace the type variables
+                Context ctx = JavaParserFactory.getContext(node, typeSolver);
+                result = solveGenericTypes(result, ctx, typeSolver);
+
+                //We should find out which is the functional method (e.g., apply) and replace the params of the
+                //solveLambdas with it, to derive so the values. We should also consider the value returned by the
+                //lambdas
+                Optional<MethodUsage> functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(result);
+                if (functionalMethod.isPresent()) {
+                    LambdaExpr lambdaExpr = node;
+
+                    InferenceContext lambdaCtx = new InferenceContext(MyObjectProvider.INSTANCE);
+                    InferenceContext funcInterfaceCtx = new InferenceContext(MyObjectProvider.INSTANCE);
+
+                    // At this point parameterType
+                    // if Function<T=? super Stream.T, ? extends map.R>
+                    // we should replace Stream.T
+                    ResolvedType functionalInterfaceType = ReferenceTypeImpl.undeterminedParameters(functionalMethod.get().getDeclaration().declaringType(), typeSolver);
+
+                    lambdaCtx.addPair(result, functionalInterfaceType);
+
+                    ResolvedType actualType;
+
+                    if (lambdaExpr.getBody() instanceof ExpressionStmt) {
+                        actualType = facade.getType(((ExpressionStmt) lambdaExpr.getBody()).getExpression());
+                    } else if (lambdaExpr.getBody() instanceof BlockStmt) {
+                        BlockStmt blockStmt = (BlockStmt) lambdaExpr.getBody();
+
+                        // Get all the return statements in the lambda block
+                        List<ReturnStmt> returnStmts = blockStmt.findAll(ReturnStmt.class);
+
+                        if (returnStmts.size() > 0) {
+                            actualType = returnStmts.stream()
+                                    .map(returnStmt -> returnStmt.getExpression().map(e -> facade.getType(e)).orElse(ResolvedVoidType.INSTANCE))
+                                    .filter(x -> x != null && !x.isVoid() && !x.isNull())
+                                    .findFirst()
+                                    .orElse(ResolvedVoidType.INSTANCE);
+
+                        } else {
+                            return ResolvedVoidType.INSTANCE;
+                        }
+
+
+                    } else {
+                        throw new UnsupportedOperationException();
+                    }
+
+                    ResolvedType formalType = functionalMethod.get().returnType();
+
+                    // Infer the functional interfaces' return vs actual type
+                    funcInterfaceCtx.addPair(formalType, actualType);
+                    // Substitute to obtain a new type
+                    ResolvedType functionalTypeWithReturn = funcInterfaceCtx.resolve(funcInterfaceCtx.addSingle(functionalInterfaceType));
+
+                    // if the functional method returns void anyway
+                    // we don't need to bother inferring types
+                    if (!(formalType instanceof ResolvedVoidType)) {
+                        lambdaCtx.addPair(result, functionalTypeWithReturn);
+                        result = lambdaCtx.resolve(lambdaCtx.addSingle(result));
+                    }
+                }
+
+                return result;
+            } else {
+                return refMethod.getCorrespondingDeclaration().getParam(pos).getType();
+            }
+        } else {
+            throw new UnsupportedOperationException("The type of a lambda expr depends on the position and its return value");
+        }
+    }
+
+    @Override
+    public ResolvedType visit(MethodReferenceExpr node, Boolean solveLambdas) {
+        if (requireParentNode(node) instanceof MethodCallExpr) {
+            MethodCallExpr callExpr = (MethodCallExpr) requireParentNode(node);
+            int pos = JavaParserSymbolDeclaration.getParamPos(node);
+            SymbolReference<ResolvedMethodDeclaration> refMethod = facade.solve(callExpr, false);
+            if (!refMethod.isSolved()) {
+                throw new com.github.javaparser.resolution.UnsolvedSymbolException(requireParentNode(node).toString(), callExpr.getName().getId());
+            }
+            logger.finest("getType on method reference expr " + refMethod.getCorrespondingDeclaration().getName());
+            //logger.finest("Method param " + refMethod.getCorrespondingDeclaration().getParam(pos));
+            if (solveLambdas) {
+                MethodUsage usage = facade.solveMethodAsUsage(callExpr);
+                ResolvedType result = usage.getParamType(pos);
+                // We need to replace the type variables
+                Context ctx = JavaParserFactory.getContext(node, typeSolver);
+                result = solveGenericTypes(result, ctx, typeSolver);
+
+                //We should find out which is the functional method (e.g., apply) and replace the params of the
+                //solveLambdas with it, to derive so the values. We should also consider the value returned by the
+                //lambdas
+                if (FunctionalInterfaceLogic.getFunctionalMethod(result).isPresent()) {
+                    MethodReferenceExpr methodReferenceExpr = node;
+
+                    ResolvedType actualType = facade.toMethodUsage(methodReferenceExpr).returnType();
+                    ResolvedType formalType = FunctionalInterfaceLogic.getFunctionalMethod(result).get().returnType();
+
+                    InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
+                    inferenceContext.addPair(formalType, actualType);
+                    result = inferenceContext.resolve(inferenceContext.addSingle(result));
+                }
+
+                return result;
+            }
+            return refMethod.getCorrespondingDeclaration().getParam(pos).getType();
+        }
+        throw new UnsupportedOperationException("The type of a method reference expr depends on the position and its return value");
+    }
+
+    @Override
+    public ResolvedType visit(FieldDeclaration node, Boolean solveLambdas) {
+        if (node.getVariables().size() == 1) {
+            return node.getVariables().get(0).accept(this, solveLambdas);
+        }
+        throw new IllegalArgumentException("Cannot resolve the type of a field with multiple variable declarations. Pick one");
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java
new file mode 100644
index 0000000..f7ab7d1
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ *
+ * @deprecated Use {@link com.github.javaparser.resolution.UnsolvedSymbolException} instead
+ */
+// Use the one in model instead
+@Deprecated
+public class UnsolvedSymbolException extends RuntimeException {
+
+    private String context;
+    private String name;
+    private TypeSolver typeSolver;
+
+    @Deprecated
+    public UnsolvedSymbolException(String name, TypeSolver typeSolver) {
+        super("Unsolved symbol : " + name + " using typesolver " + typeSolver);
+        this.typeSolver = typeSolver;
+        this.name = name;
+    }
+
+    @Deprecated
+    public UnsolvedSymbolException(Context context, String name) {
+        super("Unsolved symbol in " + context + " : " + name);
+        this.context = context.toString();
+        this.name = name;
+    }
+
+    @Deprecated
+    public UnsolvedSymbolException(String context, String name) {
+        super("Unsolved symbol in " + context + " : " + name);
+        this.context = context;
+        this.name = name;
+    }
+
+    @Deprecated
+    public UnsolvedSymbolException(String name) {
+        super("Unsolved symbol : " + name);
+        this.context = "unknown";
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return "UnsolvedSymbolException{" +
+                "context='" + context + '\'' +
+                ", name='" + name + '\'' +
+                ", typeSolver=" + typeSolver +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java
new file mode 100644
index 0000000..cc008a5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.*;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+import static java.util.Collections.*;
+
+/**
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractJavaParserContext<N extends Node> implements Context {
+
+    protected N wrappedNode;
+    protected TypeSolver typeSolver;
+
+    ///
+    /// Static methods
+    ///
+
+    public static SymbolReference<ResolvedValueDeclaration> solveWith(SymbolDeclarator symbolDeclarator, String name) {
+        for (ResolvedValueDeclaration decl : symbolDeclarator.getSymbolDeclarations()) {
+            if (decl.getName().equals(name)) {
+                return SymbolReference.solved(decl);
+            }
+        }
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    ///
+    /// Constructors
+    ///
+
+    public AbstractJavaParserContext(N wrappedNode, TypeSolver typeSolver) {
+        if (wrappedNode == null) {
+            throw new NullPointerException();
+        }
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    ///
+    /// Public methods
+    ///
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AbstractJavaParserContext<?> that = (AbstractJavaParserContext<?>) o;
+
+        if (wrappedNode != null ? !wrappedNode.equals(that.wrappedNode) : that.wrappedNode != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return wrappedNode != null ? wrappedNode.hashCode() : 0;
+    }
+
+    @Override
+    public Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+        Context parent = getParent();
+        if (parent == null) {
+            return Optional.empty();
+        } else {
+            return parent.solveGenericType(name, typeSolver);
+        }
+    }
+
+    @Override
+    public final Context getParent() {
+        Node parent = wrappedNode.getParentNode().orElse(null);
+        if (parent instanceof MethodCallExpr) {
+            MethodCallExpr parentCall = (MethodCallExpr) parent;
+            boolean found = false;
+            if (parentCall.getArguments() != null) {
+                for (Expression expression : parentCall.getArguments()) {
+                    if (expression == wrappedNode) {
+                        found = true;
+                    }
+                }
+            }
+            if (found) {
+                Node notMethod = parent;
+                while (notMethod instanceof MethodCallExpr) {
+                    notMethod = requireParentNode(notMethod);
+                }
+                return JavaParserFactory.getContext(notMethod, typeSolver);
+            }
+        }
+        Node notMethod = parent;
+        while (notMethod instanceof MethodCallExpr || notMethod instanceof FieldAccessExpr) {
+            notMethod = notMethod.getParentNode().orElse(null);
+        }
+        if (notMethod == null) {
+            return null;
+        }
+        return JavaParserFactory.getContext(notMethod, typeSolver);
+    }
+
+    ///
+    /// Protected methods
+    ///
+
+    protected Optional<Value> solveWithAsValue(SymbolDeclarator symbolDeclarator, String name, TypeSolver typeSolver) {
+        return symbolDeclarator.getSymbolDeclarations().stream()
+                .filter(d -> d.getName().equals(name))
+                .map(Value::from)
+                .findFirst();
+    }
+
+    protected Collection<ResolvedReferenceTypeDeclaration> findTypeDeclarations(Optional<Expression> optScope, TypeSolver typeSolver) {
+        if (optScope.isPresent()) {
+            Expression scope = optScope.get();
+
+            // consider static methods
+            if (scope instanceof NameExpr) {
+                NameExpr scopeAsName = (NameExpr) scope;
+                SymbolReference<ResolvedTypeDeclaration> symbolReference = this.solveType(scopeAsName.getName().getId(), typeSolver);
+                if (symbolReference.isSolved() && symbolReference.getCorrespondingDeclaration().isType()) {
+                    return singletonList(symbolReference.getCorrespondingDeclaration().asReferenceType());
+                }
+            }
+
+            ResolvedType typeOfScope;
+            try {
+                typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
+            } catch (Exception e) {
+                throw new RuntimeException("Issue calculating the type of the scope of " + this, e);
+            }
+            if (typeOfScope.isWildcard()) {
+                if (typeOfScope.asWildcard().isExtends() || typeOfScope.asWildcard().isSuper()) {
+                    return singletonList(typeOfScope.asWildcard().getBoundedType().asReferenceType().getTypeDeclaration());
+                } else {
+                    return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType());
+                }
+            } else if (typeOfScope.isArray()) {
+                // method call on array are Object methods
+                return singletonList(new ReflectionClassDeclaration(Object.class, typeSolver).asReferenceType());
+            } else if (typeOfScope.isTypeVariable()) {
+                Collection<ResolvedReferenceTypeDeclaration> result = new ArrayList<>();
+                for (ResolvedTypeParameterDeclaration.Bound bound : typeOfScope.asTypeParameter().getBounds()) {
+                    result.add(bound.getType().asReferenceType().getTypeDeclaration());
+                }
+                return result;
+            } else if (typeOfScope.isConstraint()) {
+                return singletonList(typeOfScope.asConstraintType().getBound().asReferenceType().getTypeDeclaration());
+            }
+            return singletonList(typeOfScope.asReferenceType().getTypeDeclaration());
+        }
+        ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode);
+        return singletonList(typeOfScope.asReferenceType().getTypeDeclaration());
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java
new file mode 100644
index 0000000..d611d71
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext.java
@@ -0,0 +1,101 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.nodeTypes.NodeWithParameters;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractMethodLikeDeclarationContext
+        <T extends Node & NodeWithParameters<T> & NodeWithTypeParameters<T>> extends AbstractJavaParserContext<T> {
+
+    public AbstractMethodLikeDeclarationContext(T wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    public final SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (Parameter parameter : wrappedNode.getParameters()) {
+            SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+            SymbolReference<? extends ResolvedValueDeclaration> symbolReference = AbstractJavaParserContext.solveWith(sb, name);
+            if (symbolReference.isSolved()) {
+                return symbolReference;
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public final Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+        for (com.github.javaparser.ast.type.TypeParameter tp : wrappedNode.getTypeParameters()) {
+            if (tp.getName().getId().equals(name)) {
+                return Optional.of(new ResolvedTypeVariable(new JavaParserTypeParameter(tp, typeSolver)));
+            }
+        }
+        return super.solveGenericType(name, typeSolver);
+    }
+
+    @Override
+    public final Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        for (Parameter parameter : wrappedNode.getParameters()) {
+            SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+            Optional<Value> symbolReference = solveWithAsValue(sb, name, typeSolver);
+            if (symbolReference.isPresent()) {
+                // Perform parameter type substitution as needed
+                return symbolReference;
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        return getParent().solveSymbolAsValue(name, typeSolver);
+    }
+
+    @Override
+    public final SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        if (wrappedNode.getTypeParameters() != null) {
+            for (com.github.javaparser.ast.type.TypeParameter tp : wrappedNode.getTypeParameters()) {
+                if (tp.getName().getId().equals(name)) {
+                    return SymbolReference.solved(new JavaParserTypeParameter(tp, typeSolver));
+                }
+            }
+        }
+        
+        // Local types
+        List<com.github.javaparser.ast.body.TypeDeclaration> localTypes = wrappedNode.findAll(
+                com.github.javaparser.ast.body.TypeDeclaration.class);
+        for (com.github.javaparser.ast.body.TypeDeclaration<?> localType : localTypes) {
+            if (localType.getName().getId().equals(name)) {
+                return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(localType));
+            } else if (name.startsWith(String.format("%s.", localType.getName()))) {
+                return JavaParserFactory.getContext(localType, typeSolver).solveType(
+                        name.substring(localType.getName().getId().length() + 1), typeSolver);
+            }
+        }
+        
+        return getParent().solveType(name, typeSolver);
+    }
+
+    @Override
+    public final SymbolReference<ResolvedMethodDeclaration> solveMethod(
+            String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java
new file mode 100644
index 0000000..4813359
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext.java
@@ -0,0 +1,186 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations
+    .JavaParserAnonymousClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * A symbol resolution context for an object creation node.
+ */
+public class AnonymousClassDeclarationContext extends AbstractJavaParserContext<ObjectCreationExpr> {
+
+  private final JavaParserAnonymousClassDeclaration myDeclaration =
+      new JavaParserAnonymousClassDeclaration(wrappedNode, typeSolver);
+
+  public AnonymousClassDeclarationContext(ObjectCreationExpr node, TypeSolver typeSolver) {
+    super(node, typeSolver);
+    Preconditions.checkArgument(node.getAnonymousClassBody().isPresent(),
+                                "An anonymous class must have a body");
+  }
+
+  @Override
+  public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name,
+                                                                List<ResolvedType> argumentsTypes,
+                                                                boolean staticOnly,
+                                                                TypeSolver typeSolver) {
+    List<ResolvedMethodDeclaration> candidateMethods =
+        myDeclaration
+            .getDeclaredMethods()
+            .stream()
+            .filter(m -> m.getName().equals(name) && (!staticOnly || m.isStatic()))
+            .collect(Collectors.toList());
+
+    if (!Object.class.getCanonicalName().equals(myDeclaration.getQualifiedName())) {
+      for (ResolvedReferenceType ancestor : myDeclaration.getAncestors()) {
+        SymbolReference<ResolvedMethodDeclaration> res =
+            MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(),
+                                                    name,
+                                                    argumentsTypes,
+                                                    staticOnly,
+                                                    typeSolver);
+        // consider methods from superclasses and only default methods from interfaces :
+        // not true, we should keep abstract as a valid candidate
+        // abstract are removed in MethodResolutionLogic.isApplicable is necessary
+        if (res.isSolved()) {
+          candidateMethods.add(res.getCorrespondingDeclaration());
+        }
+      }
+    }
+
+    // We want to avoid infinite recursion when a class is using its own method
+    // see issue #75
+    if (candidateMethods.isEmpty()) {
+      SymbolReference<ResolvedMethodDeclaration> parentSolution =
+          getParent().solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+      if (parentSolution.isSolved()) {
+        candidateMethods.add(parentSolution.getCorrespondingDeclaration());
+      }
+    }
+
+    // if is interface and candidate method list is empty, we should check the Object Methods
+    if (candidateMethods.isEmpty() && myDeclaration.getSuperTypeDeclaration().isInterface()) {
+      SymbolReference<ResolvedMethodDeclaration> res =
+          MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class,
+                                                                                 typeSolver),
+                                                  name,
+                                                  argumentsTypes,
+                                                  false,
+                                                  typeSolver);
+      if (res.isSolved()) {
+        candidateMethods.add(res.getCorrespondingDeclaration());
+      }
+    }
+
+    return MethodResolutionLogic.findMostApplicable(candidateMethods,
+                                                    name,
+                                                    argumentsTypes,
+                                                    typeSolver);
+  }
+
+  @Override
+  public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+    List<com.github.javaparser.ast.body.TypeDeclaration> typeDeclarations =
+        myDeclaration
+            .findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class);
+
+    Optional<SymbolReference<ResolvedTypeDeclaration>> exactMatch =
+        typeDeclarations
+            .stream()
+            .filter(internalType -> internalType.getName().getId().equals(name))
+            .findFirst()
+            .map(internalType ->
+                     SymbolReference.solved(
+                         JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType)));
+
+    if(exactMatch.isPresent()){
+      return exactMatch.get();
+    }
+
+    Optional<SymbolReference<ResolvedTypeDeclaration>> recursiveMatch =
+        typeDeclarations
+            .stream()
+            .filter(internalType -> name.startsWith(String.format("%s.", internalType.getName())))
+            .findFirst()
+            .map(internalType ->
+                     JavaParserFactory
+                         .getContext(internalType, typeSolver)
+                         .solveType(name.substring(internalType.getName().getId().length() + 1),
+                                    typeSolver));
+
+    if (recursiveMatch.isPresent()) {
+      return recursiveMatch.get();
+    }
+
+    Optional<SymbolReference<ResolvedTypeDeclaration>> typeArgumentsMatch =
+        wrappedNode
+            .getTypeArguments()
+            .map(nodes ->
+                     ((NodeWithTypeArguments<?>) nodes).getTypeArguments()
+                                                       .orElse(new NodeList<>()))
+            .orElse(new NodeList<>())
+            .stream()
+            .filter(type -> type.toString().equals(name))
+            .findFirst()
+            .map(matchingType ->
+                     SymbolReference.solved(
+                         new JavaParserTypeParameter(new TypeParameter(matchingType.toString()),
+                                                     typeSolver)));
+
+    if (typeArgumentsMatch.isPresent()) {
+      return typeArgumentsMatch.get();
+    }
+
+    // Look into extended classes and implemented interfaces
+    for (ResolvedReferenceType ancestor : myDeclaration.getAncestors()) {
+      // look at names of extended classes and implemented interfaces (this may not be important because they are checked in CompilationUnitContext)
+      if (ancestor.getTypeDeclaration().getName().equals(name)) {
+        return SymbolReference.solved(ancestor.getTypeDeclaration());
+      } 
+      // look into internal types of extended classes and implemented interfaces
+      try {
+        for (ResolvedTypeDeclaration internalTypeDeclaration : ancestor.getTypeDeclaration().internalTypes()) {
+          if (internalTypeDeclaration.getName().equals(name)) {
+            return SymbolReference.solved(internalTypeDeclaration);
+          }
+        }
+      } catch (UnsupportedOperationException e) {
+        // just continue using the next ancestor
+      }
+    }
+    
+    return getParent().solveType(name, typeSolver);
+  }
+
+  @Override
+  public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name,
+                                                                         TypeSolver typeSolver) {
+    Preconditions.checkArgument(typeSolver != null);
+
+    if (myDeclaration.hasVisibleField(name)) {
+      return SymbolReference.solved(myDeclaration.getVisibleField(name));
+    }
+
+    return getParent().solveSymbol(name, typeSolver);
+  }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java
new file mode 100644
index 0000000..4683f27
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext.java
@@ -0,0 +1,54 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Fred Lefévère-Laoide
+ */
+public class CatchClauseContext extends AbstractJavaParserContext<CatchClause> {
+
+    public CatchClauseContext(CatchClause wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    public final SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(wrappedNode.getParameter(), typeSolver);
+        SymbolReference<? extends ResolvedValueDeclaration> symbolReference = AbstractJavaParserContext.solveWith(sb, name);
+        if (symbolReference.isSolved()) {
+            return symbolReference;
+        }
+
+        // if nothing is found we should ask the parent context
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public final Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(wrappedNode.getParameter(), typeSolver);
+        Optional<Value> symbolReference = solveWithAsValue(sb, name, typeSolver);
+        if (symbolReference.isPresent()) {
+            // Perform parameter type substitution as needed
+            return symbolReference;
+        }
+
+        // if nothing is found we should ask the parent context
+        return getParent().solveSymbolAsValue(name, typeSolver);
+    }
+
+    @Override
+    public final SymbolReference<ResolvedMethodDeclaration> solveMethod(
+            String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java
new file mode 100644
index 0000000..01f4b05
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ClassOrInterfaceDeclarationContext extends AbstractJavaParserContext<ClassOrInterfaceDeclaration> {
+
+    private JavaParserTypeDeclarationAdapter javaParserTypeDeclarationAdapter;
+
+    ///
+    /// Constructors
+    ///
+
+    public ClassOrInterfaceDeclarationContext(ClassOrInterfaceDeclaration wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+        this.javaParserTypeDeclarationAdapter = new JavaParserTypeDeclarationAdapter(wrappedNode, typeSolver,
+                getDeclaration(), this);
+    }
+
+    ///
+    /// Public methods
+    ///
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        if (typeSolver == null) throw new IllegalArgumentException();
+
+        if (this.getDeclaration().hasVisibleField(name)) {
+            return SymbolReference.solved(this.getDeclaration().getVisibleField(name));
+        }
+
+        // then to parent
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        if (typeSolver == null) throw new IllegalArgumentException();
+
+        if (this.getDeclaration().hasVisibleField(name)) {
+            return Optional.of(Value.from(this.getDeclaration().getVisibleField(name)));
+        }
+
+        // then to parent
+        return getParent().solveSymbolAsValue(name, typeSolver);
+    }
+
+    @Override
+    public Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+        for (com.github.javaparser.ast.type.TypeParameter tp : wrappedNode.getTypeParameters()) {
+            if (tp.getName().getId().equals(name)) {
+                return Optional.of(new ResolvedTypeVariable(new JavaParserTypeParameter(tp, typeSolver)));
+            }
+        }
+        return getParent().solveGenericType(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        return javaParserTypeDeclarationAdapter.solveType(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return javaParserTypeDeclarationAdapter.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+    }
+
+    public SymbolReference<ResolvedConstructorDeclaration> solveConstructor(List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        return javaParserTypeDeclarationAdapter.solveConstructor(argumentsTypes, typeSolver);
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private ResolvedReferenceTypeDeclaration getDeclaration() {
+        return JavaParserFacade.get(typeSolver).getTypeDeclaration(this.wrappedNode);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java
new file mode 100644
index 0000000..e6a4aa0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnnotationDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class CompilationUnitContext extends AbstractJavaParserContext<CompilationUnit> {
+
+    ///
+    /// Static methods
+    ///
+
+    private static boolean isQualifiedName(String name) {
+        return name.contains(".");
+    }
+
+    ///
+    /// Constructors
+    ///
+
+    public CompilationUnitContext(CompilationUnit wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    ///
+    /// Public methods
+    ///
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+
+        // solve absolute references
+        String itName = name;
+        while (itName.contains(".")) {
+            String typeName = getType(itName);
+            String memberName = getMember(itName);
+            SymbolReference<ResolvedTypeDeclaration> type = this.solveType(typeName, typeSolver);
+            if (type.isSolved()) {
+                return new SymbolSolver(typeSolver).solveSymbolInType(type.getCorrespondingDeclaration(), memberName);
+            } else {
+                itName = typeName;
+            }
+        }
+
+        // Look among statically imported values
+        if (wrappedNode.getImports() != null) {
+            for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+                if(importDecl.isStatic()){
+                    if(importDecl.isAsterisk()) {
+                        String qName = importDecl.getNameAsString();
+                        ResolvedTypeDeclaration importedType = typeSolver.solveType(qName);
+                        SymbolReference<? extends ResolvedValueDeclaration> ref = new SymbolSolver(typeSolver).solveSymbolInType(importedType, name);
+                        if (ref.isSolved()) {
+                            return ref;
+                        }
+                    } else{
+                        String whole = importDecl.getNameAsString();
+
+                        // split in field/method name and type name
+                        String memberName = getMember(whole);
+                        String typeName = getType(whole);
+
+                        if (memberName.equals(name)) {
+                            ResolvedTypeDeclaration importedType = typeSolver.solveType(typeName);
+                            return new SymbolSolver(typeSolver).solveSymbolInType(importedType, memberName);
+                        }
+                    }
+                }
+            }
+        }
+
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    @Override
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        if (wrappedNode.getTypes() != null) {
+            for (TypeDeclaration<?> type : wrappedNode.getTypes()) {
+                if (type.getName().getId().equals(name)) {
+                    if (type instanceof ClassOrInterfaceDeclaration) {
+                        return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration((ClassOrInterfaceDeclaration) type));
+                    } else if (type instanceof AnnotationDeclaration) {
+                        return SymbolReference.solved(new JavaParserAnnotationDeclaration((AnnotationDeclaration) type, typeSolver));
+                    } else if (type instanceof EnumDeclaration) {
+                        return SymbolReference.solved(new JavaParserEnumDeclaration((EnumDeclaration) type, typeSolver));
+                    } else {
+                        throw new UnsupportedOperationException(type.getClass().getCanonicalName());
+                    }
+                }
+            }
+        }
+
+        if (wrappedNode.getImports() != null) {
+            int dotPos = name.indexOf('.');
+            String prefix = null;
+            if (dotPos > -1) {
+                prefix = name.substring(0, dotPos);
+            }
+            // look into type imports
+            for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+                if (!importDecl.isAsterisk()) {
+                    String qName = importDecl.getNameAsString();
+                    boolean defaultPackage = !importDecl.getName().getQualifier().isPresent();
+                    boolean found = !defaultPackage && importDecl.getName().getIdentifier().equals(name);
+                    if (!found) {
+                        if (prefix != null) {
+                            found = qName.endsWith("." + prefix);
+                            if (found) {
+                                qName = qName + name.substring(dotPos);
+                            }
+                        }
+                    }
+                    if (found) {
+                        SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+                        if (ref.isSolved()) {
+                            return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+                        }
+                    }
+                }
+            }
+            // look into type imports on demand
+            for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+                if (importDecl.isAsterisk()) {
+                    String qName = importDecl.getNameAsString() + "." + name;
+                    SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+                    if (ref.isSolved()) {
+                        return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+                    }
+                }
+            }
+        }
+
+        // Look in current package
+        if (this.wrappedNode.getPackageDeclaration().isPresent()) {
+            String qName = this.wrappedNode.getPackageDeclaration().get().getName().toString() + "." + name;
+            SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+            if (ref.isSolved()) {
+                return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+            }
+        } else {
+            // look for classes in the default package
+            String qName = name;
+            SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType(qName);
+            if (ref.isSolved()) {
+                return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+            }
+        }
+
+        // Look in the java.lang package
+        SymbolReference<ResolvedReferenceTypeDeclaration> ref = typeSolver.tryToSolveType("java.lang." + name);
+        if (ref.isSolved()) {
+            return SymbolReference.adapt(ref, ResolvedTypeDeclaration.class);
+        }
+
+        // DO NOT look for absolute name if this name is not qualified: you cannot import classes from the default package
+        if (isQualifiedName(name)) {
+            return SymbolReference.adapt(typeSolver.tryToSolveType(name), ResolvedTypeDeclaration.class);
+        } else {
+            return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+        }
+    }
+
+    private String qName(ClassOrInterfaceType type) {
+        if (type.getScope().isPresent()) {
+            return qName(type.getScope().get()) + "." + type.getName().getId();
+        } else {
+            return type.getName().getId();
+        }
+    }
+
+    private String qName(Name name) {
+        if (name.getQualifier().isPresent()) {
+            return qName(name.getQualifier().get()) + "." + name.getId();
+        } else {
+            return name.getId();
+        }
+    }
+
+    private String toSimpleName(String qName) {
+        String[] parts = qName.split("\\.");
+        return parts[parts.length - 1];
+    }
+
+    private String packageName(String qName) {
+        int lastDot = qName.lastIndexOf('.');
+        if (lastDot == -1) {
+            throw new UnsupportedOperationException();
+        } else {
+            return qName.substring(0, lastDot);
+        }
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        for (ImportDeclaration importDecl : wrappedNode.getImports()) {
+            if(importDecl.isStatic()){
+                if(importDecl.isAsterisk()){
+                    String importString = importDecl.getNameAsString();
+
+                    if (this.wrappedNode.getPackageDeclaration().isPresent()
+                            && this.wrappedNode.getPackageDeclaration().get().getName().getIdentifier().equals(packageName(importString))
+                            && this.wrappedNode.getTypes().stream().anyMatch(it -> it.getName().getIdentifier().equals(toSimpleName(importString)))) {
+                        // We are using a static import on a type defined in this file. It means the value was not found at
+                        // a lower level so this will fail
+                        return SymbolReference.unsolved(ResolvedMethodDeclaration.class);
+                    }
+
+                    ResolvedTypeDeclaration ref = typeSolver.solveType(importString);
+                    SymbolReference<ResolvedMethodDeclaration> method = MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, true, typeSolver);
+
+                    if (method.isSolved()) {
+                        return method;
+                    }
+                } else{
+                    String qName = importDecl.getNameAsString();
+
+                    if (qName.equals(name) || qName.endsWith("." + name)) {
+                        String typeName = getType(qName);
+                        ResolvedTypeDeclaration ref = typeSolver.solveType(typeName);
+                        SymbolReference<ResolvedMethodDeclaration> method = MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, true, typeSolver);
+                        if (method.isSolved()) {
+                            return method;
+                        }
+                    }
+                }
+            }
+        }
+        return SymbolReference.unsolved(ResolvedMethodDeclaration.class);
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private String getType(String qName) {
+        int index = qName.lastIndexOf('.');
+        if (index == -1) {
+            throw new UnsupportedOperationException();
+        }
+        String typeName = qName.substring(0, index);
+        return typeName;
+    }
+
+    private String getMember(String qName) {
+        int index = qName.lastIndexOf('.');
+        if (index == -1) {
+            throw new UnsupportedOperationException();
+        }
+        String memberName = qName.substring(index + 1);
+        return memberName;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java
new file mode 100644
index 0000000..bebaa73
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ConstructorContext extends AbstractMethodLikeDeclarationContext<ConstructorDeclaration> {
+
+    ///
+    /// Constructors
+    ///
+
+    public ConstructorContext(ConstructorDeclaration wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java
new file mode 100644
index 0000000..e0eda24
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ContextHelper {
+
+    private ContextHelper() {
+        // prevent instantiation
+    }
+
+    public static Optional<MethodUsage> solveMethodAsUsage(ResolvedTypeDeclaration typeDeclaration, String name,
+                                                           List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+                                                           Context invokationContext, List<ResolvedType> typeParameters) {
+        if (typeDeclaration instanceof JavassistClassDeclaration) {
+            return ((JavassistClassDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+        } else if (typeDeclaration instanceof JavassistInterfaceDeclaration) {
+            return ((JavassistInterfaceDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+        } else if (typeDeclaration instanceof JavassistEnumDeclaration) {
+            return ((JavassistEnumDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+        } else if (typeDeclaration instanceof ReflectionClassDeclaration) {
+            return ((ReflectionClassDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+        } else if (typeDeclaration instanceof ReflectionInterfaceDeclaration) {
+            return ((ReflectionInterfaceDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+        } else if (typeDeclaration instanceof ReflectionEnumDeclaration) {
+            return ((ReflectionEnumDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters);
+        } else if (typeDeclaration instanceof JavaParserClassDeclaration) {
+            return ((JavaParserClassDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+        } else if (typeDeclaration instanceof JavaParserInterfaceDeclaration) {
+            return ((JavaParserInterfaceDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+        } else if (typeDeclaration instanceof JavaParserEnumDeclaration) {
+            return ((JavaParserEnumDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+        } else if (typeDeclaration instanceof JavaParserAnonymousClassDeclaration) {
+            return ((JavaParserAnonymousClassDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver);
+        }
+        throw new UnsupportedOperationException(typeDeclaration.toString());
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java
new file mode 100644
index 0000000..7f2365f
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumConstantDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class EnumDeclarationContext extends AbstractJavaParserContext<EnumDeclaration> {
+
+    private JavaParserTypeDeclarationAdapter javaParserTypeDeclarationAdapter;
+
+    public EnumDeclarationContext(EnumDeclaration wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+        this.javaParserTypeDeclarationAdapter = new JavaParserTypeDeclarationAdapter(wrappedNode, typeSolver,
+                getDeclaration(), this);
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        if (typeSolver == null) throw new IllegalArgumentException();
+
+        // among constants
+        for (EnumConstantDeclaration constant : wrappedNode.getEntries()) {
+            if (constant.getName().getId().equals(name)) {
+                return SymbolReference.solved(new JavaParserEnumConstantDeclaration(constant, typeSolver));
+            }
+        }
+
+        if (this.getDeclaration().hasField(name)) {
+            return SymbolReference.solved(this.getDeclaration().getField(name));
+        }
+
+        // then to parent
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        return javaParserTypeDeclarationAdapter.solveType(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return javaParserTypeDeclarationAdapter.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private ResolvedReferenceTypeDeclaration getDeclaration() {
+        return new JavaParserEnumDeclaration(this.wrappedNode, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java
new file mode 100644
index 0000000..65ccedf
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class FieldAccessContext extends AbstractJavaParserContext<FieldAccessExpr> {
+
+    private static final String ARRAY_LENGTH_FIELD_NAME = "length";
+
+    public FieldAccessContext(FieldAccessExpr wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        if (wrappedNode.getName().toString().equals(name)) {
+            if (wrappedNode.getScope() instanceof ThisExpr) {
+                ResolvedType typeOfThis = JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode);
+                return new SymbolSolver(typeSolver).solveSymbolInType(typeOfThis.asReferenceType().getTypeDeclaration(), name);
+            }
+        }
+        return JavaParserFactory.getContext(requireParentNode(wrappedNode), typeSolver).solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        return JavaParserFactory.getContext(requireParentNode(wrappedNode), typeSolver).solveType(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return JavaParserFactory.getContext(requireParentNode(wrappedNode), typeSolver).solveMethod(name, parameterTypes, false, typeSolver);
+    }
+
+    @Override
+    public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        Expression scope = wrappedNode.getScope();
+        if (wrappedNode.getName().toString().equals(name)) {
+            ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
+            if (typeOfScope.isArray() && name.equals(ARRAY_LENGTH_FIELD_NAME)) {
+                return Optional.of(new Value(ResolvedPrimitiveType.INT, ARRAY_LENGTH_FIELD_NAME));
+            }
+            if (typeOfScope.isReferenceType()) {
+                Optional<ResolvedType> typeUsage = typeOfScope.asReferenceType().getFieldType(name);
+                return typeUsage.map(resolvedType -> new Value(resolvedType, name));
+            } else {
+                return Optional.empty();
+            }
+        } else {
+            return getParent().solveSymbolAsValue(name, typeSolver);
+        }
+    }
+
+    public SymbolReference<ResolvedFieldDeclaration> solveField(String name, TypeSolver typeSolver) {
+        Collection<ResolvedReferenceTypeDeclaration> rrtds = findTypeDeclarations(Optional.of(wrappedNode.getScope()), typeSolver);
+        for (ResolvedReferenceTypeDeclaration rrtd : rrtds) {
+            try {
+                return SymbolReference.solved(rrtd.getField(wrappedNode.getName().getId()));
+            } catch (Throwable t) {
+            }
+        }
+        return SymbolReference.unsolved(ResolvedFieldDeclaration.class);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java
new file mode 100644
index 0000000..cf3fe3b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+public class ForStatementContext extends AbstractJavaParserContext<ForStmt> {
+
+    public ForStatementContext(ForStmt wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (Expression expression : wrappedNode.getInitialization()) {
+            if (expression instanceof VariableDeclarationExpr) {
+                VariableDeclarationExpr variableDeclarationExpr = (VariableDeclarationExpr) expression;
+                for (VariableDeclarator variableDeclarator : variableDeclarationExpr.getVariables()) {
+                    if (variableDeclarator.getName().getId().equals(name)) {
+                        return SymbolReference.solved(JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver));
+                    }
+                }
+            } else if (!(expression instanceof AssignExpr || expression instanceof MethodCallExpr)) {
+                throw new UnsupportedOperationException(expression.getClass().getCanonicalName());
+            }
+        }
+
+        if (requireParentNode(wrappedNode) instanceof NodeWithStatements) {
+            return StatementContext.solveInBlock(name, typeSolver, wrappedNode);
+        } else {
+            return getParent().solveSymbol(name, typeSolver);
+        }
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes,
+                                                                  boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java
new file mode 100644
index 0000000..ba41202
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+public class ForechStatementContext extends AbstractJavaParserContext<ForeachStmt> {
+
+    public ForechStatementContext(ForeachStmt wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        if (wrappedNode.getVariable().getVariables().size() != 1) {
+            throw new IllegalStateException();
+        }
+        VariableDeclarator variableDeclarator = wrappedNode.getVariable().getVariables().get(0);
+        if (variableDeclarator.getName().getId().equals(name)) {
+            return SymbolReference.solved(JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver));
+        } else {
+            if (requireParentNode(wrappedNode) instanceof BlockStmt) {
+                return StatementContext.solveInBlock(name, typeSolver, wrappedNode);
+            } else {
+                return getParent().solveSymbol(name, typeSolver);
+            }
+        }
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes,
+                                                                  boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java
new file mode 100644
index 0000000..993f42d
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter.java
@@ -0,0 +1,133 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.*;
+import com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeDeclarationAdapter {
+
+    private com.github.javaparser.ast.body.TypeDeclaration<?> wrappedNode;
+    private TypeSolver typeSolver;
+    private Context context;
+    private ResolvedReferenceTypeDeclaration typeDeclaration;
+
+    public JavaParserTypeDeclarationAdapter(com.github.javaparser.ast.body.TypeDeclaration<?> wrappedNode, TypeSolver typeSolver,
+                                            ResolvedReferenceTypeDeclaration typeDeclaration,
+                                            Context context) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+        this.typeDeclaration = typeDeclaration;
+        this.context = context;
+    }
+
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        if (this.wrappedNode.getName().getId().equals(name)) {
+            return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(wrappedNode));
+        }
+
+        // Internal classes
+        for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+                com.github.javaparser.ast.body.TypeDeclaration<?> internalType = (com.github.javaparser.ast.body.TypeDeclaration<?>) member;
+                if (internalType.getName().getId().equals(name)) {
+                    return SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType));
+                } else if (name.startsWith(String.format("%s.%s", wrappedNode.getName(), internalType.getName()))) {
+                    return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(wrappedNode.getName().getId().length() + 1), typeSolver);
+                } else if (name.startsWith(String.format("%s.", internalType.getName()))) {
+                    return JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(internalType.getName().getId().length() + 1), typeSolver);
+                }
+            }
+        }
+
+        if (wrappedNode instanceof NodeWithTypeParameters) {
+            NodeWithTypeParameters<?> nodeWithTypeParameters = (NodeWithTypeParameters<?>) wrappedNode;
+            for (TypeParameter astTpRaw : nodeWithTypeParameters.getTypeParameters()) {
+                TypeParameter astTp = astTpRaw;
+                if (astTp.getName().getId().equals(name)) {
+                    return SymbolReference.solved(new JavaParserTypeParameter(astTp, typeSolver));
+                }
+            }
+        }
+
+        // Look into extended classes and implemented interfaces
+        for (ResolvedReferenceType ancestor : this.typeDeclaration.getAncestors()) {
+        	try {
+	            for (ResolvedTypeDeclaration internalTypeDeclaration : ancestor.getTypeDeclaration().internalTypes()) {
+	                if (internalTypeDeclaration.getName().equals(name)) {
+	                    return SymbolReference.solved(internalTypeDeclaration);
+	                }
+	            }
+        	} catch (UnsupportedOperationException e) {
+	            // just continue using the next ancestor
+            }
+        }
+
+        return context.getParent().solveType(name, typeSolver);
+    }
+
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        List<ResolvedMethodDeclaration> candidateMethods = typeDeclaration.getDeclaredMethods().stream()
+                .filter(m -> m.getName().equals(name))
+                .filter(m -> !staticOnly || (staticOnly &&  m.isStatic()))
+                .collect(Collectors.toList());
+        // We want to avoid infinite recursion in case of Object having Object as ancestor
+        if (!Object.class.getCanonicalName().equals(typeDeclaration.getQualifiedName())) {
+            for (ResolvedReferenceType ancestor : typeDeclaration.getAncestors()) {
+		// Avoid recursion on self
+                if (typeDeclaration != ancestor.getTypeDeclaration()) {
+                    SymbolReference<ResolvedMethodDeclaration> res = MethodResolutionLogic
+                            .solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, staticOnly, typeSolver);
+                    // consider methods from superclasses and only default methods from interfaces :
+                    // not true, we should keep abstract as a valid candidate
+                    // abstract are removed in MethodResolutionLogic.isApplicable is necessary
+                    if (res.isSolved()) {
+                        candidateMethods.add(res.getCorrespondingDeclaration());
+                    }
+		}
+            }
+        }
+        // We want to avoid infinite recursion when a class is using its own method
+        // see issue #75
+        if (candidateMethods.isEmpty()) {
+            SymbolReference<ResolvedMethodDeclaration> parentSolution = context.getParent().solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+            if (parentSolution.isSolved()) {
+                candidateMethods.add(parentSolution.getCorrespondingDeclaration());
+            }
+        }
+
+        // if is interface and candidate method list is empty, we should check the Object Methods
+        if (candidateMethods.isEmpty() && typeDeclaration.isInterface()) {
+            SymbolReference<ResolvedMethodDeclaration> res = MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class, typeSolver), name, argumentsTypes, false, typeSolver);
+            if (res.isSolved()) {
+                candidateMethods.add(res.getCorrespondingDeclaration());
+            }
+        }
+
+        return MethodResolutionLogic.findMostApplicable(candidateMethods, name, argumentsTypes, typeSolver);
+    }
+
+    public SymbolReference<ResolvedConstructorDeclaration> solveConstructor(List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        if (typeDeclaration instanceof ResolvedClassDeclaration) {
+            return ConstructorResolutionLogic.findMostApplicable(((ResolvedClassDeclaration) typeDeclaration).getConstructors(), argumentsTypes, typeSolver);
+        }
+        return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java
new file mode 100644
index 0000000..3c34fac
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedLambdaConstraintType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.logic.InferenceContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.*;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class LambdaExprContext extends AbstractJavaParserContext<LambdaExpr> {
+
+    public LambdaExprContext(LambdaExpr wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        for (Parameter parameter : wrappedNode.getParameters()) {
+            SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+            int index = 0;
+            for (ResolvedValueDeclaration decl : sb.getSymbolDeclarations()) {
+                if (decl.getName().equals(name)) {
+                    if (requireParentNode(wrappedNode) instanceof MethodCallExpr) {
+                        MethodCallExpr methodCallExpr = (MethodCallExpr) requireParentNode(wrappedNode);
+                        MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr);
+                        int i = pos(methodCallExpr, wrappedNode);
+                        ResolvedType lambdaType = methodUsage.getParamTypes().get(i);
+
+                        // Get the functional method in order for us to resolve it's type arguments properly
+                        Optional<MethodUsage> functionalMethodOpt = FunctionalInterfaceLogic.getFunctionalMethod(lambdaType);
+                        if (functionalMethodOpt.isPresent()){
+                            MethodUsage functionalMethod = functionalMethodOpt.get();
+                            InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
+
+                            // Resolve each type variable of the lambda, and use this later to infer the type of each
+                            // implicit parameter
+                            inferenceContext.addPair(lambdaType, new ReferenceTypeImpl(lambdaType.asReferenceType().getTypeDeclaration(), typeSolver));
+
+                            // Find the position of this lambda argument
+                            boolean found = false;
+                            int lambdaParamIndex;
+                            for (lambdaParamIndex = 0; lambdaParamIndex < wrappedNode.getParameters().size(); lambdaParamIndex++){
+                                if (wrappedNode.getParameter(lambdaParamIndex).getName().getIdentifier().equals(name)){
+                                    found = true;
+                                    break;
+                                }
+                            }
+                            if (!found) { return Optional.empty(); }
+
+                            // Now resolve the argument type using the inference context
+                            ResolvedType argType = inferenceContext.resolve(inferenceContext.addSingle(functionalMethod.getParamType(lambdaParamIndex)));
+
+                            ResolvedLambdaConstraintType conType;
+                            if (argType.isWildcard()){
+                                conType = ResolvedLambdaConstraintType.bound(argType.asWildcard().getBoundedType());
+                            } else {
+                                conType = ResolvedLambdaConstraintType.bound(argType);
+                            }
+                            Value value = new Value(conType, name);
+                            return Optional.of(value);
+                        } else{
+                            return Optional.empty();
+                        }
+                    } else if (requireParentNode(wrappedNode) instanceof VariableDeclarator) {
+                        VariableDeclarator variableDeclarator = (VariableDeclarator) requireParentNode(wrappedNode);
+                        ResolvedType t = JavaParserFacade.get(typeSolver).convertToUsageVariableType(variableDeclarator);
+                        Optional<MethodUsage> functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(t);
+                        if (functionalMethod.isPresent()) {
+                            ResolvedType lambdaType = functionalMethod.get().getParamType(index);
+
+                            // Replace parameter from declarator
+                            Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
+                            if (lambdaType.isReferenceType()) {
+                                for (com.github.javaparser.utils.Pair<ResolvedTypeParameterDeclaration, ResolvedType> entry : lambdaType.asReferenceType().getTypeParametersMap()) {
+                                    if (entry.b.isTypeVariable() && entry.b.asTypeParameter().declaredOnType()) {
+                                        ResolvedType ot = t.asReferenceType().typeParametersMap().getValue(entry.a);
+                                        lambdaType = lambdaType.replaceTypeVariables(entry.a, ot, inferredTypes);
+                                    }
+                                }
+                            } else if (lambdaType.isTypeVariable() && lambdaType.asTypeParameter().declaredOnType()) {
+                                lambdaType = t.asReferenceType().typeParametersMap().getValue(lambdaType.asTypeParameter());
+                            }
+
+                            Value value = new Value(lambdaType, name);
+                            return Optional.of(value);
+                        } else {
+                            throw new UnsupportedOperationException();
+                        }
+                    } else {
+                        throw new UnsupportedOperationException();
+                    }
+                }
+                index++;
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        return getParent().solveSymbolAsValue(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (Parameter parameter : wrappedNode.getParameters()) {
+            SymbolDeclarator sb = JavaParserFactory.getSymbolDeclarator(parameter, typeSolver);
+            SymbolReference<ResolvedValueDeclaration> symbolReference = solveWith(sb, name);
+            if (symbolReference.isSolved()) {
+                return symbolReference;
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        return getParent().solveType(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(
+            String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+
+    ///
+    /// Protected methods
+    ///
+
+    protected final Optional<Value> solveWithAsValue(SymbolDeclarator symbolDeclarator, String name, TypeSolver typeSolver) {
+        for (ResolvedValueDeclaration decl : symbolDeclarator.getSymbolDeclarations()) {
+            if (decl.getName().equals(name)) {
+
+                throw new UnsupportedOperationException();
+            }
+        }
+        return Optional.empty();
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private int pos(MethodCallExpr callExpr, Expression param) {
+        int i = 0;
+        for (Expression p : callExpr.getArguments()) {
+            if (p == param) {
+                return i;
+            }
+            i++;
+        }
+        throw new IllegalArgumentException();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java
new file mode 100644
index 0000000..ca9f07c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.github.javaparser.utils.Pair;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+public class MethodCallExprContext extends AbstractJavaParserContext<MethodCallExpr> {
+
+    ///
+    /// Constructors
+    ///
+
+    public MethodCallExprContext(MethodCallExpr wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    ///
+    /// Public methods
+    ///
+
+    @Override
+    public Optional<ResolvedType> solveGenericType(String name, TypeSolver typeSolver) {
+        if(wrappedNode.getScope().isPresent()){
+            ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(wrappedNode.getScope().get());
+            Optional<ResolvedType> res = typeOfScope.asReferenceType().getGenericParameterByName(name);
+            return res;
+        } else{
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "MethodCallExprContext{wrapped=" + wrappedNode + "}";
+    }
+
+    @Override
+    public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        if (wrappedNode.getScope().isPresent()) {
+            Expression scope = wrappedNode.getScope().get();
+            // Consider static method calls
+            if (scope instanceof NameExpr) {
+                String className = ((NameExpr) scope).getName().getId();
+                SymbolReference<ResolvedTypeDeclaration> ref = solveType(className, typeSolver);
+                if (ref.isSolved()) {
+                    SymbolReference<ResolvedMethodDeclaration> m = MethodResolutionLogic.solveMethodInType(ref.getCorrespondingDeclaration(), name, argumentsTypes, typeSolver);
+                    if (m.isSolved()) {
+                        MethodUsage methodUsage = new MethodUsage(m.getCorrespondingDeclaration());
+                        methodUsage = resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage);
+                        methodUsage = resolveMethodTypeParameters(methodUsage, argumentsTypes);
+                        return Optional.of(methodUsage);
+                    } else {
+                        throw new UnsolvedSymbolException(ref.getCorrespondingDeclaration().toString(),
+                                "Method '" + name + "' with parameterTypes " + argumentsTypes);
+                    }
+                }
+            }
+
+            ResolvedType typeOfScope = JavaParserFacade.get(typeSolver).getType(scope);
+            // we can replace the parameter types from the scope into the typeParametersValues
+
+            Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes = new HashMap<>();
+            for (int i = 0; i < argumentsTypes.size(); i++) {
+                // by replacing types I can also find new equivalences
+                // for example if I replace T=U with String because I know that T=String I can derive that also U equal String
+                ResolvedType originalArgumentType = argumentsTypes.get(i);
+                ResolvedType updatedArgumentType = usingParameterTypesFromScope(typeOfScope, originalArgumentType, inferredTypes);
+                argumentsTypes.set(i, updatedArgumentType);
+            }
+            for (int i = 0; i < argumentsTypes.size(); i++) {
+                ResolvedType updatedArgumentType = applyInferredTypes(argumentsTypes.get(i), inferredTypes);
+                argumentsTypes.set(i, updatedArgumentType);
+            }
+
+            return solveMethodAsUsage(typeOfScope, name, argumentsTypes, typeSolver, this);
+        } else {
+            Context parentContext = getParent();
+            while (parentContext instanceof MethodCallExprContext) {
+                parentContext = parentContext.getParent();
+            }
+            return parentContext.solveMethodAsUsage(name, argumentsTypes, typeSolver);
+        }
+    }
+
+    private MethodUsage resolveMethodTypeParametersFromExplicitList(TypeSolver typeSolver, MethodUsage methodUsage) {
+        if (wrappedNode.getTypeArguments().isPresent()) {
+            final List<ResolvedType> typeArguments = new ArrayList<>();
+            for (com.github.javaparser.ast.type.Type ty : wrappedNode.getTypeArguments().get()) {
+                typeArguments.add(JavaParserFacade.get(typeSolver).convertToUsage(ty));
+            }
+
+            List<ResolvedTypeParameterDeclaration> tyParamDecls = methodUsage.getDeclaration().getTypeParameters();
+            if (tyParamDecls.size() == typeArguments.size()) {
+                for (int i = 0; i < tyParamDecls.size(); i++) {
+                    methodUsage = methodUsage.replaceTypeParameter(tyParamDecls.get(i), typeArguments.get(i));
+                }
+            }
+        }
+
+        return methodUsage;
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        Context parentContext = getParent();
+        return parentContext.solveSymbolAsValue(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        Collection<ResolvedReferenceTypeDeclaration> rrtds = findTypeDeclarations(wrappedNode.getScope(), typeSolver);
+        for (ResolvedReferenceTypeDeclaration rrtd : rrtds) {
+            SymbolReference<ResolvedMethodDeclaration> res = MethodResolutionLogic.solveMethodInType(rrtd, name, argumentsTypes, false, typeSolver);
+            if (res.isSolved()) {
+                return res;
+            }
+        }
+        return SymbolReference.unsolved(ResolvedMethodDeclaration.class);
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private Optional<MethodUsage> solveMethodAsUsage(ResolvedReferenceType refType, String name,
+                                                     List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+                                                     Context invokationContext) {
+        Optional<MethodUsage> ref = ContextHelper.solveMethodAsUsage(refType.getTypeDeclaration(), name, argumentsTypes, typeSolver, invokationContext, refType.typeParametersValues());
+        if (ref.isPresent()) {
+            MethodUsage methodUsage = ref.get();
+
+            methodUsage = resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage);
+
+            // At this stage I should derive from the context and the value some information on the type parameters
+            // for example, when calling:
+            // myStream.collect(Collectors.toList())
+            // I should be able to figure out that considering the type of the stream (e.g., Stream<String>)
+            // and considering that Stream has this method:
+            //
+            // <R,A> R collect(Collector<? super T,A,R> collector)
+            //
+            // and collector has this method:
+            //
+            // static <T> Collector<T,?,List<T>>   toList()
+            //
+            // In this case collect.R has to be equal to List<toList.T>
+            // And toList.T has to be equal to ? super Stream.T
+            // Therefore R has to be equal to List<? super Stream.T>.
+            // In our example Stream.T equal to String, so the R (and the result of the call to collect) is
+            // List<? super String>
+
+            Map<ResolvedTypeParameterDeclaration, ResolvedType> derivedValues = new HashMap<>();
+            for (int i = 0; i < methodUsage.getParamTypes().size(); i++) {
+                ResolvedParameterDeclaration parameter = methodUsage.getDeclaration().getParam(i);
+                ResolvedType parameterType = parameter.getType();
+                if (parameter.isVariadic()) {
+                	parameterType = parameterType.asArrayType().getComponentType();
+                }
+                inferTypes(argumentsTypes.get(i), parameterType, derivedValues);
+            }
+
+            for (Map.Entry<ResolvedTypeParameterDeclaration, ResolvedType> entry : derivedValues.entrySet()){
+                methodUsage = methodUsage.replaceTypeParameter(entry.getKey(), entry.getValue());
+            }
+
+            ResolvedType returnType = refType.useThisTypeParametersOnTheGivenType(methodUsage.returnType());
+            if (returnType != methodUsage.returnType()) {
+                methodUsage = methodUsage.replaceReturnType(returnType);
+            }
+            for (int i = 0; i < methodUsage.getParamTypes().size(); i++) {
+                ResolvedType replaced = refType.useThisTypeParametersOnTheGivenType(methodUsage.getParamTypes().get(i));
+                methodUsage = methodUsage.replaceParamType(i, replaced);
+            }
+            return Optional.of(methodUsage);
+        } else {
+            return ref;
+        }
+    }
+
+    private void inferTypes(ResolvedType source, ResolvedType target, Map<ResolvedTypeParameterDeclaration, ResolvedType> mappings) {
+        if (source.equals(target)) {
+            return;
+        }
+        if (source.isReferenceType() && target.isReferenceType()) {
+            ResolvedReferenceType sourceRefType = source.asReferenceType();
+            ResolvedReferenceType targetRefType = target.asReferenceType();
+            if (sourceRefType.getQualifiedName().equals(targetRefType.getQualifiedName())) {
+            	if (!sourceRefType.isRawType() && !targetRefType.isRawType()) {
+	                for (int i = 0; i < sourceRefType.typeParametersValues().size(); i++) {
+	                    inferTypes(sourceRefType.typeParametersValues().get(i), targetRefType.typeParametersValues().get(i), mappings);
+	                }
+            	}
+            }
+            return;
+        }
+        if (source.isReferenceType() && target.isWildcard()) {
+            if (target.asWildcard().isBounded()) {
+                inferTypes(source, target.asWildcard().getBoundedType(), mappings);
+                return;
+            }
+            return;
+        }
+        if (source.isWildcard() && target.isWildcard()) {
+            if (source.asWildcard().isBounded() && target.asWildcard().isBounded()){
+                inferTypes(source.asWildcard().getBoundedType(), target.asWildcard().getBoundedType(), mappings);
+            }
+            return;
+        }
+        if (source.isReferenceType() && target.isTypeVariable()) {
+            mappings.put(target.asTypeParameter(), source);
+            return;
+        }
+        if (source.isWildcard() && target.isTypeVariable()) {
+            mappings.put(target.asTypeParameter(), source);
+            return;
+        }
+        if (source.isArray() && target.isWildcard()){
+            if(target.asWildcard().isBounded()){
+                inferTypes(source, target.asWildcard().getBoundedType(), mappings);
+                return;
+            }
+            return;
+        }
+        if (source.isArray() && target.isTypeVariable()) {
+            mappings.put(target.asTypeParameter(), source);
+            return;
+        }
+
+        if (source.isWildcard() && target.isReferenceType()){
+            if (source.asWildcard().isBounded()){
+                inferTypes(source.asWildcard().getBoundedType(), target, mappings);
+            }
+            return;
+        }
+        if (source.isConstraint() && target.isReferenceType()){
+            inferTypes(source.asConstraintType().getBound(), target, mappings);
+            return;
+        }
+
+        if (source.isConstraint() && target.isTypeVariable()){
+            inferTypes(source.asConstraintType().getBound(), target, mappings);
+            return;
+        }
+        if (source.isTypeVariable() && target.isTypeVariable()) {
+            mappings.put(target.asTypeParameter(), source);
+            return;
+        }
+        if (source.isPrimitive() || target.isPrimitive()) {
+            return;
+        }
+        if (source.isNull()) {
+            return;
+        }
+        throw new RuntimeException(source.describe() + " " + target.describe());
+    }
+
+    private MethodUsage resolveMethodTypeParameters(MethodUsage methodUsage, List<ResolvedType> actualParamTypes) {
+        Map<ResolvedTypeParameterDeclaration, ResolvedType> matchedTypeParameters = new HashMap<>();
+
+        if (methodUsage.getDeclaration().hasVariadicParameter()) {
+            if (actualParamTypes.size() == methodUsage.getDeclaration().getNumberOfParams()) {
+                // the varargs parameter is an Array, so extract the inner type
+                ResolvedType expectedType =
+                    methodUsage.getDeclaration().getLastParam().getType().asArrayType().getComponentType();
+                // the varargs corresponding type can be either T or Array<T>
+                ResolvedType actualType =
+                    actualParamTypes.get(actualParamTypes.size() - 1).isArray() ?
+                        actualParamTypes.get(actualParamTypes.size() - 1).asArrayType().getComponentType() :
+                        actualParamTypes.get(actualParamTypes.size() - 1);
+                if (!expectedType.isAssignableBy(actualType)) {
+                    for (ResolvedTypeParameterDeclaration tp : methodUsage.getDeclaration().getTypeParameters()) {
+                        expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
+                    }
+                }
+                if (!expectedType.isAssignableBy(actualType)) {
+                    // ok, then it needs to be wrapped
+                    throw new UnsupportedOperationException(
+                        String.format("Unable to resolve the type typeParametersValues in a MethodUsage. Expected type: %s, Actual type: %s. Method Declaration: %s. MethodUsage: %s",
+                                      expectedType,
+                                      actualType,
+                                      methodUsage.getDeclaration(),
+                                      methodUsage));
+                }
+                // match only the varargs type
+                matchTypeParameters(expectedType, actualType, matchedTypeParameters);
+            } else {
+                return methodUsage;
+            }
+        }
+
+        int until = methodUsage.getDeclaration().hasVariadicParameter() ?
+            actualParamTypes.size() - 1 :
+            actualParamTypes.size();
+
+        for (int i = 0; i < until; i++) {
+            ResolvedType expectedType = methodUsage.getParamType(i);
+            ResolvedType actualType = actualParamTypes.get(i);
+            matchTypeParameters(expectedType, actualType, matchedTypeParameters);
+        }
+        for (ResolvedTypeParameterDeclaration tp : matchedTypeParameters.keySet()) {
+            methodUsage = methodUsage.replaceTypeParameter(tp, matchedTypeParameters.get(tp));
+        }
+        return methodUsage;
+    }
+
+    private void matchTypeParameters(ResolvedType expectedType, ResolvedType actualType, Map<ResolvedTypeParameterDeclaration, ResolvedType> matchedTypeParameters) {
+        if (expectedType.isTypeVariable()) {
+            if (!actualType.isTypeVariable() && !actualType.isReferenceType()) {
+                throw new UnsupportedOperationException(actualType.getClass().getCanonicalName());
+            }
+            matchedTypeParameters.put(expectedType.asTypeParameter(), actualType);
+        } else if (expectedType.isArray()) {
+            if (!actualType.isArray()) {
+                throw new UnsupportedOperationException(actualType.getClass().getCanonicalName());
+            }
+            matchTypeParameters(
+                    expectedType.asArrayType().getComponentType(),
+                    actualType.asArrayType().getComponentType(),
+                    matchedTypeParameters);
+        } else if (expectedType.isReferenceType()) {
+            // avoid cases where the actual type has no type parameters but the expected one has. Such as: "classX extends classY<Integer>"
+            if (actualType.isReferenceType() && actualType.asReferenceType().typeParametersValues().size() > 0) {
+                int i = 0;
+                for (ResolvedType tp : expectedType.asReferenceType().typeParametersValues()) {
+                    matchTypeParameters(tp, actualType.asReferenceType().typeParametersValues().get(i), matchedTypeParameters);
+                    i++;
+                }
+            }
+        } else if (expectedType.isPrimitive()) {
+            // nothing to do
+        } else if (expectedType.isWildcard()) {
+            // nothing to do
+        } else {
+            throw new UnsupportedOperationException(expectedType.getClass().getCanonicalName());
+        }
+    }
+
+    private Optional<MethodUsage> solveMethodAsUsage(ResolvedTypeVariable tp, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext) {
+        for (ResolvedTypeParameterDeclaration.Bound bound : tp.asTypeParameter().getBounds()) {
+            Optional<MethodUsage> methodUsage = solveMethodAsUsage(bound.getType(), name, argumentsTypes, typeSolver, invokationContext);
+            if (methodUsage.isPresent()) {
+                return methodUsage;
+            }
+        }
+        return Optional.empty();
+    }
+
+    private Optional<MethodUsage> solveMethodAsUsage(ResolvedType type, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext) {
+        if (type instanceof ResolvedReferenceType) {
+            return solveMethodAsUsage((ResolvedReferenceType) type, name, argumentsTypes, typeSolver, invokationContext);
+        } else if (type instanceof ResolvedTypeVariable) {
+            return solveMethodAsUsage((ResolvedTypeVariable) type, name, argumentsTypes, typeSolver, invokationContext);
+        } else if (type instanceof ResolvedWildcard) {
+            ResolvedWildcard wildcardUsage = (ResolvedWildcard) type;
+            if (wildcardUsage.isSuper()) {
+                return solveMethodAsUsage(wildcardUsage.getBoundedType(), name, argumentsTypes, typeSolver, invokationContext);
+            } else if (wildcardUsage.isExtends()) {
+                throw new UnsupportedOperationException("extends wildcard");
+            } else {
+                throw new UnsupportedOperationException("unbounded wildcard");
+            }
+        } else if (type instanceof ResolvedLambdaConstraintType){
+            ResolvedLambdaConstraintType constraintType = (ResolvedLambdaConstraintType) type;
+            return solveMethodAsUsage(constraintType.getBound(), name, argumentsTypes, typeSolver, invokationContext);
+        } else if (type instanceof ResolvedArrayType) {
+            // An array inherits methods from Object not from it's component type
+            return solveMethodAsUsage(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver), name, argumentsTypes, typeSolver, invokationContext);
+        } else {
+            throw new UnsupportedOperationException("type usage: " + type.getClass().getCanonicalName());
+        }
+    }
+
+    private ResolvedType usingParameterTypesFromScope(ResolvedType scope, ResolvedType type, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        if (type.isReferenceType()) {
+            for (Pair<ResolvedTypeParameterDeclaration, ResolvedType> entry : type.asReferenceType().getTypeParametersMap()) {
+                if (entry.a.declaredOnType() && scope.asReferenceType().getGenericParameterByName(entry.a.getName()).isPresent()) {
+                    type = type.replaceTypeVariables(entry.a, scope.asReferenceType().getGenericParameterByName(entry.a.getName()).get(), inferredTypes);
+                }
+            }
+            return type;
+        } else {
+            return type;
+        }
+    }
+
+    private ResolvedType applyInferredTypes(ResolvedType type, Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        for (ResolvedTypeParameterDeclaration tp : inferredTypes.keySet()) {
+            type = type.replaceTypeVariables(tp, inferredTypes.get(tp), inferredTypes);
+        }
+        return type;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java
new file mode 100644
index 0000000..9a7530b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class MethodContext extends AbstractMethodLikeDeclarationContext<MethodDeclaration> {
+
+    ///
+    /// Constructors
+    ///
+
+    public MethodContext(MethodDeclaration wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java
new file mode 100644
index 0000000..8acab7a
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class StatementContext<N extends Statement> extends AbstractJavaParserContext<N> {
+
+    public StatementContext(N wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    public static SymbolReference<? extends ResolvedValueDeclaration> solveInBlock(String name, TypeSolver typeSolver, Statement stmt) {
+        if (!(requireParentNode(stmt) instanceof NodeWithStatements)) {
+            throw new IllegalArgumentException();
+        }
+        NodeWithStatements<?> blockStmt = (NodeWithStatements<?>) requireParentNode(stmt);
+        int position = -1;
+        for (int i = 0; i < blockStmt.getStatements().size(); i++) {
+            if (blockStmt.getStatements().get(i).equals(stmt)) {
+                position = i;
+            }
+        }
+        if (position == -1) {
+            throw new RuntimeException();
+        }
+        for (int i = position - 1; i >= 0; i--) {
+            SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(blockStmt.getStatements().get(i), typeSolver);
+            SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+            if (symbolReference.isSolved()) {
+                return symbolReference;
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        return JavaParserFactory.getContext(requireParentNode(stmt), typeSolver).solveSymbol(name, typeSolver);
+    }
+
+    public static Optional<Value> solveInBlockAsValue(String name, TypeSolver typeSolver, Statement stmt) {
+        if (!(requireParentNode(stmt) instanceof NodeWithStatements)) {
+            throw new IllegalArgumentException();
+        }
+        NodeWithStatements<?> blockStmt = (NodeWithStatements<?>) requireParentNode(stmt);
+        int position = -1;
+        for (int i = 0; i < blockStmt.getStatements().size(); i++) {
+            if (blockStmt.getStatements().get(i).equals(stmt)) {
+                position = i;
+            }
+        }
+        if (position == -1) {
+            throw new RuntimeException();
+        }
+        for (int i = position - 1; i >= 0; i--) {
+            SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(blockStmt.getStatements().get(i), typeSolver);
+            SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+            if (symbolReference.isSolved()) {
+                return Optional.of(Value.from(symbolReference.getCorrespondingDeclaration()));
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        return JavaParserFactory.getContext(requireParentNode(stmt), typeSolver).solveSymbolAsValue(name, typeSolver);
+    }
+
+    @Override
+    public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+
+        // if we're in a multiple Variable declaration line (for ex: double a=0, b=a;)
+        SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(wrappedNode, typeSolver);
+        Optional<Value> symbolReference = solveWithAsValue(symbolDeclarator, name, typeSolver);
+        if (symbolReference.isPresent()) {
+            return symbolReference;
+        }
+
+        // we should look in all the statements preceding, treating them as SymbolDeclarators
+        if (requireParentNode(wrappedNode) instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+            return getParent().solveSymbolAsValue(name, typeSolver);
+        }
+        if (requireParentNode(wrappedNode) instanceof LambdaExpr) {
+            return getParent().solveSymbolAsValue(name, typeSolver);
+        }
+        if (requireParentNode(wrappedNode) instanceof IfStmt) {
+            return getParent().solveSymbolAsValue(name, typeSolver);
+        }
+        if (!(requireParentNode(wrappedNode) instanceof NodeWithStatements)) {
+            return getParent().solveSymbolAsValue(name, typeSolver);
+        }
+        NodeWithStatements<?> nodeWithStmt = (NodeWithStatements<?>) requireParentNode(wrappedNode);
+        int position = -1;
+        for (int i = 0; i < nodeWithStmt.getStatements().size(); i++) {
+            if (nodeWithStmt.getStatements().get(i).equals(wrappedNode)) {
+                position = i;
+            }
+        }
+        if (position == -1) {
+            throw new RuntimeException();
+        }
+        for (int i = position - 1; i >= 0; i--) {
+            symbolDeclarator = JavaParserFactory.getSymbolDeclarator(nodeWithStmt.getStatements().get(i), typeSolver);
+            symbolReference = solveWithAsValue(symbolDeclarator, name, typeSolver);
+            if (symbolReference.isPresent()) {
+                return symbolReference;
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        Context parentContext = getParent();
+        return parentContext.solveSymbolAsValue(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+
+        // if we're in a multiple Variable declaration line (for ex: double a=0, b=a;)
+        SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(wrappedNode, typeSolver);
+        SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+        if (symbolReference.isSolved()) {
+            return symbolReference;
+        }
+
+        // we should look in all the statements preceding, treating them as SymbolDeclarators
+        if (requireParentNode(wrappedNode) instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+            return getParent().solveSymbol(name, typeSolver);
+        }
+        if (requireParentNode(wrappedNode) instanceof com.github.javaparser.ast.body.ConstructorDeclaration) {
+            return getParent().solveSymbol(name, typeSolver);
+        }
+        if (requireParentNode(wrappedNode) instanceof LambdaExpr) {
+            return getParent().solveSymbol(name, typeSolver);
+        }
+        if (!(requireParentNode(wrappedNode) instanceof NodeWithStatements)) {
+            return getParent().solveSymbol(name, typeSolver);
+        }
+        NodeWithStatements<?> nodeWithStmt = (NodeWithStatements<?>) requireParentNode(wrappedNode);
+        int position = -1;
+        for (int i = 0; i < nodeWithStmt.getStatements().size(); i++) {
+            if (nodeWithStmt.getStatements().get(i).equals(wrappedNode)) {
+                position = i;
+            }
+        }
+        if (position == -1) {
+            throw new RuntimeException();
+        }
+        for (int i = position - 1; i >= 0; i--) {
+            symbolDeclarator = JavaParserFactory.getSymbolDeclarator(nodeWithStmt.getStatements().get(i), typeSolver);
+            symbolReference = solveWith(symbolDeclarator, name);
+            if (symbolReference.isSolved()) {
+                return symbolReference;
+            }
+        }
+
+        // if nothing is found we should ask the parent context
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        return getParent().solveType(name, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java
new file mode 100644
index 0000000..1596729
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class SwitchEntryContext extends AbstractJavaParserContext<SwitchEntryStmt> {
+
+    public SwitchEntryContext(SwitchEntryStmt wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        SwitchStmt switchStmt = (SwitchStmt) requireParentNode(wrappedNode);
+        ResolvedType type = JavaParserFacade.get(typeSolver).getType(switchStmt.getSelector());
+        if (type.isReferenceType() && type.asReferenceType().getTypeDeclaration().isEnum()) {
+            if (type instanceof ReferenceTypeImpl) {
+                ReferenceTypeImpl typeUsageOfTypeDeclaration = (ReferenceTypeImpl) type;
+                if (typeUsageOfTypeDeclaration.getTypeDeclaration().hasField(name)) {
+                    return SymbolReference.solved(typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name));
+                }
+            } else {
+                throw new UnsupportedOperationException();
+            }
+        }
+
+        // look for declaration in other switch statements
+        for (SwitchEntryStmt seStmt : switchStmt.getEntries()) {
+            if (!seStmt.equals(wrappedNode)) {
+                for (Statement stmt : seStmt.getStatements()) {
+                    SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(stmt, typeSolver);
+                    SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name);
+                    if (symbolReference.isSolved()) {
+                        return symbolReference;
+                    }
+                }
+            }
+        }
+
+        return getParent().solveSymbol(name, typeSolver);
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java
new file mode 100644
index 0000000..80932e5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.contexts;
+
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+public class TryWithResourceContext extends AbstractJavaParserContext<TryStmt> {
+
+    public TryWithResourceContext(TryStmt wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public Optional<Value> solveSymbolAsValue(String name, TypeSolver typeSolver) {
+        for (Expression expr : wrappedNode.getResources()) {
+            if (expr instanceof VariableDeclarationExpr) {
+                for (VariableDeclarator v : ((VariableDeclarationExpr)expr).getVariables()) {
+                    if (v.getName().getIdentifier().equals(name)) {
+                        JavaParserSymbolDeclaration decl = JavaParserSymbolDeclaration.localVar(v, typeSolver);
+                        return Optional.of(Value.from(decl));
+                    }
+                }
+            }
+        }
+
+        if (requireParentNode(wrappedNode) instanceof BlockStmt) {
+            return StatementContext.solveInBlockAsValue(name, typeSolver, wrappedNode);
+        } else {
+            return getParent().solveSymbolAsValue(name, typeSolver);
+        }
+    }
+
+    @Override
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (Expression expr : wrappedNode.getResources()) {
+            if (expr instanceof VariableDeclarationExpr) {
+                for (VariableDeclarator v : ((VariableDeclarationExpr)expr).getVariables()) {
+                    if (v.getName().getIdentifier().equals(name)) {
+                        return SymbolReference.solved(JavaParserSymbolDeclaration.localVar(v, typeSolver));
+                    }
+                }
+            }
+        }
+
+        if (requireParentNode(wrappedNode) instanceof BlockStmt) {
+            return StatementContext.solveInBlock(name, typeSolver, wrappedNode);
+        } else {
+            return getParent().solveSymbol(name, typeSolver);
+        }
+    }
+
+    @Override
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes,
+                                                                  boolean staticOnly, TypeSolver typeSolver) {
+        return getParent().solveMethod(name, argumentsTypes, false, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java
new file mode 100644
index 0000000..aff7c7c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This represents the default constructor added by the compiler for objects not declaring one.
+ * It takes no parameters. See JLS 8.8.9 for details.
+ *
+ * @author Federico Tomassetti
+ */
+class DefaultConstructorDeclaration implements ResolvedConstructorDeclaration {
+
+    private ResolvedClassDeclaration classDeclaration;
+
+    DefaultConstructorDeclaration(ResolvedClassDeclaration classDeclaration) {
+        this.classDeclaration = classDeclaration;
+    }
+
+    @Override
+    public ResolvedClassDeclaration declaringType() {
+        return classDeclaration;
+    }
+
+    @Override
+    public int getNumberOfParams() {
+        return 0;
+    }
+
+    @Override
+    public ResolvedParameterDeclaration getParam(int i) {
+        throw new UnsupportedOperationException("The default constructor has not parameters");
+    }
+
+    @Override
+    public String getName() {
+        return classDeclaration.getName();
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return AccessSpecifier.PUBLIC;
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public int getNumberOfSpecifiedExceptions() {
+        return 0;
+    }
+
+    @Override
+    public ResolvedType getSpecifiedException(int index) {
+        throw new UnsupportedOperationException("The default constructor does not throw exceptions");
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java
new file mode 100644
index 0000000..d34e164
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.*;
+
+import java.util.EnumSet;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+class Helper {
+
+    public static AccessSpecifier toAccessLevel(EnumSet<Modifier> modifiers) {
+        if (modifiers.contains(Modifier.PRIVATE)) {
+            return AccessSpecifier.PRIVATE;
+        } else if (modifiers.contains(Modifier.PROTECTED)) {
+            return AccessSpecifier.PROTECTED;
+        } else if (modifiers.contains(Modifier.PUBLIC)) {
+            return AccessSpecifier.PUBLIC;
+        } else {
+            return AccessSpecifier.DEFAULT;
+        }
+    }
+
+    static String containerName(Node container) {
+        String packageName = getPackageName(container);
+        String className = getClassName("", container);
+        return packageName +
+                ((!packageName.isEmpty() && !className.isEmpty()) ? "." : "") +
+                className;
+    }
+
+    static String getPackageName(Node container) {
+        if (container instanceof CompilationUnit) {
+            Optional<PackageDeclaration> p = ((CompilationUnit) container).getPackageDeclaration();
+            if (p.isPresent()) {
+                return p.get().getName().toString();
+            }
+        } else if (container != null) {
+            return getPackageName(container.getParentNode().orElse(null));
+        }
+        return "";
+    }
+
+    static String getClassName(String base, Node container) {
+        if (container instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) {
+            String b = getClassName(base, container.getParentNode().orElse(null));
+            String cn = ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName().getId();
+            if (b.isEmpty()) {
+                return cn;
+            } else {
+                return b + "." + cn;
+            }
+        } else if (container instanceof com.github.javaparser.ast.body.EnumDeclaration) {
+            String b = getClassName(base, container.getParentNode().orElse(null));
+            String cn = ((com.github.javaparser.ast.body.EnumDeclaration) container).getName().getId();
+            if (b.isEmpty()) {
+                return cn;
+            } else {
+                return b + "." + cn;
+            }
+        } else if (container != null) {
+            return getClassName(base, container.getParentNode().orElse(null));
+        }
+        return base;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java
new file mode 100644
index 0000000..1f6c6f3
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration.java
@@ -0,0 +1,103 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserAnnotationDeclaration extends AbstractTypeDeclaration implements ResolvedAnnotationDeclaration {
+
+    private com.github.javaparser.ast.body.AnnotationDeclaration wrappedNode;
+    private TypeSolver typeSolver;
+
+    public JavaParserAnnotationDeclaration(AnnotationDeclaration wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String qualifiedName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getPackageName() {
+        return Helper.getPackageName(wrappedNode);
+    }
+
+    @Override
+    public String getClassName() {
+        return Helper.getClassName("", wrappedNode);
+    }
+
+    @Override
+    public String getQualifiedName() {
+        String containerName = Helper.containerName(wrappedNode.getParentNode().orElse(null));
+        if (containerName.isEmpty()) {
+            return wrappedNode.getName().getId();
+        } else {
+            return containerName + "." + wrappedNode.getName();
+        }
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        throw new UnsupportedOperationException("containerType is not supported for " + this.getClass().getCanonicalName());
+    }
+
+    @Override
+    public List<ResolvedAnnotationMemberDeclaration> getAnnotationMembers() {
+        return wrappedNode.getMembers().stream()
+                .filter(m -> m instanceof AnnotationMemberDeclaration)
+                .map(m -> new JavaParserAnnotationMemberDeclaration((AnnotationMemberDeclaration)m, typeSolver))
+                .collect(Collectors.toList());
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java
new file mode 100644
index 0000000..2a603da
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationMemberDeclaration.java
@@ -0,0 +1,40 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.resolution.declarations.ResolvedAnnotationMemberDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserAnnotationMemberDeclaration implements ResolvedAnnotationMemberDeclaration {
+
+    private com.github.javaparser.ast.body.AnnotationMemberDeclaration wrappedNode;
+    private TypeSolver typeSolver;
+
+    public AnnotationMemberDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+
+    public JavaParserAnnotationMemberDeclaration(AnnotationMemberDeclaration wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public Expression getDefaultValue() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResolvedType getType() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getNameAsString();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java
new file mode 100644
index 0000000..3d2cb8f
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration.java
@@ -0,0 +1,205 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * An anonymous class declaration representation.
+ */
+public class JavaParserAnonymousClassDeclaration extends AbstractClassDeclaration {
+
+  private final TypeSolver typeSolver;
+  private final ObjectCreationExpr wrappedNode;
+  private final ResolvedTypeDeclaration superTypeDeclaration;
+  private final String name = "Anonymous-" + UUID.randomUUID();
+
+  public JavaParserAnonymousClassDeclaration(ObjectCreationExpr wrappedNode,
+                                             TypeSolver typeSolver) {
+    this.typeSolver = typeSolver;
+    this.wrappedNode = wrappedNode;
+    superTypeDeclaration =
+        JavaParserFactory.getContext(wrappedNode.getParentNode().get(), typeSolver)
+                         .solveType(wrappedNode.getType().getName().getId(), typeSolver)
+                         .getCorrespondingDeclaration();
+  }
+
+  public ResolvedTypeDeclaration getSuperTypeDeclaration() {
+    return superTypeDeclaration;
+  }
+
+  public <T extends Node> List<T> findMembersOfKind(final Class<T> memberClass) {
+    if (wrappedNode.getAnonymousClassBody().isPresent()) {
+      return wrappedNode
+              .getAnonymousClassBody()
+              .get()
+              .stream()
+              .filter(node -> memberClass.isAssignableFrom(node.getClass()))
+              .map(memberClass::cast)
+              .collect(Collectors.toList());
+    } else {
+      return Collections.emptyList();
+    }
+  }
+  
+  public Context getContext() {
+      return JavaParserFactory.getContext(wrappedNode, typeSolver);
+  }
+
+  @Override
+  protected ResolvedReferenceType object() {
+    return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+  }
+
+  @Override
+  public ResolvedReferenceType getSuperClass() {
+    return new ReferenceTypeImpl(superTypeDeclaration.asReferenceType(), typeSolver);
+  }
+
+  @Override
+  public List<ResolvedReferenceType> getInterfaces() {
+    return
+        superTypeDeclaration
+            .asReferenceType().getAncestors()
+            .stream()
+            .filter(type -> type.getTypeDeclaration().isInterface())
+            .collect(Collectors.toList());
+  }
+
+  @Override
+  public List<ResolvedConstructorDeclaration> getConstructors() {
+    return
+        findMembersOfKind(com.github.javaparser.ast.body.ConstructorDeclaration.class)
+            .stream()
+            .map(ctor -> new JavaParserConstructorDeclaration(this, ctor, typeSolver))
+            .collect(Collectors.toList());
+  }
+
+  @Override
+  public AccessSpecifier accessSpecifier() {
+    return AccessSpecifier.PRIVATE;
+  }
+
+  @Override
+  public List<ResolvedReferenceType> getAncestors() {
+    return
+        ImmutableList.
+            <ResolvedReferenceType>builder()
+            .add(getSuperClass())
+            .addAll(superTypeDeclaration.asReferenceType().getAncestors())
+            .build();
+  }
+
+  @Override
+  public List<ResolvedFieldDeclaration> getAllFields() {
+
+    List<JavaParserFieldDeclaration> myFields =
+        findMembersOfKind(com.github.javaparser.ast.body.FieldDeclaration.class)
+            .stream()
+            .flatMap(field ->
+                         field.getVariables().stream()
+                              .map(variable -> new JavaParserFieldDeclaration(variable,
+                                                                              typeSolver)))
+            .collect(Collectors.toList());
+
+    List<ResolvedFieldDeclaration> superClassFields =
+        getSuperClass().getTypeDeclaration().getAllFields();
+
+    List<ResolvedFieldDeclaration> interfaceFields =
+        getInterfaces().stream()
+                       .flatMap(inteface -> inteface.getTypeDeclaration().getAllFields().stream())
+                       .collect(Collectors.toList());
+
+    return
+        ImmutableList
+        .<ResolvedFieldDeclaration>builder()
+        .addAll(myFields)
+        .addAll(superClassFields)
+        .addAll(interfaceFields)
+        .build();
+  }
+
+  @Override
+  public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+    return
+        findMembersOfKind(com.github.javaparser.ast.body.MethodDeclaration.class)
+            .stream()
+            .map(method -> new JavaParserMethodDeclaration(method, typeSolver))
+            .collect(Collectors.toSet());
+  }
+
+  @Override
+  public boolean isAssignableBy(ResolvedType type) {
+    return false;
+  }
+
+  @Override
+  public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+    return false;
+  }
+
+  @Override
+  public boolean hasDirectlyAnnotation(String qualifiedName) {
+    return false;
+  }
+
+  @Override
+  public String getPackageName() {
+    return Helper.getPackageName(wrappedNode);
+  }
+
+  @Override
+  public String getClassName() {
+    return Helper.getClassName("", wrappedNode);
+  }
+
+  @Override
+  public String getQualifiedName() {
+    String containerName = Helper.containerName(wrappedNode.getParentNode().orElse(null));
+    if (containerName.isEmpty()) {
+      return getName();
+    } else {
+      return containerName + "." + getName();
+    }
+  }
+
+  @Override
+  public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+    return
+        findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class)
+            .stream()
+            .map(typeMember -> JavaParserFacade.get(typeSolver).getTypeDeclaration(typeMember))
+            .collect(Collectors.toSet());
+  }
+
+  @Override
+  public String getName() {
+    return name;
+  }
+
+  @Override
+  public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+    return Lists.newArrayList();
+  }
+
+  @Override
+  public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+    throw new UnsupportedOperationException("containerType is not supported for " + this.getClass().getCanonicalName());
+  }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java
new file mode 100644
index 0000000..bb9f91c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration.java
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.LazyType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import com.google.common.collect.ImmutableList;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserClassDeclaration extends AbstractClassDeclaration {
+
+    ///
+    /// Fields
+    ///
+
+    private TypeSolver typeSolver;
+    private com.github.javaparser.ast.body.ClassOrInterfaceDeclaration wrappedNode;
+    private JavaParserTypeAdapter<ClassOrInterfaceDeclaration> javaParserTypeAdapter;
+
+    ///
+    /// Constructors
+    ///
+
+    public JavaParserClassDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration wrappedNode,
+                                      TypeSolver typeSolver) {
+        if (wrappedNode.isInterface()) {
+            throw new IllegalArgumentException("Interface given");
+        }
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+        this.javaParserTypeAdapter = new JavaParserTypeAdapter<>(wrappedNode, typeSolver);
+    }
+
+    ///
+    /// Public methods: from Object
+    ///
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavaParserClassDeclaration that = (JavaParserClassDeclaration) o;
+
+        if (!wrappedNode.equals(that.wrappedNode)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return wrappedNode.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "JavaParserClassDeclaration{" +
+                "wrappedNode=" + wrappedNode +
+                '}';
+    }
+
+    ///
+    /// Public methods: fields
+    ///
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        List<ResolvedFieldDeclaration> fields = javaParserTypeAdapter.getFieldsForDeclaredVariables();
+        
+        getAncestors().forEach(ancestor -> ancestor.getTypeDeclaration().getAllFields().forEach(f -> {
+            fields.add(new ResolvedFieldDeclaration() {
+                
+                @Override
+                public AccessSpecifier accessSpecifier() {
+                    return f.accessSpecifier();
+                }
+                
+                @Override
+                public String getName() {
+                    return f.getName();
+                }
+                
+                @Override
+                public ResolvedType getType() {
+                    return ancestor.useThisTypeParametersOnTheGivenType(f.getType());
+                }
+                
+                @Override
+                public boolean isStatic() {
+                    return f.isStatic();
+                }
+                
+                @Override
+                public ResolvedTypeDeclaration declaringType() {
+                    return f.declaringType();
+                }
+            });
+        }));
+        
+        return fields;
+    }
+    
+    ///
+    /// Public methods
+    ///
+
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes) {
+        Context ctx = getContext();
+        return ctx.solveMethod(name, parameterTypes, false, typeSolver);
+    }
+
+    @Deprecated
+    public Context getContext() {
+        return JavaParserFactory.getContext(wrappedNode, typeSolver);
+    }
+
+    public ResolvedType getUsage(Node node) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public ResolvedReferenceType getSuperClass() {
+        if (wrappedNode.getExtendedTypes().isEmpty()) {
+            return object();
+        } else {
+            return toReferenceType(wrappedNode.getExtendedTypes().get(0));
+        }
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getInterfaces() {
+        List<ResolvedReferenceType> interfaces = new ArrayList<>();
+        if (wrappedNode.getImplementedTypes() != null) {
+            for (ClassOrInterfaceType t : wrappedNode.getImplementedTypes()) {
+                interfaces.add(toReferenceType(t));
+            }
+        }
+        return interfaces;
+    }
+
+    @Override
+    public List<ResolvedConstructorDeclaration> getConstructors() {
+        List<ResolvedConstructorDeclaration> declared = new LinkedList<>();
+        for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.ConstructorDeclaration) {
+                com.github.javaparser.ast.body.ConstructorDeclaration constructorDeclaration = (com.github.javaparser.ast.body.ConstructorDeclaration) member;
+                declared.add(new JavaParserConstructorDeclaration(this, constructorDeclaration, typeSolver));
+            }
+        }
+        if (declared.isEmpty()) {
+            // If there are no constructors insert the default constructor
+            return ImmutableList.of(new DefaultConstructorDeclaration(this));
+        } else {
+            return declared;
+        }
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        for (AnnotationExpr annotationExpr : wrappedNode.getAnnotations()) {
+            if (solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return wrappedNode.isInterface();
+    }
+
+    @Override
+    public String getPackageName() {
+        return javaParserTypeAdapter.getPackageName();
+    }
+
+    @Override
+    public String getClassName() {
+        return javaParserTypeAdapter.getClassName();
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return javaParserTypeAdapter.getQualifiedName();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return javaParserTypeAdapter.isAssignableBy(other);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        return javaParserTypeAdapter.isAssignableBy(type);
+    }
+
+    @Override
+    public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+        // TODO consider generic types
+        if (this.getQualifiedName().equals(other.getQualifiedName())) {
+            return true;
+        }
+        ResolvedClassDeclaration superclass = (ResolvedClassDeclaration) getSuperClass().getTypeDeclaration();
+        if (superclass != null) {
+            // We want to avoid infinite recursion in case of Object having Object as ancestor
+            if (Object.class.getCanonicalName().equals(superclass.getQualifiedName())) {
+                return true;
+            }
+            if (superclass.canBeAssignedTo(other)) {
+                return true;
+            }
+        }
+
+        if (this.wrappedNode.getImplementedTypes() != null) {
+            for (ClassOrInterfaceType type : wrappedNode.getImplementedTypes()) {
+                ResolvedReferenceTypeDeclaration ancestor = (ResolvedReferenceTypeDeclaration) new SymbolSolver(typeSolver).solveType(type);
+                if (ancestor.canBeAssignedTo(other)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return false;
+    }
+
+    @Deprecated
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        if (this.wrappedNode.getName().getId().equals(name)) {
+            return SymbolReference.solved(this);
+        }
+        SymbolReference<ResolvedTypeDeclaration> ref = javaParserTypeAdapter.solveType(name, typeSolver);
+        if (ref.isSolved()) {
+            return ref;
+        }
+
+        String prefix = wrappedNode.getName() + ".";
+        if (name.startsWith(prefix) && name.length() > prefix.length()) {
+            return new JavaParserClassDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
+        }
+
+        return getContext().getParent().solveType(name, typeSolver);
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        List<ResolvedReferenceType> ancestors = new ArrayList<>();
+
+        // We want to avoid infinite recursion in case of Object having Object as ancestor
+        if (!(Object.class.getCanonicalName().equals(getQualifiedName()))) {
+            ResolvedReferenceType superclass = getSuperClass();
+            if (superclass != null) {
+                ancestors.add(superclass);
+            }
+            if (wrappedNode.getImplementedTypes() != null) {
+                for (ClassOrInterfaceType implemented : wrappedNode.getImplementedTypes()) {
+                    ResolvedReferenceType ancestor = toReferenceType(implemented);
+                    ancestors.add(ancestor);
+                }
+            }
+        }
+
+        return ancestors;
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        Set<ResolvedMethodDeclaration> methods = new HashSet<>();
+        for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+                methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver));
+            }
+        }
+        return methods;
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return this.wrappedNode.getTypeParameters().stream().map(
+                (tp) -> new JavaParserTypeParameter(tp, typeSolver)
+        ).collect(Collectors.toList());
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserClassDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public com.github.javaparser.ast.body.ClassOrInterfaceDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return Helper.toAccessLevel(wrappedNode.getModifiers());
+    }
+
+    ///
+    /// Protected methods
+    ///
+
+    @Override
+    protected ResolvedReferenceType object() {
+        return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+    }
+
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        Set<ResolvedReferenceTypeDeclaration> res = new HashSet<>();
+        for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+                res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration)member));
+            }
+        }
+        return res;
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return javaParserTypeAdapter.containerType();
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterfaceType) {
+        String className = classOrInterfaceType.getName().getId();
+        if (classOrInterfaceType.getScope().isPresent()) {
+            // look for the qualified name (for example class of type Rectangle2D.Double)
+            className = classOrInterfaceType.getScope().get().toString() + "." + className;
+        }
+        SymbolReference<ResolvedTypeDeclaration> ref = solveType(className, typeSolver);
+        if (!ref.isSolved()) {
+            Optional<ClassOrInterfaceType> localScope = classOrInterfaceType.getScope();
+            if (localScope.isPresent()) {
+                String localName = localScope.get().getName().getId() + "." + classOrInterfaceType.getName().getId();
+                ref = solveType(localName, typeSolver);
+            }
+        }
+        if (!ref.isSolved()) {
+            throw new UnsolvedSymbolException(classOrInterfaceType.getName().getId());
+        }
+        if (!classOrInterfaceType.getTypeArguments().isPresent()) {
+            return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), typeSolver);
+        }
+        List<ResolvedType> superClassTypeParameters = classOrInterfaceType.getTypeArguments().get()
+                .stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta)))
+                .collect(Collectors.toList());
+        return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java
new file mode 100644
index 0000000..e9500fe
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserConstructorDeclaration implements ResolvedConstructorDeclaration {
+
+    private ResolvedClassDeclaration classDeclaration;
+    private com.github.javaparser.ast.body.ConstructorDeclaration wrappedNode;
+    private TypeSolver typeSolver;
+
+    JavaParserConstructorDeclaration(ResolvedClassDeclaration classDeclaration, com.github.javaparser.ast.body.ConstructorDeclaration wrappedNode,
+                                     TypeSolver typeSolver) {
+        this.classDeclaration = classDeclaration;
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public ResolvedClassDeclaration declaringType() {
+        return classDeclaration;
+    }
+
+    @Override
+    public int getNumberOfParams() {
+        return this.wrappedNode.getParameters().size();
+    }
+
+    @Override
+    public ResolvedParameterDeclaration getParam(int i) {
+        if (i < 0 || i >= getNumberOfParams()) {
+            throw new IllegalArgumentException(String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()));
+        }
+        return new JavaParserParameterDeclaration(wrappedNode.getParameters().get(i), typeSolver);
+    }
+
+    @Override
+    public String getName() {
+        return this.classDeclaration.getName();
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserConstructorDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public com.github.javaparser.ast.body.ConstructorDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+    
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return Helper.toAccessLevel(wrappedNode.getModifiers());
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)).collect(Collectors.toList());
+    }
+
+    @Override
+    public int getNumberOfSpecifiedExceptions() {
+        return wrappedNode.getThrownExceptions().size();
+    }
+
+    @Override
+    public ResolvedType getSpecifiedException(int index) {
+        if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+            throw new IllegalArgumentException(String.format("No exception with index %d. Number of exceptions: %d",
+                    index, getNumberOfSpecifiedExceptions()));
+        }
+        return JavaParserFacade.get(typeSolver)
+                .convert(wrappedNode.getThrownExceptions().get(index), wrappedNode);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java
new file mode 100644
index 0000000..6f90958
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserEnumConstantDeclaration implements ResolvedEnumConstantDeclaration {
+
+    private TypeSolver typeSolver;
+    private com.github.javaparser.ast.body.EnumConstantDeclaration wrappedNode;
+
+    public JavaParserEnumConstantDeclaration(com.github.javaparser.ast.body.EnumConstantDeclaration wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public ResolvedType getType() {
+        return new ReferenceTypeImpl(new JavaParserEnumDeclaration((EnumDeclaration) requireParentNode(wrappedNode), typeSolver), typeSolver);
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserEnumConstantDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public com.github.javaparser.ast.body.EnumConstantDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java
new file mode 100644
index 0000000..818c060
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserEnumDeclaration extends AbstractTypeDeclaration implements ResolvedEnumDeclaration {
+
+    private TypeSolver typeSolver;
+    private com.github.javaparser.ast.body.EnumDeclaration wrappedNode;
+    private JavaParserTypeAdapter<com.github.javaparser.ast.body.EnumDeclaration> javaParserTypeAdapter;
+
+    public JavaParserEnumDeclaration(com.github.javaparser.ast.body.EnumDeclaration wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+        this.javaParserTypeAdapter = new JavaParserTypeAdapter<>(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public String toString() {
+        return "JavaParserEnumDeclaration{" +
+                "wrappedNode=" + wrappedNode +
+                '}';
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        Set<ResolvedMethodDeclaration> methods = new HashSet<>();
+        for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+                methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver));
+            }
+        }
+        return methods;
+    }
+
+    public Context getContext() {
+        return JavaParserFactory.getContext(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean isType() {
+        return true;
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+        String otherName = other.getQualifiedName();
+        // Enums cannot be extended
+        if (otherName.equals(this.getQualifiedName())) {
+            return true;
+        }
+        if (otherName.equals(Enum.class.getCanonicalName())) {
+            return true;
+        }
+        // Enum implements Comparable and Serializable
+        if (otherName.equals(Comparable.class.getCanonicalName())) {
+            return true;
+        }
+        if (otherName.equals(Serializable.class.getCanonicalName())) {
+            return true;
+        }
+        if (otherName.equals(Object.class.getCanonicalName())) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isClass() {
+        return false;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return false;
+    }
+
+    @Override
+    public String getPackageName() {
+        return javaParserTypeAdapter.getPackageName();
+    }
+
+    @Override
+    public String getClassName() {
+        return javaParserTypeAdapter.getClassName();
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return javaParserTypeAdapter.getQualifiedName();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return javaParserTypeAdapter.isAssignableBy(other);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        return javaParserTypeAdapter.isAssignableBy(type);
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavaParserEnumDeclaration that = (JavaParserEnumDeclaration) o;
+
+        if (!wrappedNode.equals(that.wrappedNode)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return wrappedNode.hashCode();
+    }
+
+    @Deprecated
+    public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> parameterTypes,
+                                                    TypeSolver typeSolver, Context invokationContext, List<ResolvedType> typeParameterValues) {
+        if (name.equals("values") && parameterTypes.isEmpty()) {
+            return Optional.of(new ValuesMethod(this, typeSolver).getUsage(null));
+        }
+        // TODO add methods inherited from Enum
+        return getContext().solveMethodAsUsage(name, parameterTypes, typeSolver);
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        List<ResolvedFieldDeclaration> fields = javaParserTypeAdapter.getFieldsForDeclaredVariables();
+
+        if (this.wrappedNode.getEntries() != null) {
+            for (EnumConstantDeclaration member : this.wrappedNode.getEntries()) {
+                fields.add(new JavaParserFieldDeclaration(member, typeSolver));
+            }
+        }
+
+        return fields;
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        List<ResolvedReferenceType> ancestors = new ArrayList<>();
+        ResolvedReferenceType enumClass = ReflectionFactory.typeUsageFor(Enum.class, typeSolver).asReferenceType();
+        ResolvedTypeParameterDeclaration eTypeParameter = enumClass.getTypeDeclaration().getTypeParameters().get(0);
+        enumClass = enumClass.deriveTypeParameters(new ResolvedTypeParametersMap.Builder().setValue(eTypeParameter, new ReferenceTypeImpl(this, typeSolver)).build());
+        ancestors.add(enumClass);
+        if (wrappedNode.getImplementedTypes() != null) {
+            for (ClassOrInterfaceType implementedType : wrappedNode.getImplementedTypes()) {
+                SymbolReference<ResolvedTypeDeclaration> implementedDeclRef = new SymbolSolver(typeSolver).solveTypeInType(this, implementedType.getName().getId());
+                if (!implementedDeclRef.isSolved()) {
+                    throw new UnsolvedSymbolException(implementedType.getName().getId());
+                }
+                ancestors.add(new ReferenceTypeImpl((ResolvedReferenceTypeDeclaration) implementedDeclRef.getCorrespondingDeclaration(), typeSolver));
+            }
+        }
+        return ancestors;
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserEnumDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public com.github.javaparser.ast.body.EnumDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+
+    @Override
+    public List<ResolvedEnumConstantDeclaration> getEnumConstants() {
+        return wrappedNode.getEntries().stream()
+                .map(entry -> new JavaParserEnumConstantDeclaration(entry, typeSolver))
+                .collect(Collectors.toList());
+    }
+
+    // Needed by ContextHelper
+    public static class ValuesMethod implements ResolvedMethodDeclaration {
+
+        private JavaParserEnumDeclaration enumDeclaration;
+        private TypeSolver typeSolver;
+
+        public ValuesMethod(JavaParserEnumDeclaration enumDeclaration, TypeSolver typeSolver) {
+            this.enumDeclaration = enumDeclaration;
+            this.typeSolver = typeSolver;
+        }
+
+        @Override
+        public ResolvedReferenceTypeDeclaration declaringType() {
+            return enumDeclaration;
+        }
+
+        @Override
+        public ResolvedType getReturnType() {
+            return new ResolvedArrayType(new ReferenceTypeImpl(enumDeclaration, typeSolver));
+        }
+
+        @Override
+        public int getNumberOfParams() {
+            return 0;
+        }
+
+        @Override
+        public ResolvedParameterDeclaration getParam(int i) {
+            throw new UnsupportedOperationException();
+        }
+
+        public MethodUsage getUsage(Node node) {
+            throw new UnsupportedOperationException();
+        }
+
+        public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
+            return new MethodUsage(this);
+        }
+
+        @Override
+        public boolean isAbstract() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isDefaultMethod() {
+            return false;
+        }
+
+        @Override
+        public boolean isStatic() {
+            return false;
+        }
+
+        @Override
+        public String getName() {
+            return "values";
+        }
+
+        @Override
+        public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public AccessSpecifier accessSpecifier() {
+            return Helper.toAccessLevel(enumDeclaration.getWrappedNode().getModifiers());
+        }
+
+        @Override
+        public int getNumberOfSpecifiedExceptions() {
+            return 0;
+        }
+
+        @Override
+        public ResolvedType getSpecifiedException(int index) {
+            throw new UnsupportedOperationException("The values method of an enum does not throw any exception");
+        }
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        Set<ResolvedReferenceTypeDeclaration> res = new HashSet<>();
+        for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+                res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration)member));
+            }
+        }
+        return res;
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return javaParserTypeAdapter.containerType();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java
new file mode 100644
index 0000000..1c9e005
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserFieldDeclaration implements ResolvedFieldDeclaration {
+
+    private VariableDeclarator variableDeclarator;
+    private com.github.javaparser.ast.body.FieldDeclaration wrappedNode;
+    private EnumConstantDeclaration enumConstantDeclaration;
+    private TypeSolver typeSolver;
+
+    public JavaParserFieldDeclaration(VariableDeclarator variableDeclarator, TypeSolver typeSolver) {
+        if (typeSolver == null) {
+            throw new IllegalArgumentException("typeSolver should not be null");
+        }
+        this.variableDeclarator = variableDeclarator;
+        this.typeSolver = typeSolver;
+        if (!(requireParentNode(variableDeclarator) instanceof com.github.javaparser.ast.body.FieldDeclaration)) {
+            throw new IllegalStateException(requireParentNode(variableDeclarator).getClass().getCanonicalName());
+        }
+        this.wrappedNode = (com.github.javaparser.ast.body.FieldDeclaration) requireParentNode(variableDeclarator);
+    }
+
+    public JavaParserFieldDeclaration(EnumConstantDeclaration enumConstantDeclaration, TypeSolver typeSolver) {
+        if (typeSolver == null) {
+            throw new IllegalArgumentException("typeSolver should not be null");
+        }
+        this.enumConstantDeclaration = enumConstantDeclaration;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public ResolvedType getType() {
+        if (enumConstantDeclaration != null) {
+            com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = (com.github.javaparser.ast.body.EnumDeclaration) requireParentNode(enumConstantDeclaration);
+            return new ReferenceTypeImpl(new JavaParserEnumDeclaration(enumDeclaration, typeSolver), typeSolver);
+        }
+        return JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), wrappedNode);
+    }
+
+    @Override
+    public String getName() {
+        if (enumConstantDeclaration != null) {
+            return enumConstantDeclaration.getName().getId();
+        } else {
+            return variableDeclarator.getName().getId();
+        }
+    }
+
+    @Override
+    public boolean isStatic() {
+        return wrappedNode.getModifiers().contains(Modifier.STATIC);
+    }
+
+    @Override
+    public boolean isField() {
+        return true;
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserFieldDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public com.github.javaparser.ast.body.FieldDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+
+    @Override
+    public String toString() {
+        return "JPField{" + getName() + "}";
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return Helper.toAccessLevel(wrappedNode.getModifiers());
+    }
+
+    @Override
+    public ResolvedTypeDeclaration declaringType() {
+        Optional<com.github.javaparser.ast.body.TypeDeclaration> typeDeclaration = wrappedNode.findParent(com.github.javaparser.ast.body.TypeDeclaration.class);
+        if (typeDeclaration.isPresent()) {
+            return JavaParserFacade.get(typeSolver).getTypeDeclaration(typeDeclaration.get());
+        }
+        throw new IllegalStateException();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java
new file mode 100644
index 0000000..34955a0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.LazyType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserInterfaceDeclaration extends AbstractTypeDeclaration implements ResolvedInterfaceDeclaration {
+
+    private TypeSolver typeSolver;
+    private ClassOrInterfaceDeclaration wrappedNode;
+    private JavaParserTypeAdapter<ClassOrInterfaceDeclaration> javaParserTypeAdapter;
+
+    public JavaParserInterfaceDeclaration(ClassOrInterfaceDeclaration wrappedNode, TypeSolver typeSolver) {
+        if (!wrappedNode.isInterface()) {
+            throw new IllegalArgumentException();
+        }
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+        this.javaParserTypeAdapter = new JavaParserTypeAdapter<>(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        Set<ResolvedMethodDeclaration> methods = new HashSet<>();
+        for (BodyDeclaration<?> member : wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.MethodDeclaration) {
+                methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver));
+            }
+        }
+        return methods;
+    }
+
+    public Context getContext() {
+        return JavaParserFactory.getContext(wrappedNode, typeSolver);
+    }
+
+    public ResolvedType getUsage(Node node) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavaParserInterfaceDeclaration that = (JavaParserInterfaceDeclaration) o;
+
+        if (!wrappedNode.equals(that.wrappedNode)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return wrappedNode.hashCode();
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public ResolvedInterfaceDeclaration asInterface() {
+        return this;
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        for (AnnotationExpr annotationExpr : wrappedNode.getAnnotations()) {
+            if (solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return true;
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getInterfacesExtended() {
+        List<ResolvedReferenceType> interfaces = new ArrayList<>();
+        if (wrappedNode.getImplementedTypes() != null) {
+            for (ClassOrInterfaceType t : wrappedNode.getImplementedTypes()) {
+                interfaces.add(new ReferenceTypeImpl(solveType(t.getName().getId(), typeSolver).getCorrespondingDeclaration().asInterface(), typeSolver));
+            }
+        }
+        return interfaces;
+    }
+
+    @Override
+    public String getPackageName() {
+        return javaParserTypeAdapter.getPackageName();
+    }
+
+    @Override
+    public String getClassName() {
+        return javaParserTypeAdapter.getClassName();
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return javaParserTypeAdapter.getQualifiedName();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return javaParserTypeAdapter.isAssignableBy(other);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        return javaParserTypeAdapter.isAssignableBy(type);
+    }
+
+    @Override
+    public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+        // TODO consider generic types
+        if (this.getQualifiedName().equals(other.getQualifiedName())) {
+            return true;
+        }
+        if (this.wrappedNode.getExtendedTypes() != null) {
+            for (ClassOrInterfaceType type : wrappedNode.getExtendedTypes()) {
+                ResolvedReferenceTypeDeclaration ancestor = (ResolvedReferenceTypeDeclaration) new SymbolSolver(typeSolver).solveType(type);
+                if (ancestor.canBeAssignedTo(other)) {
+                    return true;
+                }
+            }
+        }
+
+        if (this.wrappedNode.getImplementedTypes() != null) {
+            for (ClassOrInterfaceType type : wrappedNode.getImplementedTypes()) {
+                ResolvedReferenceTypeDeclaration ancestor = (ResolvedReferenceTypeDeclaration) new SymbolSolver(typeSolver).solveType(type);
+                if (ancestor.canBeAssignedTo(other)) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return false;
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        List<ResolvedFieldDeclaration> fields = javaParserTypeAdapter.getFieldsForDeclaredVariables();
+        
+        getAncestors().forEach(ancestor -> ancestor.getTypeDeclaration().getAllFields().forEach(f -> {
+            fields.add(new ResolvedFieldDeclaration() {
+                
+                @Override
+                public AccessSpecifier accessSpecifier() {
+                    return f.accessSpecifier();
+                }
+                
+                @Override
+                public String getName() {
+                    return f.getName();
+                }
+                
+                @Override
+                public ResolvedType getType() {
+                    return ancestor.useThisTypeParametersOnTheGivenType(f.getType());
+                }
+                
+                @Override
+                public boolean isStatic() {
+                    return f.isStatic();
+                }
+                
+                @Override
+                public ResolvedTypeDeclaration declaringType() {
+                    return f.declaringType();
+                }
+            });
+        }));
+        
+        return fields;
+    }
+
+
+    @Override
+    public String toString() {
+        return "JavaParserInterfaceDeclaration{" +
+                "wrappedNode=" + wrappedNode +
+                '}';
+    }
+
+    @Deprecated
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        if (this.wrappedNode.getName().getId().equals(name)) {
+            return SymbolReference.solved(this);
+        }
+        SymbolReference<ResolvedTypeDeclaration> ref = javaParserTypeAdapter.solveType(name, typeSolver);
+        if (ref.isSolved()) {
+            return ref;
+        }
+
+        String prefix = wrappedNode.getName() + ".";
+        if (name.startsWith(prefix) && name.length() > prefix.length()) {
+            return new JavaParserInterfaceDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
+        }
+
+        return getContext().getParent().solveType(name, typeSolver);
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        List<ResolvedReferenceType> ancestors = new ArrayList<>();
+        if (wrappedNode.getExtendedTypes() != null) {
+            for (ClassOrInterfaceType extended : wrappedNode.getExtendedTypes()) {
+                ancestors.add(toReferenceType(extended));
+            }
+        }
+        if (wrappedNode.getImplementedTypes() != null) {
+            for (ClassOrInterfaceType implemented : wrappedNode.getImplementedTypes()) {
+                ancestors.add(toReferenceType(implemented));
+            }
+        }
+        return ancestors;
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        if (this.wrappedNode.getTypeParameters() == null) {
+            return Collections.emptyList();
+        } else {
+            return this.wrappedNode.getTypeParameters().stream().map(
+                    (tp) -> new JavaParserTypeParameter(tp, typeSolver)
+            ).collect(Collectors.toList());
+        }
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserInterfaceDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public ClassOrInterfaceDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return Helper.toAccessLevel(wrappedNode.getModifiers());
+    }
+
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        Set<ResolvedReferenceTypeDeclaration> res = new HashSet<>();
+        for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+                res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration)member));
+            }
+        }
+        return res;
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return javaParserTypeAdapter.containerType();
+    }
+
+    ///
+    /// Private methods
+    ///
+
+    private ResolvedReferenceType toReferenceType(ClassOrInterfaceType classOrInterfaceType) {
+        SymbolReference<? extends ResolvedTypeDeclaration> ref = null;
+        if (classOrInterfaceType.toString().indexOf('.') > -1) {
+            ref = typeSolver.tryToSolveType(classOrInterfaceType.toString());
+        }
+        if (ref == null || !ref.isSolved()) {
+            ref = solveType(classOrInterfaceType.toString(), typeSolver);
+        }
+        if (!ref.isSolved()) {
+            ref = solveType(classOrInterfaceType.getName().getId(), typeSolver);
+        }
+        if (!ref.isSolved()) {
+            throw new UnsolvedSymbolException(classOrInterfaceType.getName().getId());
+        }
+        if (!classOrInterfaceType.getTypeArguments().isPresent()) {
+            return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), typeSolver);
+        }
+        List<ResolvedType> superClassTypeParameters = classOrInterfaceType.getTypeArguments().get()
+                .stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta)))
+                .collect(Collectors.toList());
+        return new ReferenceTypeImpl(ref.getCorrespondingDeclaration().asReferenceType(), superClassTypeParameters, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java
new file mode 100644
index 0000000..4f3cb35
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserMethodDeclaration implements ResolvedMethodDeclaration {
+
+    private com.github.javaparser.ast.body.MethodDeclaration wrappedNode;
+    private TypeSolver typeSolver;
+
+    public JavaParserMethodDeclaration(com.github.javaparser.ast.body.MethodDeclaration wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public String toString() {
+        return "JavaParserMethodDeclaration{" +
+                "wrappedNode=" + wrappedNode +
+                ", typeSolver=" + typeSolver +
+                '}';
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration declaringType() {
+        if (requireParentNode(wrappedNode) instanceof ObjectCreationExpr) {
+            ObjectCreationExpr parentNode = (ObjectCreationExpr) requireParentNode(wrappedNode);
+            return new JavaParserAnonymousClassDeclaration(parentNode, typeSolver);
+        }
+        return JavaParserFactory.toTypeDeclaration(requireParentNode(wrappedNode), typeSolver);
+    }
+
+    @Override
+    public ResolvedType getReturnType() {
+        return JavaParserFacade.get(typeSolver).convert(wrappedNode.getType(), getContext());
+    }
+
+    @Override
+    public int getNumberOfParams() {
+        return wrappedNode.getParameters().size();
+    }
+
+    @Override
+    public ResolvedParameterDeclaration getParam(int i) {
+        if (i < 0 || i >= getNumberOfParams()) {
+            throw new IllegalArgumentException(String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()));
+        }
+        return new JavaParserParameterDeclaration(wrappedNode.getParameters().get(i), typeSolver);
+    }
+
+    public MethodUsage getUsage(Node node) {
+        throw new UnsupportedOperationException();
+    }
+
+    public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
+        return new MethodDeclarationCommonLogic(this, typeSolver).resolveTypeVariables(context, parameterTypes);
+    }
+
+    private Context getContext() {
+        return JavaParserFactory.getContext(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return !wrappedNode.getBody().isPresent();
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public boolean isField() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isParameter() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isType() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)).collect(Collectors.toList());
+    }
+
+    @Override
+    public boolean isDefaultMethod() {
+        return wrappedNode.isDefault();
+    }
+
+    @Override
+    public boolean isStatic() {
+        return wrappedNode.isStatic();
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserMethodDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public com.github.javaparser.ast.body.MethodDeclaration getWrappedNode() {
+        return wrappedNode;
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return Helper.toAccessLevel(wrappedNode.getModifiers());
+    }
+
+    @Override
+    public int getNumberOfSpecifiedExceptions() {
+        return wrappedNode.getThrownExceptions().size();
+    }
+
+    @Override
+    public ResolvedType getSpecifiedException(int index) {
+        if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+            throw new IllegalArgumentException(String.format("No exception with index %d. Number of exceptions: %d",
+                    index, getNumberOfSpecifiedExceptions()));
+        }
+        return JavaParserFacade.get(typeSolver).convert(wrappedNode.getThrownExceptions()
+                .get(index), wrappedNode);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java
new file mode 100644
index 0000000..cba7d32
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.LambdaExprContext;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserParameterDeclaration implements ResolvedParameterDeclaration {
+
+    private Parameter wrappedNode;
+    private TypeSolver typeSolver;
+
+    public JavaParserParameterDeclaration(Parameter wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return true;
+    }
+
+    @Override
+    public boolean isVariadic() {
+        return wrappedNode.isVarArgs();
+    }
+
+    @Override
+    public boolean isType() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResolvedType getType() {
+        if (wrappedNode.getType() instanceof UnknownType && JavaParserFactory.getContext(wrappedNode, typeSolver) instanceof LambdaExprContext) {
+            Optional<Value> value = JavaParserFactory.getContext(wrappedNode, typeSolver).solveSymbolAsValue(wrappedNode.getNameAsString(), typeSolver);
+            if (value.isPresent()) {
+                return value.get().getType();
+            }
+        }
+        ResolvedType res = JavaParserFacade.get(typeSolver).convert(wrappedNode.getType(), wrappedNode);
+        if (isVariadic()) {
+            res = new ResolvedArrayType(res);
+        }
+        return res;
+    }
+
+    @Override
+    public ResolvedParameterDeclaration asParameter() {
+        return this;
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserParameterDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public Parameter getWrappedNode() {
+        return wrappedNode;
+    }
+
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java
new file mode 100644
index 0000000..f1f1ffb
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserSymbolDeclaration implements ResolvedValueDeclaration {
+
+    private String name;
+    private Node wrappedNode;
+    private boolean field;
+    private boolean parameter;
+    private boolean variable;
+    private TypeSolver typeSolver;
+
+    private JavaParserSymbolDeclaration(Node wrappedNode, String name, TypeSolver typeSolver, boolean field, boolean parameter, boolean variable) {
+        this.name = name;
+        this.wrappedNode = wrappedNode;
+        this.field = field;
+        this.variable = variable;
+        this.parameter = parameter;
+        this.typeSolver = typeSolver;
+    }
+
+    public static JavaParserFieldDeclaration field(VariableDeclarator wrappedNode, TypeSolver typeSolver) {
+        return new JavaParserFieldDeclaration(wrappedNode, typeSolver);
+    }
+
+    public static JavaParserParameterDeclaration parameter(Parameter parameter, TypeSolver typeSolver) {
+        return new JavaParserParameterDeclaration(parameter, typeSolver);
+    }
+
+    public static JavaParserSymbolDeclaration localVar(VariableDeclarator variableDeclarator, TypeSolver typeSolver) {
+        return new JavaParserSymbolDeclaration(variableDeclarator, variableDeclarator.getName().getId(), typeSolver, false, false, true);
+    }
+
+    public static int getParamPos(Parameter parameter) {
+        int pos = 0;
+        for (Node node : requireParentNode(parameter).getChildNodes()) {
+            if (node == parameter) {
+                return pos;
+            } else if (node instanceof Parameter) {
+                pos++;
+            }
+        }
+        return pos;
+    }
+
+    public static int getParamPos(Node node) {
+        if (requireParentNode(node) instanceof MethodCallExpr) {
+            MethodCallExpr call = (MethodCallExpr) requireParentNode(node);
+            for (int i = 0; i < call.getArguments().size(); i++) {
+                if (call.getArguments().get(i) == node) return i;
+            }
+            throw new IllegalStateException();
+        }
+        throw new IllegalArgumentException();
+    }
+
+    @Override
+    public String toString() {
+        return "JavaParserSymbolDeclaration{" +
+                "name='" + name + '\'' +
+                ", wrappedNode=" + wrappedNode +
+                '}';
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public boolean isField() {
+        return field;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return parameter;
+    }
+
+    @Override
+    public boolean isType() {
+        return false;
+    }
+
+    @Override
+    public ResolvedType getType() {
+        if (wrappedNode instanceof Parameter) {
+            Parameter parameter = (Parameter) wrappedNode;
+            if (requireParentNode(wrappedNode) instanceof LambdaExpr) {
+                int pos = getParamPos(parameter);
+                ResolvedType lambdaType = JavaParserFacade.get(typeSolver).getType(requireParentNode(wrappedNode));
+
+                // TODO understand from the context to which method this corresponds
+                //MethodDeclaration methodDeclaration = JavaParserFacade.get(typeSolver).getMethodCalled
+                //MethodDeclaration methodCalled = JavaParserFacade.get(typeSolver).solve()
+                throw new UnsupportedOperationException(wrappedNode.getClass().getCanonicalName());
+            } else {
+                final ResolvedType rawType;
+                if (parameter.getType() instanceof com.github.javaparser.ast.type.PrimitiveType) {
+                    rawType = ResolvedPrimitiveType.byName(((com.github.javaparser.ast.type.PrimitiveType) parameter.getType()).getType().name());
+                } else {
+                    rawType = JavaParserFacade.get(typeSolver).convertToUsage(parameter.getType(), wrappedNode);
+                }
+                if (parameter.isVarArgs()) {
+                    return new ResolvedArrayType(rawType);
+                }
+                return rawType;
+            }
+        } else if (wrappedNode instanceof VariableDeclarator) {
+            VariableDeclarator variableDeclarator = (VariableDeclarator) wrappedNode;
+            if (requireParentNode(wrappedNode) instanceof VariableDeclarationExpr) {
+                return JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), JavaParserFactory.getContext(wrappedNode, typeSolver));
+            } else if (requireParentNode(wrappedNode) instanceof FieldDeclaration) {
+                return JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), JavaParserFactory.getContext(wrappedNode, typeSolver));
+            }
+        }
+        throw new UnsupportedOperationException(wrappedNode.getClass().getCanonicalName());
+    }
+
+    @Override
+    public ResolvedTypeDeclaration asType() {
+        throw new UnsupportedOperationException(this.getClass().getCanonicalName() + ": wrapping " + this.getWrappedNode().getClass().getCanonicalName());
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserSymbolDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public Node getWrappedNode() {
+        return wrappedNode;
+    }
+
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java
new file mode 100644
index 0000000..198083f
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter.java
@@ -0,0 +1,140 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.nodeTypes.NodeWithMembers;
+import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeAdapter<T extends Node & NodeWithSimpleName<T> & NodeWithMembers<T>> {
+
+    private T wrappedNode;
+    private TypeSolver typeSolver;
+
+    public JavaParserTypeAdapter(T wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    public String getPackageName() {
+        return Helper.getPackageName(wrappedNode);
+    }
+
+    public String getClassName() {
+        return Helper.getClassName("", wrappedNode);
+    }
+
+    public String getQualifiedName() {
+        String containerName = Helper.containerName(getParentNode(wrappedNode));
+        if (containerName.isEmpty()) {
+            return wrappedNode.getName().getId();
+        } else {
+            return containerName + "." + wrappedNode.getName().getId();
+        }
+    }
+
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        List<ResolvedReferenceType> ancestorsOfOther = other.getAllAncestors();
+        ancestorsOfOther.add(new ReferenceTypeImpl(other, typeSolver));
+        for (ResolvedReferenceType ancestorOfOther : ancestorsOfOther) {
+            if (ancestorOfOther.getQualifiedName().equals(this.getQualifiedName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean isAssignableBy(ResolvedType type) {
+        if (type.isNull()) {
+            return true;
+        }
+        if (type.isReferenceType()) {
+            ResolvedReferenceTypeDeclaration other = typeSolver.solveType(type.describe());
+            return isAssignableBy(other);
+        } else {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public SymbolReference<ResolvedTypeDeclaration> solveType(String name, TypeSolver typeSolver) {
+        if(wrappedNode instanceof NodeWithTypeParameters<?>) {
+            NodeList<TypeParameter> typeParameters = ((NodeWithTypeParameters<?>) wrappedNode).getTypeParameters();
+            for (com.github.javaparser.ast.type.TypeParameter typeParameter : typeParameters) {
+                if (typeParameter.getName().getId().equals(name)) {
+                    return SymbolReference.solved(new JavaParserTypeVariableDeclaration(typeParameter, typeSolver));
+                }
+            }
+        }
+
+        // Internal classes
+        for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+            if (member instanceof com.github.javaparser.ast.body.TypeDeclaration) {
+                com.github.javaparser.ast.body.TypeDeclaration<?> internalType = (com.github.javaparser.ast.body.TypeDeclaration<?>) member;
+                String prefix = internalType.getName() + ".";
+                if (internalType.getName().getId().equals(name)) {
+                    if (internalType instanceof ClassOrInterfaceDeclaration) {
+                        return SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver));
+                    } else if (internalType instanceof EnumDeclaration) {
+                        return SymbolReference.solved(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver));
+                    } else {
+                        throw new UnsupportedOperationException();
+                    }
+                } else if (name.startsWith(prefix) && name.length() > prefix.length()) {
+                    if (internalType instanceof ClassOrInterfaceDeclaration) {
+                        return new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length()), typeSolver);
+                    } else if (internalType instanceof EnumDeclaration) {
+                        return new SymbolSolver(typeSolver).solveTypeInType(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver), name.substring(prefix.length()));
+                    } else {
+                        throw new UnsupportedOperationException();
+                    }
+                }
+            }
+        }
+        return SymbolReference.unsolved(ResolvedTypeDeclaration.class);
+    }
+
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return wrappedNode
+                .getParentNode()
+                .map(node -> JavaParserFactory.toTypeDeclaration(node, typeSolver));
+    }
+    
+    public List<ResolvedFieldDeclaration> getFieldsForDeclaredVariables() {
+        List<ResolvedFieldDeclaration> fields = new ArrayList<>();
+        if (wrappedNode.getMembers() != null) {
+            for (BodyDeclaration<?> member : this.wrappedNode.getMembers()) {
+                if (member instanceof com.github.javaparser.ast.body.FieldDeclaration) {
+                    com.github.javaparser.ast.body.FieldDeclaration field = (com.github.javaparser.ast.body.FieldDeclaration) member;
+                    for (VariableDeclarator vd : field.getVariables()) {
+                        fields.add(new JavaParserFieldDeclaration(vd, typeSolver));
+                    }
+                }
+            }
+        }
+        return fields;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java
new file mode 100644
index 0000000..0d1f42e
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.requireParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeParameter extends AbstractTypeDeclaration implements ResolvedTypeParameterDeclaration {
+
+    private com.github.javaparser.ast.type.TypeParameter wrappedNode;
+    private TypeSolver typeSolver;
+
+    public JavaParserTypeParameter(com.github.javaparser.ast.type.TypeParameter wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return Collections.emptySet();
+    }
+
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes) {
+        return getContext().solveMethod(name, parameterTypes, false, typeSolver);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof JavaParserTypeParameter)) return false;
+
+        JavaParserTypeParameter that = (JavaParserTypeParameter) o;
+
+        if (wrappedNode != null ? !wrappedNode.equals(that.wrappedNode) : that.wrappedNode != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = wrappedNode != null ? wrappedNode.hashCode() : 0;
+        result = 31 * result + (typeSolver != null ? typeSolver.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+    }
+
+    @Override
+    public String getContainerQualifiedName() {
+        ResolvedTypeParametrizable container = getContainer();
+        if (container instanceof ResolvedReferenceTypeDeclaration) {
+            return ((ResolvedReferenceTypeDeclaration) container).getQualifiedName();
+        } else if (container instanceof JavaParserConstructorDeclaration) {
+            return ((JavaParserConstructorDeclaration) container).getQualifiedSignature();
+        } else {
+            return ((JavaParserMethodDeclaration) container).getQualifiedSignature();
+        }
+    }
+
+    @Override
+    public String getContainerId() {
+        ResolvedTypeParametrizable container = getContainer();
+        if (container instanceof ResolvedReferenceTypeDeclaration) {
+            return ((ResolvedReferenceTypeDeclaration) container).getId();
+        } else if (container instanceof JavaParserConstructorDeclaration) {
+            return ((JavaParserConstructorDeclaration) container).getQualifiedSignature();
+        } else {
+            return ((JavaParserMethodDeclaration) container).getQualifiedSignature();
+        }
+    }
+
+    @Override
+    public ResolvedTypeParametrizable getContainer() {
+        Node parentNode = requireParentNode(wrappedNode);
+        if (parentNode instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) {
+            com.github.javaparser.ast.body.ClassOrInterfaceDeclaration jpTypeDeclaration = (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) parentNode;
+            return JavaParserFacade.get(typeSolver).getTypeDeclaration(jpTypeDeclaration);
+        } else if (parentNode instanceof com.github.javaparser.ast.body.ConstructorDeclaration){
+            com.github.javaparser.ast.body.ConstructorDeclaration jpConstructorDeclaration = (com.github.javaparser.ast.body.ConstructorDeclaration) parentNode;
+            Optional<ClassOrInterfaceDeclaration> jpTypeDeclaration = jpConstructorDeclaration.getAncestorOfType(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.class);
+            if (jpTypeDeclaration.isPresent()) {
+                ResolvedReferenceTypeDeclaration typeDeclaration = JavaParserFacade.get(typeSolver).getTypeDeclaration(jpTypeDeclaration.get());
+                if (typeDeclaration.isClass()) {
+                    return new JavaParserConstructorDeclaration(typeDeclaration.asClass(), jpConstructorDeclaration, typeSolver);
+                }
+            }
+        } else {
+            com.github.javaparser.ast.body.MethodDeclaration jpMethodDeclaration = (com.github.javaparser.ast.body.MethodDeclaration) parentNode;
+            return new JavaParserMethodDeclaration(jpMethodDeclaration, typeSolver);
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return String.format("%s.%s", getContainerQualifiedName(), getName());
+    }
+
+    @Override
+    public List<Bound> getBounds() {
+        return wrappedNode.getTypeBound().stream().map((astB) -> toBound(astB, typeSolver)).collect(Collectors.toList());
+    }
+
+    private Bound toBound(ClassOrInterfaceType classOrInterfaceType, TypeSolver typeSolver) {
+        ResolvedType type = JavaParserFacade.get(typeSolver).convertToUsage(classOrInterfaceType, classOrInterfaceType);
+        return Bound.extendsBound(type);
+    }
+
+    public Context getContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    public ResolvedType getUsage(Node node) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResolvedFieldDeclaration getField(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasField(String name) {
+        return false;
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return true;
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserTypeParameter.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public com.github.javaparser.ast.type.TypeParameter getWrappedNode() {
+        return wrappedNode;
+    }
+
+    @Override
+    public String toString() {
+        return "JPTypeParameter(" + wrappedNode.getName() + ", bounds=" + wrappedNode.getTypeBound() + ")";
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        ResolvedTypeParametrizable container = getContainer();
+        if (container instanceof ResolvedReferenceTypeDeclaration) {
+            return Optional.of((ResolvedReferenceTypeDeclaration) container);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java
new file mode 100644
index 0000000..a602ebf
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeVariableDeclaration extends AbstractTypeDeclaration {
+
+    private TypeParameter wrappedNode;
+    private TypeSolver typeSolver;
+
+    public JavaParserTypeVariableDeclaration(TypeParameter wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+    }
+
+    @Override
+    public String getPackageName() {
+        return Helper.getPackageName(wrappedNode);
+    }
+
+    @Override
+    public String getClassName() {
+        return Helper.getClassName("", wrappedNode);
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return getName();
+    }
+
+    public Context getContext() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String toString() {
+        return "JavaParserTypeVariableDeclaration{" +
+                wrappedNode.getName() +
+                '}';
+    }
+
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes) {
+        throw new UnsupportedOperationException();
+    }
+
+    public ResolvedType getUsage(Node node) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        if (type.isTypeVariable()) {
+            throw new UnsupportedOperationException("Is this type variable declaration assignable by " + type.describe());
+        } else {
+            throw new UnsupportedOperationException("Is this type variable declaration assignable by " + type);
+        }
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return true;
+    }
+
+    @Override
+    public ResolvedFieldDeclaration getField(String name) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasField(String name) {
+        return false;
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public String getName() {
+        return wrappedNode.getName().getId();
+    }
+
+    @Override
+    public boolean isField() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isParameter() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isType() {
+        return true;
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isClass() {
+        return false;
+    }
+
+    @Override
+    public boolean isInterface() {
+        return false;
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return Collections.emptyList();
+    }
+
+    public ResolvedTypeParameterDeclaration asTypeParameter() {
+        return new JavaParserTypeParameter(this.wrappedNode, typeSolver);
+    }
+
+    /**
+     * Returns the JavaParser node associated with this JavaParserTypeVariableDeclaration.
+     *
+     * @return A visitable JavaParser node wrapped by this object.
+     */
+    public TypeParameter getWrappedNode() {
+        return wrappedNode;
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return asTypeParameter().containerType();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java
new file mode 100644
index 0000000..14fdafc
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
+
+/**
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractSymbolDeclarator<N extends Node> implements SymbolDeclarator {
+
+    protected N wrappedNode;
+    protected TypeSolver typeSolver;
+
+    public AbstractSymbolDeclarator(N wrappedNode, TypeSolver typeSolver) {
+        this.wrappedNode = wrappedNode;
+        this.typeSolver = typeSolver;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java
new file mode 100644
index 0000000..dddf7a5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class FieldSymbolDeclarator extends AbstractSymbolDeclarator<FieldDeclaration> {
+
+    public FieldSymbolDeclarator(FieldDeclaration wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+        List<ResolvedValueDeclaration> symbols = new LinkedList<>();
+        for (VariableDeclarator v : wrappedNode.getVariables()) {
+            symbols.add(JavaParserSymbolDeclaration.field(v, typeSolver));
+        }
+        return symbols;
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java
new file mode 100644
index 0000000..e950b70
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class NoSymbolDeclarator<N extends Node> extends AbstractSymbolDeclarator<N> {
+
+    public NoSymbolDeclarator(N wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+        return Collections.emptyList();
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java
new file mode 100644
index 0000000..45d8e16
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ParameterSymbolDeclarator extends AbstractSymbolDeclarator<Parameter> {
+
+    public ParameterSymbolDeclarator(Parameter wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+    }
+
+    @Override
+    public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+        List<ResolvedValueDeclaration> symbols = new LinkedList<>();
+        symbols.add(JavaParserSymbolDeclaration.parameter(wrappedNode, typeSolver));
+        return symbols;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java
new file mode 100644
index 0000000..88865de
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarators;
+
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class VariableSymbolDeclarator extends AbstractSymbolDeclarator<VariableDeclarationExpr> {
+
+    public VariableSymbolDeclarator(VariableDeclarationExpr wrappedNode, TypeSolver typeSolver) {
+        super(wrappedNode, typeSolver);
+        wrappedNode.getParentNode().ifPresent(p -> {
+            if (p instanceof FieldDeclaration) {
+                throw new IllegalArgumentException();
+            }
+        });
+    }
+
+    @Override
+    public List<ResolvedValueDeclaration> getSymbolDeclarations() {
+        return wrappedNode.getVariables().stream()
+                .map(v -> JavaParserSymbolDeclaration.localVar(v, typeSolver))
+                .collect(Collectors.toCollection(LinkedList::new));
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java
new file mode 100644
index 0000000..9ddf1cf
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javaparsermodel/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+/**
+ * Implementation of model based on JavaParser.
+ */
+package com.github.javaparser.symbolsolver.javaparsermodel;
\ No newline at end of file
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java
new file mode 100644
index 0000000..6c516b5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder;
+import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.AccessFlag;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.SignatureAttribute;
+import javassist.bytecode.SyntheticAttribute;
+
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistClassDeclaration extends AbstractClassDeclaration {
+
+
+
+    private CtClass ctClass;
+    private TypeSolver typeSolver;
+    private JavassistTypeDeclarationAdapter javassistTypeDeclarationAdapter;
+
+    public JavassistClassDeclaration(CtClass ctClass, TypeSolver typeSolver) {
+        if (ctClass == null) {
+            throw new IllegalArgumentException();
+        }
+        if (ctClass.isInterface() || ctClass.isAnnotation() || ctClass.isPrimitive() || ctClass.isEnum()) {
+            throw new IllegalArgumentException("Trying to instantiate a JavassistClassDeclaration with something which is not a class: " + ctClass.toString());
+        }
+        this.ctClass = ctClass;
+        this.typeSolver = typeSolver;
+        this.javassistTypeDeclarationAdapter = new JavassistTypeDeclarationAdapter(ctClass, typeSolver);
+    }
+
+    @Override
+    protected ResolvedReferenceType object() {
+        return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return javassistTypeDeclarationAdapter.getDeclaredMethods();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        JavassistClassDeclaration that = (JavassistClassDeclaration) o;
+
+        if (!ctClass.equals(that.ctClass)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return ctClass.hashCode();
+    }
+
+    @Override
+    public String getPackageName() {
+        return ctClass.getPackageName();
+    }
+
+    @Override
+    public String getClassName() {
+        String className = ctClass.getName().replace('$', '.');
+        if (getPackageName() != null) {
+            return className.substring(getPackageName().length() + 1, className.length());
+        }
+        return className;
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return ctClass.getName().replace('$', '.');
+    }
+
+    public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+                                                    Context invokationContext, List<ResolvedType> typeParameterValues) {
+        return JavassistUtils.getMethodUsage(ctClass, name, argumentsTypes, typeSolver, invokationContext);
+    }
+
+    @Deprecated
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (CtField field : ctClass.getDeclaredFields()) {
+            if (field.getName().equals(name)) {
+                return SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver));
+            }
+        }
+
+        final String superclassFQN = getSuperclassFQN();
+        SymbolReference<? extends ResolvedValueDeclaration> ref = solveSymbolForFQN(name, typeSolver, superclassFQN);
+        if (ref.isSolved()) {
+            return ref;
+        }
+
+        String[] interfaceFQNs = getInterfaceFQNs();
+        for (String interfaceFQN : interfaceFQNs) {
+            SymbolReference<? extends ResolvedValueDeclaration> interfaceRef = solveSymbolForFQN(name, typeSolver, interfaceFQN);
+            if (interfaceRef.isSolved()) {
+                return interfaceRef;
+            }
+        }
+
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    private SymbolReference<? extends ResolvedValueDeclaration> solveSymbolForFQN(String symbolName, TypeSolver typeSolver, String fqn) {
+        if (fqn == null) {
+            return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+        }
+
+        ResolvedReferenceTypeDeclaration fqnTypeDeclaration = typeSolver.solveType(fqn);
+        return new SymbolSolver(typeSolver).solveSymbolInType(fqnTypeDeclaration, symbolName);
+    }
+
+    private String[] getInterfaceFQNs() {
+        return ctClass.getClassFile().getInterfaces();
+    }
+
+    private String getSuperclassFQN() {
+        return ctClass.getClassFile().getSuperclass();
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        List<ResolvedReferenceType> ancestors = new LinkedList<>();
+        if (getSuperClass() != null) {
+            ancestors.add(getSuperClass());
+        }
+        ancestors.addAll(getInterfaces());
+        return ancestors;
+    }
+
+    @Deprecated
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly) {
+        List<ResolvedMethodDeclaration> candidates = new ArrayList<>();
+        Predicate<CtMethod> staticOnlyCheck = m -> !staticOnly || (staticOnly && Modifier.isStatic(m.getModifiers()));
+        for (CtMethod method : ctClass.getDeclaredMethods()) {
+            boolean isSynthetic = method.getMethodInfo().getAttribute(SyntheticAttribute.tag) != null;
+            boolean isNotBridge =  (method.getMethodInfo().getAccessFlags() & AccessFlag.BRIDGE) == 0;
+            if (method.getName().equals(name) && !isSynthetic && isNotBridge && staticOnlyCheck.test(method)) {
+                candidates.add(new JavassistMethodDeclaration(method, typeSolver));
+            }
+        }
+
+        try {
+            CtClass superClass = ctClass.getSuperclass();
+            if (superClass != null) {
+                SymbolReference<ResolvedMethodDeclaration> ref = new JavassistClassDeclaration(superClass, typeSolver).solveMethod(name, argumentsTypes, staticOnly);
+                if (ref.isSolved()) {
+                    candidates.add(ref.getCorrespondingDeclaration());
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        try {
+            for (CtClass interfaze : ctClass.getInterfaces()) {
+                SymbolReference<ResolvedMethodDeclaration> ref = new JavassistInterfaceDeclaration(interfaze, typeSolver).solveMethod(name, argumentsTypes, staticOnly);
+                if (ref.isSolved()) {
+                    candidates.add(ref.getCorrespondingDeclaration());
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        return MethodResolutionLogic.findMostApplicable(candidates, name, argumentsTypes, typeSolver);
+    }
+
+    public ResolvedType getUsage(Node node) {
+        return new ReferenceTypeImpl(this, typeSolver);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        if (type.isNull()) {
+            return true;
+        }
+
+        if (type instanceof LambdaArgumentTypePlaceholder) {
+            return isFunctionalInterface();
+        }
+
+        // TODO look into generics
+        if (type.describe().equals(this.getQualifiedName())) {
+            return true;
+        }
+        try {
+            if (this.ctClass.getSuperclass() != null
+                    && new JavassistClassDeclaration(this.ctClass.getSuperclass(), typeSolver).isAssignableBy(type)) {
+                return true;
+            }
+            for (CtClass interfaze : ctClass.getInterfaces()) {
+                if (new JavassistInterfaceDeclaration(interfaze, typeSolver).isAssignableBy(type)) {
+                    return true;
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return false;
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+      return javassistTypeDeclarationAdapter.getDeclaredFields();
+    }
+
+    @Override
+    public String getName() {
+        String[] nameElements = ctClass.getSimpleName().replace('$', '.').split("\\.");
+        return nameElements[nameElements.length - 1];
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean isType() {
+        return true;
+    }
+
+    @Override
+    public boolean isClass() {
+        return !ctClass.isInterface();
+    }
+
+    @Override
+    public ResolvedReferenceType getSuperClass() {
+        try {
+            if (ctClass.getSuperclass() == null) {
+                return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+            }
+            if (ctClass.getGenericSignature() == null) {
+                return new ReferenceTypeImpl(new JavassistClassDeclaration(ctClass.getSuperclass(), typeSolver), typeSolver);
+            }
+
+            SignatureAttribute.ClassSignature classSignature = SignatureAttribute.toClassSignature(ctClass.getGenericSignature());
+            return JavassistUtils.signatureTypeToType(classSignature.getSuperClass(), typeSolver, this).asReferenceType();
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (BadBytecode e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getInterfaces() {
+        try {
+            if (ctClass.getGenericSignature() == null) {
+                return Arrays.stream(ctClass.getInterfaces())
+                        .map(i -> new JavassistInterfaceDeclaration(i, typeSolver))
+                        .map(i -> new ReferenceTypeImpl(i, typeSolver))
+                        .collect(Collectors.toList());
+            } else {
+                SignatureAttribute.ClassSignature classSignature = SignatureAttribute.toClassSignature(ctClass.getGenericSignature());
+                return Arrays.stream(classSignature.getInterfaces())
+                        .map(i -> JavassistUtils.signatureTypeToType(i, typeSolver, this).asReferenceType())
+                        .collect(Collectors.toList());
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (BadBytecode e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public boolean isInterface() {
+        return ctClass.isInterface();
+    }
+
+    @Override
+    public String toString() {
+        return "JavassistClassDeclaration {" + ctClass.getName() + '}';
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return javassistTypeDeclarationAdapter.getTypeParameters();
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return JavassistFactory.modifiersToAccessLevel(ctClass.getModifiers());
+    }
+
+    @Override
+    public List<ResolvedConstructorDeclaration> getConstructors() {
+      return javassistTypeDeclarationAdapter.getConstructors();
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return javassistTypeDeclarationAdapter.containerType();
+    }
+
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        try {
+            /*
+            Get all internal types of the current class and get their corresponding ReferenceTypeDeclaration.
+            Finally, return them in a Set.
+             */
+            return Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)).collect(Collectors.toSet());
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration getInternalType(String name) {
+        /*
+        The name of the ReferenceTypeDeclaration could be composed of the internal class and the outer class, e.g. A$B. That's why we search the internal type in the ending part.
+        In case the name is composed of the internal type only, i.e. f.getName() returns B, it will also works.
+         */
+        Optional<ResolvedReferenceTypeDeclaration> type =
+                this.internalTypes().stream().filter(f -> f.getName().endsWith(name)).findFirst();
+        return type.orElseThrow(() ->
+                new UnsolvedSymbolException("Internal type not found: " + name));
+    }
+
+    @Override
+    public boolean hasInternalType(String name) {
+        /*
+        The name of the ReferenceTypeDeclaration could be composed of the internal class and the outer class, e.g. A$B. That's why we search the internal type in the ending part.
+        In case the name is composed of the internal type only, i.e. f.getName() returns B, it will also works.
+         */
+        return this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name));
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java
new file mode 100644
index 0000000..0fd010a
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import javassist.CtConstructor;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.SignatureAttribute;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Fred Lefévère-Laoide
+ */
+public class JavassistConstructorDeclaration implements ResolvedConstructorDeclaration {
+    private CtConstructor ctConstructor;
+    private TypeSolver typeSolver;
+
+    public JavassistConstructorDeclaration(CtConstructor ctConstructor, TypeSolver typeSolver) {
+        this.ctConstructor = ctConstructor;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public String toString() {
+        return "JavassistMethodDeclaration{" +
+                "CtConstructor=" + ctConstructor +
+                '}';
+    }
+
+    @Override
+    public String getName() {
+        return ctConstructor.getName();
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean isType() {
+        return false;
+    }
+
+    @Override
+    public ResolvedClassDeclaration declaringType() {
+        return new JavassistClassDeclaration(ctConstructor.getDeclaringClass(), typeSolver);
+    }
+
+    @Override
+    public int getNumberOfParams() {
+        try {
+            return ctConstructor.getParameterTypes().length;
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedParameterDeclaration getParam(int i) {
+        try {
+            boolean variadic = false;
+            if ((ctConstructor.getModifiers() & javassist.Modifier.VARARGS) > 0) {
+                variadic = i == (ctConstructor.getParameterTypes().length - 1);
+            }
+            if (ctConstructor.getGenericSignature() != null) {
+                SignatureAttribute.MethodSignature methodSignature = SignatureAttribute.toMethodSignature(ctConstructor.getGenericSignature());
+                SignatureAttribute.Type signatureType = methodSignature.getParameterTypes()[i];
+                return new JavassistParameterDeclaration(JavassistUtils.signatureTypeToType(signatureType, typeSolver, this), typeSolver, variadic);
+            } else {
+                return new JavassistParameterDeclaration(ctConstructor.getParameterTypes()[i], typeSolver, variadic);
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (BadBytecode badBytecode) {
+            throw new RuntimeException(badBytecode);
+        }
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        try {
+            if (ctConstructor.getGenericSignature() == null) {
+                return Collections.emptyList();
+            }
+            SignatureAttribute.MethodSignature methodSignature = SignatureAttribute.toMethodSignature(ctConstructor.getGenericSignature());
+            return Arrays.stream(methodSignature.getTypeParameters()).map((jasTp) -> new JavassistTypeParameter(jasTp, this, typeSolver)).collect(Collectors.toList());
+        } catch (BadBytecode badBytecode) {
+            throw new RuntimeException(badBytecode);
+        }
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return JavassistFactory.modifiersToAccessLevel(ctConstructor.getModifiers());
+    }
+
+    @Override
+    public int getNumberOfSpecifiedExceptions() {
+        try {
+            return ctConstructor.getExceptionTypes().length;
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedType getSpecifiedException(int index) {
+        if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+            throw new IllegalArgumentException(String.format("No exception with index %d. Number of exceptions: %d",
+                    index, getNumberOfSpecifiedExceptions()));
+        }
+        try {
+            return JavassistFactory.typeUsageFor(ctConstructor.getExceptionTypes()[index], typeSolver);
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java
new file mode 100644
index 0000000..178c74b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumConstantDeclaration.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import javassist.CtField;
+import javassist.bytecode.AccessFlag;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistEnumConstantDeclaration implements ResolvedEnumConstantDeclaration {
+
+    private CtField ctField;
+    private TypeSolver typeSolver;
+
+    public JavassistEnumConstantDeclaration(CtField ctField, TypeSolver typeSolver) {
+        if (ctField == null) {
+            throw new IllegalArgumentException();
+        }
+        if ((ctField.getFieldInfo2().getAccessFlags() & AccessFlag.ENUM) != 0) {
+            throw new IllegalArgumentException("Trying to instantiate a JavassistEnumConstantDeclaration with something which is not an enum field: " + ctField.toString());
+        }
+        this.ctField = ctField;
+        this.typeSolver = typeSolver;
+    }
+
+
+    @Override
+    public String getName() {
+        return ctField.getName();
+    }
+
+    @Override
+    public ResolvedType getType() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java
new file mode 100644
index 0000000..9a54a09
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.AccessFlag;
+import javassist.bytecode.SyntheticAttribute;
+
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistEnumDeclaration extends AbstractTypeDeclaration implements ResolvedEnumDeclaration {
+
+    private CtClass ctClass;
+    private TypeSolver typeSolver;
+    private JavassistTypeDeclarationAdapter javassistTypeDeclarationAdapter;
+
+    public JavassistEnumDeclaration(CtClass ctClass, TypeSolver typeSolver) {
+        if (ctClass == null) {
+            throw new IllegalArgumentException();
+        }
+        if (!ctClass.isEnum()) {
+            throw new IllegalArgumentException("Trying to instantiate a JavassistEnumDeclaration with something which is not an enum: " + ctClass.toString());
+        }
+        this.ctClass = ctClass;
+        this.typeSolver = typeSolver;
+        this.javassistTypeDeclarationAdapter = new JavassistTypeDeclarationAdapter(ctClass, typeSolver);
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return JavassistFactory.modifiersToAccessLevel(ctClass.getModifiers());
+    }
+
+    @Override
+    public String getPackageName() {
+        return ctClass.getPackageName();
+    }
+
+    @Override
+    public String getClassName() {
+        String name = ctClass.getName().replace('$', '.');
+        if (getPackageName() != null) {
+            return name.substring(getPackageName().length() + 1, name.length());
+        }
+        return name;
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return ctClass.getName().replace('$', '.');
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        // Direct ancestors of an enum are java.lang.Enum and interfaces
+        List<ResolvedReferenceType> ancestors = new LinkedList<>();
+
+        try {
+            CtClass superClass = ctClass.getSuperclass();
+
+            if (superClass != null) {
+                ResolvedType superClassTypeUsage = JavassistFactory.typeUsageFor(superClass, typeSolver);
+
+                if (superClassTypeUsage.isReferenceType()) {
+                    ancestors.add(superClassTypeUsage.asReferenceType());
+                }
+            }
+
+            for (CtClass interfaze : ctClass.getInterfaces()) {
+                ResolvedType interfazeTypeUsage = JavassistFactory.typeUsageFor(interfaze, typeSolver);
+
+                if (interfazeTypeUsage.isReferenceType()) {
+                    ancestors.add(interfazeTypeUsage.asReferenceType());
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException("Ancestor not found for " + ctClass.getName() + ".", e);
+        }
+
+        return ancestors;
+    }
+
+    @Override
+    public ResolvedFieldDeclaration getField(String name) {
+        Optional<ResolvedFieldDeclaration> field = javassistTypeDeclarationAdapter.getDeclaredFields().stream().filter(f -> f.getName().equals(name)).findFirst();
+
+        return field.orElseThrow(() -> new RuntimeException("Field " + name + " does not exist in " + ctClass.getName() + "."));
+    }
+
+    @Override
+    public boolean hasField(String name) {
+        return javassistTypeDeclarationAdapter.getDeclaredFields().stream().anyMatch(f -> f.getName().equals(name));
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        return javassistTypeDeclarationAdapter.getDeclaredFields();
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return javassistTypeDeclarationAdapter.getDeclaredMethods();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getName() {
+        String[] nameElements = ctClass.getSimpleName().replace('$', '.').split("\\.");
+        return nameElements[nameElements.length - 1];
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return javassistTypeDeclarationAdapter.getTypeParameters();
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return javassistTypeDeclarationAdapter.containerType();
+    }
+
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly) {
+        List<ResolvedMethodDeclaration> candidates = new ArrayList<>();
+        Predicate<CtMethod> staticOnlyCheck = m -> !staticOnly || (staticOnly && Modifier.isStatic(m.getModifiers()));
+        for (CtMethod method : ctClass.getDeclaredMethods()) {
+            boolean isSynthetic = method.getMethodInfo().getAttribute(SyntheticAttribute.tag) != null;
+            boolean isNotBridge = (method.getMethodInfo().getAccessFlags() & AccessFlag.BRIDGE) == 0;
+            if (method.getName().equals(name) && !isSynthetic && isNotBridge && staticOnlyCheck.test(method)) {
+                candidates.add(new JavassistMethodDeclaration(method, typeSolver));
+            }
+        }
+
+        try {
+            CtClass superClass = ctClass.getSuperclass();
+            if (superClass != null) {
+                SymbolReference<ResolvedMethodDeclaration> ref = new JavassistClassDeclaration(superClass, typeSolver).solveMethod(name, argumentsTypes, staticOnly);
+                if (ref.isSolved()) {
+                    candidates.add(ref.getCorrespondingDeclaration());
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        return MethodResolutionLogic.findMostApplicable(candidates, name, argumentsTypes, typeSolver);
+    }
+
+    public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+                                                    Context invokationContext, List<ResolvedType> typeParameterValues) {
+        return JavassistUtils.getMethodUsage(ctClass, name, argumentsTypes, typeSolver, invokationContext);
+    }
+
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        try {
+            /*
+            Get all internal types of the current class and get their corresponding ReferenceTypeDeclaration.
+            Finally, return them in a Set.
+             */
+            return Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)).collect(Collectors.toSet());
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration getInternalType(String name) {
+        /*
+        The name of the ReferenceTypeDeclaration could be composed on the internal class and the outer class, e.g. A$B. That's why we search the internal type in the ending part.
+        In case the name is composed of the internal type only, i.e. f.getName() returns B, it will also works.
+         */
+        Optional<ResolvedReferenceTypeDeclaration> type =
+                this.internalTypes().stream().filter(f -> f.getName().endsWith(name)).findFirst();
+        return type.orElseThrow(() ->
+                new UnsolvedSymbolException("Internal type not found: " + name));
+    }
+
+    @Override
+    public boolean hasInternalType(String name) {
+        /*
+        The name of the ReferenceTypeDeclaration could be composed on the internal class and the outer class, e.g. A$B. That's why we search the internal type in the ending part.
+        In case the name is composed of the internal type only, i.e. f.getName() returns B, it will also works.
+         */
+        return this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name));
+    }
+
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (CtField field : ctClass.getDeclaredFields()) {
+            if (field.getName().equals(name)) {
+                return SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver));
+            }
+        }
+
+        String[] interfaceFQNs = getInterfaceFQNs();
+        for (String interfaceFQN : interfaceFQNs) {
+            SymbolReference<? extends ResolvedValueDeclaration> interfaceRef = solveSymbolForFQN(name, typeSolver, interfaceFQN);
+            if (interfaceRef.isSolved()) {
+                return interfaceRef;
+            }
+        }
+
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    private SymbolReference<? extends ResolvedValueDeclaration> solveSymbolForFQN(String symbolName, TypeSolver typeSolver, String fqn) {
+        if (fqn == null) {
+            return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+        }
+
+        ResolvedReferenceTypeDeclaration fqnTypeDeclaration = typeSolver.solveType(fqn);
+        return new SymbolSolver(typeSolver).solveSymbolInType(fqnTypeDeclaration, symbolName);
+    }
+
+    private String[] getInterfaceFQNs() {
+        return ctClass.getClassFile().getInterfaces();
+    }
+
+    @Override
+    public List<ResolvedEnumConstantDeclaration> getEnumConstants() {
+        return Arrays.stream(ctClass.getFields())
+                .filter(f -> (f.getFieldInfo2().getAccessFlags() & AccessFlag.ENUM) != 0)
+                .map(f -> new JavassistEnumConstantDeclaration(f, typeSolver))
+                .collect(Collectors.toList());
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java
new file mode 100644
index 0000000..1188b9b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import javassist.CtClass;
+import javassist.NotFoundException;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistFactory {
+
+  public static ResolvedType typeUsageFor(CtClass ctClazz, TypeSolver typeSolver) {
+    try {
+      if (ctClazz.isArray()) {
+        return new ResolvedArrayType(typeUsageFor(ctClazz.getComponentType(), typeSolver));
+      } else if (ctClazz.isPrimitive()) {
+        if (ctClazz.getName().equals("void")) {
+          return ResolvedVoidType.INSTANCE;
+        } else {
+          return ResolvedPrimitiveType.byName(ctClazz.getName());
+        }
+      } else {
+        if (ctClazz.isInterface()) {
+          return new ReferenceTypeImpl(new JavassistInterfaceDeclaration(ctClazz, typeSolver),
+              typeSolver);
+        } else if (ctClazz.isEnum()) {
+          return new ReferenceTypeImpl(new JavassistEnumDeclaration(ctClazz, typeSolver),
+              typeSolver);
+        } else {
+          return new ReferenceTypeImpl(new JavassistClassDeclaration(ctClazz, typeSolver),
+              typeSolver);
+        }
+      }
+    } catch (NotFoundException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static ResolvedReferenceTypeDeclaration toTypeDeclaration(CtClass ctClazz, TypeSolver typeSolver) {
+    if (ctClazz.isInterface()) {
+      return new JavassistInterfaceDeclaration(ctClazz, typeSolver);
+    } else if (ctClazz.isEnum()) {
+      return new JavassistEnumDeclaration(ctClazz, typeSolver);
+    } else if (ctClazz.isAnnotation()) {
+      throw new UnsupportedOperationException("CtClass of annotation not yet supported");
+    } else if (ctClazz.isArray()) {
+      throw new IllegalArgumentException("This method should not be called passing an array");
+    } else {
+      return new JavassistClassDeclaration(ctClazz, typeSolver);
+    }
+  }
+
+  static AccessSpecifier modifiersToAccessLevel(final int modifiers) {
+    if (Modifier.isPublic(modifiers)) {
+      return AccessSpecifier.PUBLIC;
+    } else if (Modifier.isProtected(modifiers)) {
+      return AccessSpecifier.PROTECTED;
+    } else if (Modifier.isPrivate(modifiers)) {
+      return AccessSpecifier.PRIVATE;
+    } else {
+      return AccessSpecifier.DEFAULT;
+    }
+  }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java
new file mode 100644
index 0000000..85958ca
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParametrizable;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import javassist.CtField;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.SignatureAttribute;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistFieldDeclaration implements ResolvedFieldDeclaration {
+    private CtField ctField;
+    private TypeSolver typeSolver;
+
+    public JavassistFieldDeclaration(CtField ctField, TypeSolver typeSolver) {
+        this.ctField = ctField;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public ResolvedType getType() {
+        try {
+            if (ctField.getGenericSignature() != null && declaringType() instanceof ResolvedTypeParametrizable) {
+                javassist.bytecode.SignatureAttribute.Type genericSignatureType = SignatureAttribute.toFieldSignature(ctField.getGenericSignature());
+                return JavassistUtils.signatureTypeToType(genericSignatureType, typeSolver, (ResolvedTypeParametrizable) declaringType());
+            } else {
+                return JavassistFactory.typeUsageFor(ctField.getType(), typeSolver);
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (BadBytecode e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public boolean isStatic() {
+        return Modifier.isStatic(ctField.getModifiers());
+    }
+
+    @Override
+    public String getName() {
+        return ctField.getName();
+    }
+
+    @Override
+    public boolean isField() {
+        return true;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean isType() {
+        return false;
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return JavassistFactory.modifiersToAccessLevel(ctField.getModifiers());
+    }
+
+    @Override
+    public ResolvedTypeDeclaration declaringType() {
+        return JavassistFactory.toTypeDeclaration(ctField.getDeclaringClass(), typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java
new file mode 100644
index 0000000..9637535
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.AccessFlag;
+import javassist.bytecode.SyntheticAttribute;
+
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistInterfaceDeclaration extends AbstractTypeDeclaration implements ResolvedInterfaceDeclaration {
+
+    private CtClass ctClass;
+    private TypeSolver typeSolver;
+    private JavassistTypeDeclarationAdapter javassistTypeDeclarationAdapter;
+
+    @Override
+    public String toString() {
+        return "JavassistInterfaceDeclaration{" +
+                "ctClass=" + ctClass.getName() +
+                ", typeSolver=" + typeSolver +
+                '}';
+    }
+
+    public JavassistInterfaceDeclaration(CtClass ctClass, TypeSolver typeSolver) {
+        if (!ctClass.isInterface()) {
+            throw new IllegalArgumentException("Not an interface: " + ctClass.getName());
+        }
+        this.ctClass = ctClass;
+        this.typeSolver = typeSolver;
+        this.javassistTypeDeclarationAdapter = new JavassistTypeDeclarationAdapter(ctClass, typeSolver);
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getInterfacesExtended() {
+        try {
+            return Arrays.stream(ctClass.getInterfaces()).map(i -> new JavassistInterfaceDeclaration(i, typeSolver))
+                    .map(i -> new ReferenceTypeImpl(i, typeSolver)).collect(Collectors.toList());
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public String getPackageName() {
+        return ctClass.getPackageName();
+    }
+
+    @Override
+    public String getClassName() {
+        String className = ctClass.getName().replace('$', '.');
+        if (getPackageName() != null) {
+            return className.substring(getPackageName().length() + 1, className.length());
+        }
+        return className;
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return ctClass.getName().replace('$', '.');
+    }
+
+    @Deprecated
+    public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+                                                    Context invokationContext, List<ResolvedType> typeParameterValues) {
+
+        return JavassistUtils.getMethodUsage(ctClass, name, argumentsTypes, typeSolver, invokationContext);
+    }
+
+    @Deprecated
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly) {
+        List<ResolvedMethodDeclaration> candidates = new ArrayList<>();
+        Predicate<CtMethod> staticOnlyCheck = m -> !staticOnly || (staticOnly && Modifier.isStatic(m.getModifiers()));
+        for (CtMethod method : ctClass.getDeclaredMethods()) {
+            boolean isSynthetic = method.getMethodInfo().getAttribute(SyntheticAttribute.tag) != null;
+            boolean isNotBridge =  (method.getMethodInfo().getAccessFlags() & AccessFlag.BRIDGE) == 0;
+            if (method.getName().equals(name) && !isSynthetic && isNotBridge && staticOnlyCheck.test(method)) {
+                candidates.add(new JavassistMethodDeclaration(method, typeSolver));
+            }
+        }
+
+        try {
+            CtClass superClass = ctClass.getSuperclass();
+            if (superClass != null) {
+                SymbolReference<ResolvedMethodDeclaration> ref = new JavassistClassDeclaration(superClass, typeSolver).solveMethod(name, argumentsTypes, staticOnly);
+                if (ref.isSolved()) {
+                    candidates.add(ref.getCorrespondingDeclaration());
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        try {
+            for (CtClass interfaze : ctClass.getInterfaces()) {
+                SymbolReference<ResolvedMethodDeclaration> ref = new JavassistInterfaceDeclaration(interfaze, typeSolver).solveMethod(name, argumentsTypes, staticOnly);
+                if (ref.isSolved()) {
+                    candidates.add(ref.getCorrespondingDeclaration());
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        return MethodResolutionLogic.findMostApplicable(candidates, name, argumentsTypes, typeSolver);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+      return javassistTypeDeclarationAdapter.getDeclaredFields();
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        List<ResolvedReferenceType> ancestors = new ArrayList<>();
+        try {
+            for (CtClass interfaze : ctClass.getInterfaces()) {
+                ResolvedReferenceType superInterfaze = JavassistFactory.typeUsageFor(interfaze, typeSolver).asReferenceType();
+                ancestors.add(superInterfaze);
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        ancestors = ancestors.stream().filter(a -> a.getQualifiedName() != Object.class.getCanonicalName())
+                .collect(Collectors.toList());
+        ancestors.add(new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver));
+        return ancestors;
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return Arrays.stream(ctClass.getDeclaredMethods())
+                .map(m -> new JavassistMethodDeclaration(m, typeSolver))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        try {
+            for (Object annotationRaw : ctClass.getAnnotations()) {
+                if (annotationRaw.getClass().getCanonicalName().equals(canonicalName)) {
+                    return true;
+                }
+                if (Arrays.stream(annotationRaw.getClass().getInterfaces()).anyMatch(it -> it.getCanonicalName().equals(canonicalName))) {
+                    return true;
+                }
+            }
+        } catch (ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        String[] nameElements = ctClass.getSimpleName().replace('$', '.').split("\\.");
+        return nameElements[nameElements.length - 1];
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return javassistTypeDeclarationAdapter.getTypeParameters();
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return JavassistFactory.modifiersToAccessLevel(ctClass.getModifiers());
+    }
+
+    @Override
+    public ResolvedInterfaceDeclaration asInterface() {
+        return this;
+    }
+
+
+    @Deprecated
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (CtField field : ctClass.getDeclaredFields()) {
+            if (field.getName().equals(name)) {
+                return SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver));
+            }
+        }
+
+        String[] interfaceFQNs = getInterfaceFQNs();
+        for (String interfaceFQN : interfaceFQNs) {
+            SymbolReference<? extends ResolvedValueDeclaration> interfaceRef = solveSymbolForFQN(name, typeSolver, interfaceFQN);
+            if (interfaceRef.isSolved()) {
+                return interfaceRef;
+            }
+        }
+
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    private SymbolReference<? extends ResolvedValueDeclaration> solveSymbolForFQN(String symbolName, TypeSolver typeSolver, String fqn) {
+        if (fqn == null) {
+            return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+        }
+
+        ResolvedReferenceTypeDeclaration fqnTypeDeclaration = typeSolver.solveType(fqn);
+        return new SymbolSolver(typeSolver).solveSymbolInType(fqnTypeDeclaration, symbolName);
+    }
+
+    private String[] getInterfaceFQNs() {
+        return ctClass.getClassFile().getInterfaces();
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return javassistTypeDeclarationAdapter.containerType();
+    }
+
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        try {
+            /*
+            Get all internal types of the current class and get their corresponding ReferenceTypeDeclaration.
+            Finally, return them in a Set.
+             */
+            return Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)).collect(Collectors.toSet());
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration getInternalType(String name) {
+        /*
+        The name of the ReferenceTypeDeclaration could be composed on the internal class and the outer class, e.g. A$B. That's why we search the internal type in the ending part.
+        In case the name is composed of the internal type only, i.e. f.getName() returns B, it will also works.
+         */
+        Optional<ResolvedReferenceTypeDeclaration> type =
+                this.internalTypes().stream().filter(f -> f.getName().endsWith(name)).findFirst();
+        return type.orElseThrow(() ->
+                new UnsolvedSymbolException("Internal type not found: " + name));
+    }
+
+    @Override
+    public boolean hasInternalType(String name) {
+        /*
+        The name of the ReferenceTypeDeclaration could be composed on the internal class and the outer class, e.g. A$B. That's why we search the internal type in the ending part.
+        In case the name is composed of the internal type only, i.e. f.getName() returns B, it will also works.
+         */
+        return this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name));
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java
new file mode 100644
index 0000000..c474d50
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.SignatureAttribute;
+
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistMethodDeclaration implements ResolvedMethodDeclaration {
+    private CtMethod ctMethod;
+    private TypeSolver typeSolver;
+
+    public JavassistMethodDeclaration(CtMethod ctMethod, TypeSolver typeSolver) {
+        this.ctMethod = ctMethod;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public boolean isDefaultMethod() {
+        return ctMethod.getDeclaringClass().isInterface() && !isAbstract();
+    }
+
+    @Override
+    public boolean isStatic() {
+        return Modifier.isStatic(ctMethod.getModifiers());
+    }
+
+    @Override
+    public String toString() {
+        return "JavassistMethodDeclaration{" +
+                "ctMethod=" + ctMethod +
+                '}';
+    }
+
+    @Override
+    public String getName() {
+        return ctMethod.getName();
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean isType() {
+        return false;
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration declaringType() {
+        if (ctMethod.getDeclaringClass().isInterface()) {
+            return new JavassistInterfaceDeclaration(ctMethod.getDeclaringClass(), typeSolver);
+        } else {
+            return new JavassistClassDeclaration(ctMethod.getDeclaringClass(), typeSolver);
+        }
+    }
+
+    @Override
+    public ResolvedType getReturnType() {
+        try {
+            if (ctMethod.getGenericSignature() != null) {
+                javassist.bytecode.SignatureAttribute.Type genericSignatureType = SignatureAttribute.toMethodSignature(ctMethod.getGenericSignature()).getReturnType();
+                return JavassistUtils.signatureTypeToType(genericSignatureType, typeSolver, this);
+            } else {
+                return JavassistFactory.typeUsageFor(ctMethod.getReturnType(), typeSolver);
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (BadBytecode e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    @Override
+    public int getNumberOfParams() {
+        try {
+            return ctMethod.getParameterTypes().length;
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedParameterDeclaration getParam(int i) {
+        try {
+            boolean variadic = false;
+            if ((ctMethod.getModifiers() & javassist.Modifier.VARARGS) > 0) {
+                variadic = i == (ctMethod.getParameterTypes().length - 1);
+            }
+            if (ctMethod.getGenericSignature() != null) {
+                SignatureAttribute.MethodSignature methodSignature = SignatureAttribute.toMethodSignature(ctMethod.getGenericSignature());
+                SignatureAttribute.Type signatureType = methodSignature.getParameterTypes()[i];
+                return new JavassistParameterDeclaration(JavassistUtils.signatureTypeToType(signatureType, typeSolver, this), typeSolver, variadic);
+            } else {
+                return new JavassistParameterDeclaration(ctMethod.getParameterTypes()[i], typeSolver, variadic);
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        } catch (BadBytecode badBytecode) {
+            throw new RuntimeException(badBytecode);
+        }
+    }
+
+    public MethodUsage getUsage(Node node) {
+        throw new UnsupportedOperationException();
+    }
+
+    public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
+        return new MethodDeclarationCommonLogic(this, typeSolver).resolveTypeVariables(context, parameterTypes);
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return Modifier.isAbstract(ctMethod.getModifiers());
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        try {
+            if (ctMethod.getGenericSignature() == null) {
+                return Collections.emptyList();
+            }
+            SignatureAttribute.MethodSignature methodSignature = SignatureAttribute.toMethodSignature(ctMethod.getGenericSignature());
+            return Arrays.stream(methodSignature.getTypeParameters()).map((jasTp) -> new JavassistTypeParameter(jasTp, this, typeSolver)).collect(Collectors.toList());
+        } catch (BadBytecode badBytecode) {
+            throw new RuntimeException(badBytecode);
+        }
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int getNumberOfSpecifiedExceptions() {
+        try {
+            return ctMethod.getExceptionTypes().length;
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedType getSpecifiedException(int index) {
+        if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+            throw new IllegalArgumentException(String.format("No exception with index %d. Number of exceptions: %d",
+                    index, getNumberOfSpecifiedExceptions()));
+        }
+        try {
+            return JavassistFactory.typeUsageFor(ctMethod.getExceptionTypes()[index], typeSolver);
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java
new file mode 100644
index 0000000..4b3e14e
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import javassist.CtClass;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistParameterDeclaration implements ResolvedParameterDeclaration {
+    private ResolvedType type;
+    private TypeSolver typeSolver;
+    private boolean variadic;
+
+    public JavassistParameterDeclaration(CtClass type, TypeSolver typeSolver, boolean variadic) {
+        this(JavassistFactory.typeUsageFor(type, typeSolver), typeSolver, variadic);
+    }
+
+    public JavassistParameterDeclaration(ResolvedType type, TypeSolver typeSolver, boolean variadic) {
+        this.type = type;
+        this.typeSolver = typeSolver;
+        this.variadic = variadic;
+    }
+
+    @Override
+    public String toString() {
+        return "JavassistParameterDeclaration{" +
+                "type=" + type +
+                ", typeSolver=" + typeSolver +
+                ", variadic=" + variadic +
+                '}';
+    }
+
+    @Override
+    public String getName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isField() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isParameter() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isVariadic() {
+        return variadic;
+    }
+
+    @Override
+    public boolean isType() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ResolvedType getType() {
+        return type;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java
new file mode 100644
index 0000000..ae56434
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import javassist.CtClass;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.SignatureAttribute;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistTypeDeclarationAdapter {
+
+  private CtClass ctClass;
+  private TypeSolver typeSolver;
+
+  public JavassistTypeDeclarationAdapter(CtClass ctClass, TypeSolver typeSolver) {
+    this.ctClass = ctClass;
+    this.typeSolver = typeSolver;
+  }
+
+  public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+    return Arrays.stream(ctClass.getDeclaredMethods())
+        .map(m -> new JavassistMethodDeclaration(m, typeSolver)).collect(Collectors.toSet());
+  }
+
+  public List<ResolvedConstructorDeclaration> getConstructors() {
+    return Arrays.stream(ctClass.getConstructors())
+        .map(m -> new JavassistConstructorDeclaration(m, typeSolver)).collect(Collectors.toList());
+  }
+
+  public List<ResolvedFieldDeclaration> getDeclaredFields() {
+    List<ResolvedFieldDeclaration> fieldDecls = new ArrayList<>();
+    collectDeclaredFields(ctClass, fieldDecls);
+    return fieldDecls;
+  }
+
+  private void collectDeclaredFields(CtClass ctClass, List<ResolvedFieldDeclaration> fieldDecls) {
+    if (ctClass != null) {
+      Arrays.stream(ctClass.getDeclaredFields())
+          .forEach(f -> fieldDecls.add(new JavassistFieldDeclaration(f, typeSolver)));
+      try {
+        collectDeclaredFields(ctClass.getSuperclass(), fieldDecls);
+      } catch (NotFoundException e) {
+        // We'll stop here
+      }
+    }
+  }
+
+  public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+    if (null == ctClass.getGenericSignature()) {
+      return Collections.emptyList();
+    } else {
+      try {
+        SignatureAttribute.ClassSignature classSignature =
+            SignatureAttribute.toClassSignature(ctClass.getGenericSignature());
+        return Arrays.<SignatureAttribute.TypeParameter>stream(classSignature.getParameters())
+            .map((tp) -> new JavassistTypeParameter(tp, JavassistFactory.toTypeDeclaration(ctClass, typeSolver), typeSolver))
+            .collect(Collectors.toList());
+      } catch (BadBytecode badBytecode) {
+        throw new RuntimeException(badBytecode);
+      }
+    }
+  }
+
+  public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+    try {
+      return ctClass.getDeclaringClass() == null ?
+          Optional.empty() :
+          Optional.of(JavassistFactory.toTypeDeclaration(ctClass.getDeclaringClass(), typeSolver));
+    } catch (NotFoundException e) {
+      throw new RuntimeException(e);
+    }
+  }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java
new file mode 100644
index 0000000..bd99217
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import javassist.bytecode.SignatureAttribute;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavassistTypeParameter implements ResolvedTypeParameterDeclaration {
+
+    private SignatureAttribute.TypeParameter wrapped;
+    private TypeSolver typeSolver;
+    private ResolvedTypeParametrizable container;
+
+    public JavassistTypeParameter(SignatureAttribute.TypeParameter wrapped, ResolvedTypeParametrizable container, TypeSolver typeSolver) {
+        this.wrapped = wrapped;
+        this.typeSolver = typeSolver;
+        this.container = container;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ResolvedTypeParameterDeclaration)) return false;
+
+        ResolvedTypeParameterDeclaration that = (ResolvedTypeParameterDeclaration) o;
+
+        if (!getQualifiedName().equals(that.getQualifiedName())) {
+            return false;
+        }
+        if (declaredOnType() != that.declaredOnType()) {
+            return false;
+        }
+        if (declaredOnMethod() != that.declaredOnMethod()) {
+            return false;
+        }
+        // TODO check bounds
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "JavassistTypeParameter{" +
+                wrapped.getName()
+                + '}';
+    }
+
+    @Override
+    public String getName() {
+        return wrapped.getName();
+    }
+
+    @Override
+    public String getContainerQualifiedName() {
+        if (this.container instanceof ResolvedReferenceTypeDeclaration) {
+            return ((ResolvedReferenceTypeDeclaration) this.container).getQualifiedName();
+        } else if (this.container instanceof ResolvedMethodLikeDeclaration) {
+            return ((ResolvedMethodLikeDeclaration) this.container).getQualifiedName();
+        }
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getContainerId() {
+        return getContainerQualifiedName();
+    }
+
+    @Override
+    public ResolvedTypeParametrizable getContainer() {
+        return this.container;
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration.Bound> getBounds() {
+        List<Bound> bounds = new ArrayList<>();
+        if (wrapped.getClassBound() != null && !wrapped.getClassBound().toString().equals(Object.class.getCanonicalName())) {
+            throw new UnsupportedOperationException(wrapped.getClassBound().toString());
+        }
+        for (SignatureAttribute.ObjectType ot : wrapped.getInterfaceBound()) {
+            throw new UnsupportedOperationException(ot.toString());
+        }
+        return bounds;
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        if (container instanceof ResolvedReferenceTypeDeclaration) {
+            return Optional.of((ResolvedReferenceTypeDeclaration) container);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java
new file mode 100644
index 0000000..5b3d68e
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParametrizable;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.resolution.SymbolSolver;
+import javassist.CtClass;
+import javassist.CtMethod;
+import javassist.NotFoundException;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.SignatureAttribute;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+class JavassistUtils {
+
+    static Optional<MethodUsage> getMethodUsage(CtClass ctClass, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext) {
+        // TODO avoid bridge and synthetic methods
+        for (CtMethod method : ctClass.getDeclaredMethods()) {
+            if (method.getName().equals(name)) {
+                // TODO check typeParametersValues
+                MethodUsage methodUsage = new MethodUsage(new JavassistMethodDeclaration(method, typeSolver));
+                if (argumentsTypes.size() < methodUsage.getNoParams()) {
+                    // this method cannot be a good candidate (except if variadic ?)
+                    continue;
+                }
+                try {
+                    if (method.getGenericSignature() != null) {
+                        SignatureAttribute.MethodSignature methodSignature = SignatureAttribute.toMethodSignature(method.getGenericSignature());
+                        List<ResolvedType> parametersOfReturnType = parseTypeParameters(methodSignature.getReturnType().toString(), typeSolver, invokationContext);
+                        ResolvedType newReturnType = methodUsage.returnType();
+                        // consume one parametersOfReturnType at the time
+                        if (newReturnType.isReferenceType() && parametersOfReturnType.size() > 0) {
+                            newReturnType = newReturnType.asReferenceType().transformTypeParameters(tp -> parametersOfReturnType.remove(0));
+                        }
+                        methodUsage = methodUsage.replaceReturnType(newReturnType);
+                    }
+                    return Optional.of(methodUsage);
+                } catch (BadBytecode e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+
+        try {
+            CtClass superClass = ctClass.getSuperclass();
+            if (superClass != null) {
+                Optional<MethodUsage> ref = new JavassistClassDeclaration(superClass, typeSolver).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, null);
+                if (ref.isPresent()) {
+                    return ref;
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        try {
+            for (CtClass interfaze : ctClass.getInterfaces()) {
+                Optional<MethodUsage> ref = new JavassistInterfaceDeclaration(interfaze, typeSolver).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, null);
+                if (ref.isPresent()) {
+                    return ref;
+                }
+            }
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+
+        return Optional.empty();
+    }
+
+    private static List<ResolvedType> parseTypeParameters(String signature, TypeSolver typeSolver, Context invokationContext) {
+        String originalSignature = signature;
+        if (signature.contains("<")) {
+            signature = signature.substring(signature.indexOf('<') + 1);
+            if (!signature.endsWith(">")) {
+                throw new IllegalArgumentException();
+            }
+            signature = signature.substring(0, signature.length() - 1);
+            if (signature.contains(",")) {
+                throw new UnsupportedOperationException();
+            }
+            if (signature.startsWith("?")) {
+                // TODO: check bounds
+                List<ResolvedType> types = new ArrayList<>();
+                types.add(ResolvedWildcard.UNBOUNDED);
+                return types;
+            }
+            List<ResolvedType> typeParameters = parseTypeParameters(signature, typeSolver, invokationContext);
+            if (signature.contains("<")) {
+                signature = signature.substring(0, signature.indexOf('<'));
+            }
+            if (signature.contains(">")) {
+                throw new UnsupportedOperationException();
+            }
+
+            ResolvedType type = new SymbolSolver(typeSolver).solveTypeUsage(signature, invokationContext);
+
+            if (type.isReferenceType() && typeParameters.size() > 0) {
+                type = type.asReferenceType().transformTypeParameters(tp -> typeParameters.remove(0));
+            }
+            List<ResolvedType> types = new ArrayList<>();
+            types.add(type);
+            return types;
+        } else {
+            return Collections.emptyList();
+        }
+    }
+
+    static ResolvedType signatureTypeToType(SignatureAttribute.Type signatureType, TypeSolver typeSolver, ResolvedTypeParametrizable typeParametrizable) {
+        if (signatureType instanceof SignatureAttribute.ClassType) {
+            SignatureAttribute.ClassType classType = (SignatureAttribute.ClassType) signatureType;
+            List<ResolvedType> typeArguments = classType.getTypeArguments() == null ? Collections.emptyList() : Arrays.stream(classType.getTypeArguments()).map(ta -> typeArgumentToType(ta, typeSolver, typeParametrizable)).collect(Collectors.toList());
+            final String typeName =
+                    classType.getDeclaringClass() != null ?
+                            classType.getDeclaringClass().getName() + "." + classType.getName() :
+                            classType.getName();
+            ResolvedReferenceTypeDeclaration typeDeclaration = typeSolver.solveType(
+                    removeTypeArguments(internalNameToCanonicalName(typeName)));
+            return new ReferenceTypeImpl(typeDeclaration, typeArguments, typeSolver);
+        } else if (signatureType instanceof SignatureAttribute.TypeVariable) {
+            SignatureAttribute.TypeVariable typeVariableSignature = (SignatureAttribute.TypeVariable)signatureType;
+            Optional<ResolvedTypeParameterDeclaration> typeParameterDeclarationOpt = typeParametrizable.findTypeParameter(typeVariableSignature.getName());
+            if (!typeParameterDeclarationOpt.isPresent()) {
+                throw new UnsolvedSymbolException("Unable to solve TypeVariable " + typeVariableSignature);
+            }
+            ResolvedTypeParameterDeclaration typeParameterDeclaration = typeParameterDeclarationOpt.get();
+            return new ResolvedTypeVariable(typeParameterDeclaration);
+        } else if (signatureType instanceof SignatureAttribute.ArrayType) {
+            SignatureAttribute.ArrayType arrayType = (SignatureAttribute.ArrayType) signatureType;
+            return new ResolvedArrayType(signatureTypeToType(arrayType.getComponentType(), typeSolver, typeParametrizable));
+        } else if (signatureType instanceof SignatureAttribute.BaseType) {
+            SignatureAttribute.BaseType baseType = (SignatureAttribute.BaseType) signatureType;
+            if (baseType.toString().equals("void")) {
+                return ResolvedVoidType.INSTANCE;
+            } else {
+                return ResolvedPrimitiveType.byName(baseType.toString());
+            }
+        } else {
+            throw new RuntimeException(signatureType.getClass().getCanonicalName());
+        }
+    }
+    
+    private static String removeTypeArguments(String typeName) {
+        if (typeName.contains("<")) {
+            return typeName.substring(0, typeName.indexOf('<'));
+        } else {
+            return typeName;
+        }
+    }
+
+    private static String internalNameToCanonicalName(String typeName) {
+        return typeName.replaceAll("\\$", ".");
+    }
+
+    private static ResolvedType objectTypeArgumentToType(SignatureAttribute.ObjectType typeArgument, TypeSolver typeSolver, ResolvedTypeParametrizable typeParametrizable) {
+        String typeName = typeArgument.jvmTypeName();
+        Optional<ResolvedType> type = getGenericParameterByName(typeName, typeParametrizable);
+        return type.orElseGet(() -> new ReferenceTypeImpl(
+            typeSolver.solveType(removeTypeArguments(internalNameToCanonicalName(typeName))),
+            typeSolver));
+    }
+
+    private static Optional<ResolvedType> getGenericParameterByName(String typeName, ResolvedTypeParametrizable typeParametrizable) {
+        Optional<ResolvedTypeParameterDeclaration> tp = typeParametrizable.findTypeParameter(typeName);
+        return tp.map(ResolvedTypeVariable::new);
+    }
+
+    private static ResolvedType typeArgumentToType(SignatureAttribute.TypeArgument typeArgument, TypeSolver typeSolver, ResolvedTypeParametrizable typeParametrizable) {
+        if (typeArgument.isWildcard()) {
+            if (typeArgument.getType() == null) {
+                return ResolvedWildcard.UNBOUNDED;
+            } else if (typeArgument.getKind() == '+') {
+                return ResolvedWildcard.extendsBound(objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable));
+            } else if (typeArgument.getKind() == '-') {
+                return ResolvedWildcard.superBound(objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable));
+            } else {
+                throw new UnsupportedOperationException();
+            }
+        } else {
+            return objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable);
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java
new file mode 100644
index 0000000..3512f53
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/javassistmodel/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+/**
+ * Implementation of model based on Javassist.
+ */
+package com.github.javaparser.symbolsolver.javassistmodel;
\ No newline at end of file
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java
new file mode 100644
index 0000000..44dbdec
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/LazyType.java
@@ -0,0 +1,120 @@
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.Map;
+import java.util.function.Function;
+
+public class LazyType implements ResolvedType {
+    private ResolvedType concrete;
+    private Function<Void, ResolvedType> provider;
+
+    public LazyType(Function<Void, ResolvedType> provider) {
+        this.provider = provider;
+    }
+
+    private ResolvedType getType() {
+        if (concrete == null) {
+            concrete = provider.apply(null);
+        }
+        return concrete;
+    }
+
+    @Override
+    public boolean isArray() {
+        return getType().isArray();
+    }
+
+    @Override
+    public int arrayLevel() {
+        return getType().arrayLevel();
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return getType().isPrimitive();
+    }
+
+    @Override
+    public boolean isNull() {
+        return getType().isNull();
+    }
+
+    @Override
+    public boolean isReference() {
+        return getType().isReference();
+    }
+
+    @Override
+    public boolean isReferenceType() {
+        return getType().isReferenceType();
+    }
+
+    @Override
+    public boolean isVoid() {
+        return getType().isVoid();
+    }
+
+    @Override
+    public boolean isTypeVariable() {
+        return getType().isTypeVariable();
+    }
+
+    @Override
+    public boolean isWildcard() {
+        return getType().isWildcard();
+    }
+
+    @Override
+    public ResolvedArrayType asArrayType() {
+        return getType().asArrayType();
+    }
+
+    @Override
+    public ResolvedReferenceType asReferenceType() {
+        return getType().asReferenceType();
+    }
+
+    @Override
+    public ResolvedTypeParameterDeclaration asTypeParameter() {
+        return getType().asTypeParameter();
+    }
+
+    @Override
+    public ResolvedTypeVariable asTypeVariable() {
+        return getType().asTypeVariable();
+    }
+
+    @Override
+    public ResolvedPrimitiveType asPrimitive() {
+        return getType().asPrimitive();
+    }
+
+    @Override
+    public ResolvedWildcard asWildcard() {
+        return getType().asWildcard();
+    }
+
+    @Override
+    public String describe() {
+        return getType().describe();
+    }
+
+    @Override
+    public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced,
+                                             Map<ResolvedTypeParameterDeclaration, ResolvedType> inferredTypes) {
+        return getType().replaceTypeVariables(tp, replaced, inferredTypes);
+    }
+
+    @Override
+    public ResolvedType replaceTypeVariables(ResolvedTypeParameterDeclaration tp, ResolvedType replaced) {
+        return getType().replaceTypeVariables(tp, replaced);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        return getType().isAssignableBy(other);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java
new file mode 100644
index 0000000..927253e
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeTransformer;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.resolution.types.parametrization.ResolvedTypeParametersMap;
+import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+// TODO Remove references to typeSolver: it is needed to instantiate other instances of ReferenceTypeUsage
+//      and to get the Object type declaration
+public class ReferenceTypeImpl extends ResolvedReferenceType {
+
+    private TypeSolver typeSolver;
+
+    public static ResolvedReferenceType undeterminedParameters(ResolvedReferenceTypeDeclaration typeDeclaration, TypeSolver typeSolver) {
+        return new ReferenceTypeImpl(typeDeclaration, typeDeclaration.getTypeParameters().stream().map(
+                ResolvedTypeVariable::new
+        ).collect(Collectors.toList()), typeSolver);
+    }
+
+    @Override
+    protected ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration, List<ResolvedType> typeParametersCorrected) {
+        return new ReferenceTypeImpl(typeDeclaration, typeParametersCorrected, typeSolver);
+    }
+
+    @Override
+    protected ResolvedReferenceType create(ResolvedReferenceTypeDeclaration typeDeclaration) {
+        return new ReferenceTypeImpl(typeDeclaration, typeSolver);
+    }
+
+    public ReferenceTypeImpl(ResolvedReferenceTypeDeclaration typeDeclaration, TypeSolver typeSolver) {
+        super(typeDeclaration);
+        this.typeSolver = typeSolver;
+    }
+
+    public ReferenceTypeImpl(ResolvedReferenceTypeDeclaration typeDeclaration, List<ResolvedType> typeArguments, TypeSolver typeSolver) {
+        super(typeDeclaration, typeArguments);
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public ResolvedTypeParameterDeclaration asTypeParameter() {
+        if (this.typeDeclaration instanceof JavaParserTypeVariableDeclaration) {
+            JavaParserTypeVariableDeclaration javaParserTypeVariableDeclaration = (JavaParserTypeVariableDeclaration) this.typeDeclaration;
+            return javaParserTypeVariableDeclaration.asTypeParameter();
+        }
+        throw new UnsupportedOperationException(this.typeDeclaration.getClass().getCanonicalName());
+    }
+
+    /**
+     * This method checks if ThisType t = new OtherType() would compile.
+     */
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        if (other instanceof NullType) {
+            return !this.isPrimitive();
+        }
+        // everything is assignable to Object except void
+        if (!other.isVoid() && this.getQualifiedName().equals(Object.class.getCanonicalName())) {
+            return true;
+        }
+        // consider boxing
+        if (other.isPrimitive()) {
+            if (this.getQualifiedName().equals(Object.class.getCanonicalName())) {
+                return true;
+            } else {
+                // Check if 'other' can be boxed to match this type
+                if (isCorrespondingBoxingType(other.describe())) return true;
+
+                // Resolve the boxed type and check if it can be assigned via widening reference conversion
+                SymbolReference<ResolvedReferenceTypeDeclaration> type = typeSolver.tryToSolveType(other.asPrimitive().getBoxTypeQName());
+                return type.getCorrespondingDeclaration().canBeAssignedTo(super.typeDeclaration);
+            }
+        }
+        if (other instanceof LambdaArgumentTypePlaceholder) {
+            return this.getTypeDeclaration().hasAnnotation(FunctionalInterface.class.getCanonicalName());
+        } else if (other instanceof ReferenceTypeImpl) {
+            ReferenceTypeImpl otherRef = (ReferenceTypeImpl) other;
+            if (compareConsideringTypeParameters(otherRef)) {
+                return true;
+            }
+            for (ResolvedReferenceType otherAncestor : otherRef.getAllAncestors()) {
+                if (compareConsideringTypeParameters(otherAncestor)) {
+                    return true;
+                }
+            }
+            return false;
+        } else if (other.isTypeVariable()) {
+            for (ResolvedTypeParameterDeclaration.Bound bound : other.asTypeVariable().asTypeParameter().getBounds()) {
+                if (bound.isExtends()) {
+                    if (this.isAssignableBy(bound.getType())) {
+                        return true;
+                    }
+                }
+            }
+            return false;
+        } else if (other.isConstraint()){
+            return isAssignableBy(other.asConstraintType().getBound());
+        } else if (other.isWildcard()) {
+            if (this.getQualifiedName().equals(Object.class.getCanonicalName())) {
+                return true;
+            } else if (other.asWildcard().isExtends()) {
+                return isAssignableBy(other.asWildcard().getBoundedType());
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public Set<MethodUsage> getDeclaredMethods() {
+        // TODO replace variables
+        Set<MethodUsage> methods = new HashSet<>();
+        for (ResolvedMethodDeclaration methodDeclaration : getTypeDeclaration().getDeclaredMethods()) {
+            MethodUsage methodUsage = new MethodUsage(methodDeclaration);
+            methods.add(methodUsage);
+        }
+        return methods;
+    }
+
+    @Override
+    public ResolvedType toRawType() {
+        if (this.isRawType()) {
+                return this;
+        } else {
+            return new ReferenceTypeImpl(typeDeclaration, typeSolver);
+        }
+    }
+
+    @Override
+    public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+        return typeParametersValues().stream().anyMatch(tp -> tp.mention(typeParameters));
+    }
+
+    /**
+     * Execute a transformation on all the type parameters of this element.
+     */
+    @Override
+    public ResolvedType transformTypeParameters(ResolvedTypeTransformer transformer) {
+        ResolvedType result = this;
+        int i = 0;
+        for (ResolvedType tp : this.typeParametersValues()) {
+            ResolvedType transformedTp = transformer.transform(tp);
+            // Identity comparison on purpose
+            if (transformedTp != tp) {
+                List<ResolvedType> typeParametersCorrected = result.asReferenceType().typeParametersValues();
+                typeParametersCorrected.set(i, transformedTp);
+                result = create(typeDeclaration, typeParametersCorrected);
+            }
+            i++;
+        }
+        return result;
+    }
+
+    public List<ResolvedReferenceType> getAllAncestors() {
+        // We need to go through the inheritance line and propagate the type parametes
+
+        List<ResolvedReferenceType> ancestors = typeDeclaration.getAllAncestors();
+
+        ancestors = ancestors.stream()
+                .map(a -> typeParametersMap().replaceAll(a).asReferenceType())
+                .collect(Collectors.toList());
+
+        // Avoid repetitions of Object
+        ancestors.removeIf(a -> a.getQualifiedName().equals(Object.class.getCanonicalName()));
+        ResolvedReferenceTypeDeclaration objectType = typeSolver.solveType(Object.class.getCanonicalName());
+        ResolvedReferenceType objectRef = create(objectType);
+        ancestors.add(objectRef);
+        return ancestors;
+    }
+
+    public ResolvedReferenceType deriveTypeParameters(ResolvedTypeParametersMap typeParametersMap) {
+        return create(typeDeclaration, typeParametersMap);
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java
new file mode 100644
index 0000000..a9cbea7
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider.java
@@ -0,0 +1,36 @@
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.symbolsolver.logic.ObjectProvider;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class MyObjectProvider implements ObjectProvider {
+
+    public static final MyObjectProvider INSTANCE = new MyObjectProvider();
+
+    private MyObjectProvider() {
+        // prevent instantiation
+    }
+
+    @Override
+    public ResolvedReferenceType object() {
+        return new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, new ReflectionTypeSolver()), new ReflectionTypeSolver());
+    }
+
+    @Override
+    public ResolvedReferenceType byName(String qualifiedName) {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedReferenceTypeDeclaration typeDeclaration = typeSolver.solveType(qualifiedName);
+        if (!typeDeclaration.getTypeParameters().isEmpty()) {
+            throw new UnsupportedOperationException();
+        }
+        return new ReferenceTypeImpl(typeDeclaration, typeSolver);
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java
new file mode 100644
index 0000000..5be7bec
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter.java
@@ -0,0 +1,190 @@
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.NullType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.TypeVariable;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+class ReflectionClassAdapter {
+
+    private Class<?> clazz;
+    private TypeSolver typeSolver;
+    private ResolvedReferenceTypeDeclaration typeDeclaration;
+
+    public ReflectionClassAdapter(Class<?> clazz, TypeSolver typeSolver, ResolvedReferenceTypeDeclaration typeDeclaration) {
+        this.clazz = clazz;
+        this.typeSolver = typeSolver;
+        this.typeDeclaration = typeDeclaration;
+    }
+
+    public ReferenceTypeImpl getSuperClass() {
+        if (clazz.getGenericSuperclass() == null) {
+            return null;
+        }
+        java.lang.reflect.Type superType = clazz.getGenericSuperclass();
+        if (superType instanceof ParameterizedType) {
+            ParameterizedType parameterizedType = (ParameterizedType) superType;
+            List<ResolvedType> typeParameters = Arrays.stream(parameterizedType.getActualTypeArguments())
+                    .map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver))
+                    .collect(Collectors.toList());
+            return new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeParameters, typeSolver);
+        }
+        return new ReferenceTypeImpl(new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver), typeSolver);
+    }
+
+    public List<ResolvedReferenceType> getInterfaces() {
+        List<ResolvedReferenceType> interfaces = new ArrayList<>();
+        for (java.lang.reflect.Type superInterface : clazz.getGenericInterfaces()) {
+            if (superInterface instanceof ParameterizedType) {
+                ParameterizedType parameterizedType = (ParameterizedType) superInterface;
+                List<ResolvedType> typeParameters = Arrays.stream(parameterizedType.getActualTypeArguments())
+                        .map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver))
+                        .collect(Collectors.toList());
+                interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class<?>) ((ParameterizedType) superInterface).getRawType(), typeSolver), typeParameters, typeSolver));
+            } else {
+                interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class<?>) superInterface, typeSolver), typeSolver));
+            }
+        }
+        return interfaces;
+    }
+
+    public List<ResolvedReferenceType> getAncestors() {
+        List<ResolvedReferenceType> ancestors = new LinkedList<>();
+        if (getSuperClass() != null) {
+            ReferenceTypeImpl superClass = getSuperClass();
+            ancestors.add(superClass);
+        } else {
+            ReferenceTypeImpl object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+            ancestors.add(object);
+        }
+        ancestors.addAll(getInterfaces());
+        for (int i = 0; i < ancestors.size(); i++) {
+            ResolvedReferenceType ancestor = ancestors.get(i);
+            if (ancestor.hasName() && ancestor.getQualifiedName().equals(Object.class.getCanonicalName())) {
+                ancestors.remove(i);
+                i--;
+            }
+        }
+        return ancestors;
+    }
+
+    public ResolvedFieldDeclaration getField(String name) {
+        for (Field field : clazz.getDeclaredFields()) {
+            if (field.getName().equals(name)) {
+                return new ReflectionFieldDeclaration(field, typeSolver);
+            }
+        }
+        for (ResolvedReferenceType ancestor : typeDeclaration.getAllAncestors()) {
+            if (ancestor.getTypeDeclaration().hasField(name)) {
+                ReflectionFieldDeclaration reflectionFieldDeclaration = (ReflectionFieldDeclaration) ancestor.getTypeDeclaration().getField(name);
+                return reflectionFieldDeclaration.replaceType(ancestor.getFieldType(name).get());
+            }
+        }
+        throw new UnsolvedSymbolException(name, "Field in " + this);
+    }
+
+    public boolean hasField(String name) {
+        for (Field field : clazz.getDeclaredFields()) {
+            if (field.getName().equals(name)) {
+                return true;
+            }
+        }
+        ReferenceTypeImpl superclass = getSuperClass();
+        if (superclass == null) {
+            return false;
+        } else {
+            return superclass.getTypeDeclaration().hasField(name);
+        }
+    }
+
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        ArrayList<ResolvedFieldDeclaration> fields = new ArrayList<>();
+        for (Field field : clazz.getDeclaredFields()) {
+            fields.add(new ReflectionFieldDeclaration(field, typeSolver));
+        }
+        for (ResolvedReferenceType ancestor : typeDeclaration.getAllAncestors()) {
+            fields.addAll(ancestor.getTypeDeclaration().getAllFields());
+        }
+        return fields;
+    }
+
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return Arrays.stream(clazz.getDeclaredMethods())
+                .filter(m -> !m.isSynthetic() && !m.isBridge())
+                .map(m -> new ReflectionMethodDeclaration(m, typeSolver))
+                .collect(Collectors.toSet());
+    }
+
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        List<ResolvedTypeParameterDeclaration> params = new ArrayList<>();
+        for (TypeVariable<?> tv : this.clazz.getTypeParameters()) {
+            params.add(new ReflectionTypeParameter(tv, true, typeSolver));
+        }
+        return params;
+    }
+
+    public boolean isAssignableBy(ResolvedType type) {
+        if (type instanceof NullType) {
+            return true;
+        }
+        if (type instanceof LambdaArgumentTypePlaceholder) {
+            return isFunctionalInterface();
+        }
+        if (type.isArray()) {
+            return false;
+        }
+        if (type.isPrimitive()) {
+            return false;
+        }
+        if (type.describe().equals(typeDeclaration.getQualifiedName())) {
+            return true;
+        }
+        if (type instanceof ReferenceTypeImpl) {
+            ReferenceTypeImpl otherTypeDeclaration = (ReferenceTypeImpl) type;
+            return otherTypeDeclaration.getTypeDeclaration().canBeAssignedTo(typeDeclaration);
+        }
+
+        return false;
+    }
+
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        for (Annotation a : clazz.getDeclaredAnnotations()) {
+            if (a.annotationType().getCanonicalName().equals(canonicalName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private final boolean isFunctionalInterface() {
+        return FunctionalInterfaceLogic.getFunctionalMethod(typeDeclaration).isPresent();
+    }
+
+    public List<ResolvedConstructorDeclaration> getConstructors() {
+        return Arrays.stream(clazz.getConstructors())
+                .map(m -> new ReflectionConstructorDeclaration(m, typeSolver))
+                .collect(Collectors.toList());
+    }
+    
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        Class<?> declaringClass = clazz.getDeclaringClass();
+        return declaringClass == null ?
+                Optional.empty() :
+                Optional.of(ReflectionFactory.typeDeclarationFor(declaringClass, typeSolver));
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
new file mode 100644
index 0000000..a93353c
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.ContextHelper;
+import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.comparators.MethodComparator;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionClassDeclaration extends AbstractClassDeclaration {
+
+    ///
+    /// Fields
+    ///
+
+    private Class<?> clazz;
+    private TypeSolver typeSolver;
+    private ReflectionClassAdapter reflectionClassAdapter;
+
+    ///
+    /// Constructors
+    ///
+
+    public ReflectionClassDeclaration(Class<?> clazz, TypeSolver typeSolver) {
+        if (clazz == null) {
+            throw new IllegalArgumentException("Class should not be null");
+        }
+        if (clazz.isInterface()) {
+            throw new IllegalArgumentException("Class should not be an interface");
+        }
+        if (clazz.isPrimitive()) {
+            throw new IllegalArgumentException("Class should not represent a primitive class");
+        }
+        if (clazz.isArray()) {
+            throw new IllegalArgumentException("Class should not be an array");
+        }
+        if (clazz.isEnum()) {
+            throw new IllegalArgumentException("Class should not be an enum");
+        }
+        this.clazz = clazz;
+        this.typeSolver = typeSolver;
+        this.reflectionClassAdapter = new ReflectionClassAdapter(clazz, typeSolver, this);
+    }
+
+    ///
+    /// Public methods
+    ///
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return reflectionClassAdapter.getDeclaredMethods();
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        return reflectionClassAdapter.getAncestors();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ReflectionClassDeclaration that = (ReflectionClassDeclaration) o;
+
+        if (!clazz.getCanonicalName().equals(that.clazz.getCanonicalName())) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return clazz.hashCode();
+    }
+
+
+    @Override
+    public String getPackageName() {
+        if (clazz.getPackage() != null) {
+            return clazz.getPackage().getName();
+        }
+        return null;
+    }
+
+    @Override
+    public String getClassName() {
+        String canonicalName = clazz.getCanonicalName();
+        if (canonicalName != null && getPackageName() != null) {
+            return canonicalName.substring(getPackageName().length() + 1, canonicalName.length());
+        }
+        return null;
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return clazz.getCanonicalName();
+    }
+
+    @Deprecated
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> argumentsTypes, boolean staticOnly) {
+        List<ResolvedMethodDeclaration> methods = new ArrayList<>();
+        Predicate<Method> staticFilter = m -> !staticOnly || (staticOnly && Modifier.isStatic(m.getModifiers()));
+        for (Method method : Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)).filter(staticFilter)
+                                    .sorted(new MethodComparator()).collect(Collectors.toList())) {
+            if (method.isBridge() || method.isSynthetic()) continue;
+            ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver);
+            methods.add(methodDeclaration);
+        }
+        if (getSuperClass() != null) {
+            ResolvedClassDeclaration superClass = (ResolvedClassDeclaration) getSuperClass().getTypeDeclaration();
+            SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(superClass, name, argumentsTypes, staticOnly, typeSolver);
+            if (ref.isSolved()) {
+                methods.add(ref.getCorrespondingDeclaration());
+            }
+        }
+        for (ResolvedReferenceType interfaceDeclaration : getInterfaces()) {
+            SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(interfaceDeclaration.getTypeDeclaration(), name, argumentsTypes, staticOnly, typeSolver);
+            if (ref.isSolved()) {
+                methods.add(ref.getCorrespondingDeclaration());
+            }
+        }
+        return MethodResolutionLogic.findMostApplicable(methods, name, argumentsTypes, typeSolver);
+    }
+
+    @Override
+    public String toString() {
+        return "ReflectionClassDeclaration{" +
+                "clazz=" + getId() +
+                '}';
+    }
+
+    public ResolvedType getUsage(Node node) {
+
+        return new ReferenceTypeImpl(this, typeSolver);
+    }
+
+    public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, Context invokationContext, List<ResolvedType> typeParameterValues) {
+        List<MethodUsage> methods = new ArrayList<>();
+        for (Method method : Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)).sorted(new MethodComparator()).collect(Collectors.toList())) {
+            if (method.isBridge() || method.isSynthetic()) continue;
+            ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver);
+            MethodUsage methodUsage = new MethodUsage(methodDeclaration);
+            for (int i = 0; i < getTypeParameters().size() && i < typeParameterValues.size(); i++) {
+                ResolvedTypeParameterDeclaration tpToReplace = getTypeParameters().get(i);
+                ResolvedType newValue = typeParameterValues.get(i);
+                methodUsage = methodUsage.replaceTypeParameter(tpToReplace, newValue);
+            }
+            methods.add(methodUsage);
+        }
+        if (getSuperClass() != null) {
+            ResolvedClassDeclaration superClass = (ResolvedClassDeclaration) getSuperClass().getTypeDeclaration();
+            Optional<MethodUsage> ref = ContextHelper.solveMethodAsUsage(superClass, name, argumentsTypes, typeSolver, invokationContext, typeParameterValues);
+            if (ref.isPresent()) {
+                methods.add(ref.get());
+            }
+        }
+        for (ResolvedReferenceType interfaceDeclaration : getInterfaces()) {
+            Optional<MethodUsage> ref = ContextHelper.solveMethodAsUsage(interfaceDeclaration.getTypeDeclaration(), name, argumentsTypes, typeSolver, invokationContext, typeParameterValues);
+            if (ref.isPresent()) {
+                methods.add(ref.get());
+            }
+        }
+        Optional<MethodUsage> ref = MethodResolutionLogic.findMostApplicableUsage(methods, name, argumentsTypes, typeSolver);
+        return ref;
+    }
+
+    @Override
+    public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+        if (other instanceof LambdaArgumentTypePlaceholder) {
+            return isFunctionalInterface();
+        }
+        if (other.getQualifiedName().equals(getQualifiedName())) {
+            return true;
+        }
+        if (this.clazz.getSuperclass() != null
+                && new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver).canBeAssignedTo(other)) {
+            return true;
+        }
+        for (Class<?> interfaze : clazz.getInterfaces()) {
+            if (new ReflectionInterfaceDeclaration(interfaze, typeSolver).canBeAssignedTo(other)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        return reflectionClassAdapter.isAssignableBy(type);
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return false;
+    }
+
+    @Override
+    public ResolvedFieldDeclaration getField(String name) {
+        return reflectionClassAdapter.getField(name);
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        return reflectionClassAdapter.getAllFields();
+    }
+
+    @Deprecated
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (Field field : clazz.getFields()) {
+            if (field.getName().equals(name)) {
+                return SymbolReference.solved(new ReflectionFieldDeclaration(field, typeSolver));
+            }
+        }
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        return reflectionClassAdapter.hasDirectlyAnnotation(canonicalName);
+    }
+
+    @Override
+    public boolean hasField(String name) {
+        return reflectionClassAdapter.hasField(name);
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+    }
+
+    @Override
+    public String getName() {
+        return clazz.getSimpleName();
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean isType() {
+        return true;
+    }
+
+    @Override
+    public boolean isClass() {
+        return !clazz.isInterface();
+    }
+
+    @Override
+    public ReferenceTypeImpl getSuperClass() {
+        return reflectionClassAdapter.getSuperClass();
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getInterfaces() {
+        return reflectionClassAdapter.getInterfaces();
+    }
+
+    @Override
+    public boolean isInterface() {
+        return clazz.isInterface();
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return reflectionClassAdapter.getTypeParameters();
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return ReflectionFactory.modifiersToAccessLevel(this.clazz.getModifiers());
+    }
+
+    @Override
+    public List<ResolvedConstructorDeclaration> getConstructors() {
+        return reflectionClassAdapter.getConstructors();
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return reflectionClassAdapter.containerType();
+    }
+    
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        return Arrays.stream(this.clazz.getDeclaredClasses())
+                .map(ic -> ReflectionFactory.typeDeclarationFor(ic, typeSolver))
+                .collect(Collectors.toSet());
+    }
+
+    ///
+    /// Protected methods
+    ///
+
+    @Override
+    protected ResolvedReferenceType object() {
+        return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java
new file mode 100644
index 0000000..beb0c43
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Fred Lefévère-Laoide
+ */
+public class ReflectionConstructorDeclaration implements ResolvedConstructorDeclaration {
+
+    private Constructor<?> constructor;
+    private TypeSolver typeSolver;
+
+    public ReflectionConstructorDeclaration(Constructor<?> constructor,
+                                            TypeSolver typeSolver) {
+        this.constructor = constructor;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public ResolvedClassDeclaration declaringType() {
+        return new ReflectionClassDeclaration(constructor.getDeclaringClass(), typeSolver);
+    }
+
+    @Override
+    public int getNumberOfParams() {
+        return constructor.getParameterCount();
+    }
+
+    @Override
+    public ResolvedParameterDeclaration getParam(int i) {
+        if (i < 0 || i >= getNumberOfParams()) {
+            throw new IllegalArgumentException(String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()));
+        }
+        boolean variadic = false;
+        if (constructor.isVarArgs()) {
+            variadic = i == (constructor.getParameterCount() - 1);
+        }
+        return new ReflectionParameterDeclaration(constructor.getParameterTypes()[i], constructor.getGenericParameterTypes()[i], typeSolver, variadic);
+    }
+
+    @Override
+    public String getName() {
+        return constructor.getName();
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return ReflectionFactory.modifiersToAccessLevel(constructor.getModifiers());
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return Arrays.stream(constructor.getTypeParameters()).map((refTp) -> new ReflectionTypeParameter(refTp, false, typeSolver)).collect(Collectors.toList());
+    }
+
+    @Override
+    public int getNumberOfSpecifiedExceptions() {
+        return this.constructor.getExceptionTypes().length;
+    }
+
+    @Override
+    public ResolvedType getSpecifiedException(int index) {
+        if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+            throw new IllegalArgumentException();
+        }
+        return ReflectionFactory.typeUsageFor(this.constructor.getExceptionTypes()[index], typeSolver);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java
new file mode 100644
index 0000000..07799e8
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumConstantDeclaration.java
@@ -0,0 +1,31 @@
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.lang.reflect.Field;
+
+public class ReflectionEnumConstantDeclaration implements ResolvedEnumConstantDeclaration {
+
+    private Field enumConstant;
+    private TypeSolver typeSolver;
+
+    public ReflectionEnumConstantDeclaration(Field enumConstant, TypeSolver typeSolver) {
+        if (!enumConstant.isEnumConstant()) {
+            throw new IllegalArgumentException("The given field does not represent an enum constant");
+        }
+        this.enumConstant = enumConstant;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public String getName() {
+        return enumConstant.getName();
+    }
+
+    @Override
+    public ResolvedType getType() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java
new file mode 100644
index 0000000..a0b4bc3
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.logic.ConfilictingGenericTypesException;
+import com.github.javaparser.symbolsolver.logic.InferenceContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionEnumDeclaration extends AbstractTypeDeclaration implements ResolvedEnumDeclaration {
+
+  ///
+  /// Fields
+  ///
+
+  private Class<?> clazz;
+  private TypeSolver typeSolver;
+  private ReflectionClassAdapter reflectionClassAdapter;
+
+  ///
+  /// Constructors
+  ///
+
+  public ReflectionEnumDeclaration(Class<?> clazz, TypeSolver typeSolver) {
+    if (clazz == null) {
+      throw new IllegalArgumentException("Class should not be null");
+    }
+    if (clazz.isInterface()) {
+      throw new IllegalArgumentException("Class should not be an interface");
+    }
+    if (clazz.isPrimitive()) {
+      throw new IllegalArgumentException("Class should not represent a primitive class");
+    }
+    if (clazz.isArray()) {
+      throw new IllegalArgumentException("Class should not be an array");
+    }
+    if (!clazz.isEnum()) {
+      throw new IllegalArgumentException("Class should be an enum");
+    }
+    this.clazz = clazz;
+    this.typeSolver = typeSolver;
+    this.reflectionClassAdapter = new ReflectionClassAdapter(clazz, typeSolver, this);
+  }
+
+  ///
+  /// Public methods
+  ///
+
+  @Override
+  public AccessSpecifier accessSpecifier() {
+    return ReflectionFactory.modifiersToAccessLevel(this.clazz.getModifiers());
+  }
+  
+  @Override
+  public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+      return reflectionClassAdapter.containerType();
+  }
+
+  @Override
+  public String getPackageName() {
+    if (clazz.getPackage() != null) {
+      return clazz.getPackage().getName();
+    }
+    return null;
+  }
+
+  @Override
+  public String getClassName() {
+    String canonicalName = clazz.getCanonicalName();
+    if (canonicalName != null && getPackageName() != null) {
+      return canonicalName.substring(getPackageName().length() + 1, canonicalName.length());
+    }
+    return null;
+  }
+
+  @Override
+  public String getQualifiedName() {
+    return clazz.getCanonicalName();
+  }
+
+  @Override
+  public List<ResolvedReferenceType> getAncestors() {
+    return reflectionClassAdapter.getAncestors();
+  }
+
+  @Override
+  public ResolvedFieldDeclaration getField(String name) {
+    return reflectionClassAdapter.getField(name);
+  }
+
+  @Override
+  public boolean hasField(String name) {
+    return reflectionClassAdapter.hasField(name);
+  }
+
+  @Override
+  public List<ResolvedFieldDeclaration> getAllFields() {
+    return reflectionClassAdapter.getAllFields();
+  }
+
+  @Override
+  public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+    return reflectionClassAdapter.getDeclaredMethods();
+  }
+
+  @Override
+  public boolean isAssignableBy(ResolvedType type) {
+    return reflectionClassAdapter.isAssignableBy(type);
+  }
+
+  @Override
+  public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+    return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+  }
+
+  @Override
+  public boolean hasDirectlyAnnotation(String qualifiedName) {
+    return reflectionClassAdapter.hasDirectlyAnnotation(qualifiedName);
+  }
+
+  @Override
+  public String getName() {
+    return clazz.getSimpleName();
+  }
+
+  @Override
+  public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+    return reflectionClassAdapter.getTypeParameters();
+  }
+
+  public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes, boolean staticOnly) {
+    return ReflectionMethodResolutionLogic.solveMethod(name, parameterTypes, staticOnly,
+            typeSolver,this, clazz);
+  }
+
+  public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> parameterTypes, TypeSolver typeSolver,
+                                                  Context invokationContext, List<ResolvedType> typeParameterValues) {
+    Optional<MethodUsage> res = ReflectionMethodResolutionLogic.solveMethodAsUsage(name, parameterTypes, typeSolver, invokationContext,
+            typeParameterValues, this, clazz);
+    if (res.isPresent()) {
+        // We have to replace method type typeParametersValues here
+        InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
+        MethodUsage methodUsage = res.get();
+        int i = 0;
+        List<ResolvedType> parameters = new LinkedList<>();
+        for (ResolvedType actualType : parameterTypes) {
+          ResolvedType formalType = methodUsage.getParamType(i);
+            // We need to replace the class type typeParametersValues (while we derive the method ones)
+
+            parameters.add(inferenceContext.addPair(formalType, actualType));
+            i++;
+        }
+        try {
+          ResolvedType returnType = inferenceContext.addSingle(methodUsage.returnType());
+            for (int j=0;j<parameters.size();j++) {
+                methodUsage = methodUsage.replaceParamType(j, inferenceContext.resolve(parameters.get(j)));
+            }
+            methodUsage = methodUsage.replaceReturnType(inferenceContext.resolve(returnType));
+            return Optional.of(methodUsage);
+        } catch (ConfilictingGenericTypesException e) {
+            return Optional.empty();
+        }
+    } else {
+        return res;
+    }
+}
+
+  @Override
+  public List<ResolvedEnumConstantDeclaration> getEnumConstants() {
+      return Arrays.stream(clazz.getFields())
+              .filter(f -> f.isEnumConstant())
+              .map(c -> new ReflectionEnumConstantDeclaration(c, typeSolver))
+              .collect(Collectors.toList());
+  }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java
new file mode 100644
index 0000000..fe0fc34
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionFactory {
+
+    public static ResolvedReferenceTypeDeclaration typeDeclarationFor(Class<?> clazz, TypeSolver typeSolver) {
+        if (clazz.isArray()) {
+            throw new IllegalArgumentException("No type declaration available for an Array");
+        } else if (clazz.isPrimitive()) {
+            throw new IllegalArgumentException();
+        } else if (clazz.isInterface()) {
+            return new ReflectionInterfaceDeclaration(clazz, typeSolver);
+        } else if (clazz.isEnum()) {
+            return new ReflectionEnumDeclaration(clazz, typeSolver);
+        } else {
+            return new ReflectionClassDeclaration(clazz, typeSolver);
+        }
+    }
+
+    public static ResolvedType typeUsageFor(java.lang.reflect.Type type, TypeSolver typeSolver) {
+        if (type instanceof java.lang.reflect.TypeVariable) {
+            java.lang.reflect.TypeVariable<?> tv = (java.lang.reflect.TypeVariable<?>) type;
+            boolean declaredOnClass = tv.getGenericDeclaration() instanceof java.lang.reflect.Type;
+            ResolvedTypeParameterDeclaration typeParameter = new ReflectionTypeParameter(tv, declaredOnClass, typeSolver);
+            return new ResolvedTypeVariable(typeParameter);
+        } else if (type instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) type;
+            ResolvedReferenceType rawType = typeUsageFor(pt.getRawType(), typeSolver).asReferenceType();
+            List<java.lang.reflect.Type> actualTypes = new ArrayList<>();
+            actualTypes.addAll(Arrays.asList(pt.getActualTypeArguments()));
+            // we consume the actual types
+            rawType = rawType.transformTypeParameters(tp -> typeUsageFor(actualTypes.remove(0), typeSolver)).asReferenceType();
+            return rawType;
+        } else if (type instanceof Class) {
+            Class<?> c = (Class<?>) type;
+            if (c.isPrimitive()) {
+                if (c.getName().equals(Void.TYPE.getName())) {
+                    return ResolvedVoidType.INSTANCE;
+                } else {
+                    return ResolvedPrimitiveType.byName(c.getName());
+                }
+            } else if (c.isArray()) {
+                return new ResolvedArrayType(typeUsageFor(c.getComponentType(), typeSolver));
+            } else {
+                return new ReferenceTypeImpl(typeDeclarationFor(c, typeSolver), typeSolver);
+            }
+        } else if (type instanceof GenericArrayType) {
+            GenericArrayType genericArrayType = (GenericArrayType) type;
+            return new ResolvedArrayType(typeUsageFor(genericArrayType.getGenericComponentType(), typeSolver));
+        } else if (type instanceof WildcardType) {
+            WildcardType wildcardType = (WildcardType) type;
+            if (wildcardType.getLowerBounds().length > 0 && wildcardType.getUpperBounds().length > 0) {
+                if (wildcardType.getUpperBounds().length == 1 && wildcardType.getUpperBounds()[0].getTypeName().equals("java.lang.Object")) {
+                    // ok, it does not matter
+                }
+            }
+            if (wildcardType.getLowerBounds().length > 0) {
+                if (wildcardType.getLowerBounds().length > 1) {
+                    throw new UnsupportedOperationException();
+                }
+                return ResolvedWildcard.superBound(typeUsageFor(wildcardType.getLowerBounds()[0], typeSolver));
+            }
+            if (wildcardType.getUpperBounds().length > 0) {
+                if (wildcardType.getUpperBounds().length > 1) {
+                    throw new UnsupportedOperationException();
+                }
+                return ResolvedWildcard.extendsBound(typeUsageFor(wildcardType.getUpperBounds()[0], typeSolver));
+            }
+            return ResolvedWildcard.UNBOUNDED;
+        } else {
+            throw new UnsupportedOperationException(type.getClass().getCanonicalName() + " " + type);
+        }
+    }
+
+    static AccessSpecifier modifiersToAccessLevel(final int modifiers) {
+        if (Modifier.isPublic(modifiers)) {
+            return AccessSpecifier.PUBLIC;
+        } else if (Modifier.isProtected(modifiers)) {
+            return AccessSpecifier.PROTECTED;
+        } else if (Modifier.isPrivate(modifiers)) {
+            return AccessSpecifier.PRIVATE;
+        } else {
+            return AccessSpecifier.DEFAULT;
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java
new file mode 100644
index 0000000..198a3e0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionFieldDeclaration implements ResolvedFieldDeclaration {
+
+    private Field field;
+    private TypeSolver typeSolver;
+    private ResolvedType type;
+
+    public ReflectionFieldDeclaration(Field field, TypeSolver typeSolver) {
+        this.field = field;
+        this.typeSolver = typeSolver;
+        this.type = calcType();
+    }
+
+    private ReflectionFieldDeclaration(Field field, TypeSolver typeSolver, ResolvedType type) {
+        this.field = field;
+        this.typeSolver = typeSolver;
+        this.type = type;
+    }
+
+    @Override
+    public ResolvedType getType() {
+        return type;
+    }
+
+    private ResolvedType calcType() {
+        // TODO consider interfaces, enums, primitive types, arrays
+        return ReflectionFactory.typeUsageFor(field.getGenericType(), typeSolver);
+    }
+
+    @Override
+    public String getName() {
+        return field.getName();
+    }
+
+    @Override
+    public boolean isStatic() {
+        return Modifier.isStatic(field.getModifiers());
+    }
+
+    @Override
+    public boolean isField() {
+        return true;
+    }
+
+    @Override
+    public ResolvedTypeDeclaration declaringType() {
+        return ReflectionFactory.typeDeclarationFor(field.getDeclaringClass(), typeSolver);
+    }
+
+    public ResolvedFieldDeclaration replaceType(ResolvedType fieldType) {
+        return new ReflectionFieldDeclaration(field, typeSolver, fieldType);
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public boolean isType() {
+        return false;
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return ReflectionFactory.modifiersToAccessLevel(field.getModifiers());
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
new file mode 100644
index 0000000..7453e23
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder;
+import com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration;
+import com.github.javaparser.symbolsolver.logic.ConfilictingGenericTypesException;
+import com.github.javaparser.symbolsolver.logic.InferenceContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.NullType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+
+import java.lang.reflect.Field;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionInterfaceDeclaration extends AbstractTypeDeclaration implements ResolvedInterfaceDeclaration {
+
+    ///
+    /// Fields
+    ///
+
+    private Class<?> clazz;
+    private TypeSolver typeSolver;
+    private ReflectionClassAdapter reflectionClassAdapter;
+
+    ///
+    /// Constructor
+    ///
+
+    public ReflectionInterfaceDeclaration(Class<?> clazz, TypeSolver typeSolver) {
+        if (!clazz.isInterface()) {
+            throw new IllegalArgumentException();
+        }
+
+        this.clazz = clazz;
+        this.typeSolver = typeSolver;
+        this.reflectionClassAdapter = new ReflectionClassAdapter(clazz, typeSolver, this);
+    }
+
+    ///
+    /// Public methods
+    ///
+
+    @Override
+    public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+        return isAssignableBy(new ReferenceTypeImpl(other, typeSolver));
+    }
+
+    @Override
+    public String getPackageName() {
+        if (clazz.getPackage() != null) {
+            return clazz.getPackage().getName();
+        }
+        return null;
+    }
+
+    @Override
+    public String getClassName() {
+        String canonicalName = clazz.getCanonicalName();
+        if (canonicalName != null && getPackageName() != null) {
+            return canonicalName.substring(getPackageName().length() + 1, canonicalName.length());
+        }
+        return null;
+    }
+
+    @Override
+    public String getQualifiedName() {
+        return clazz.getCanonicalName();
+    }
+
+    @Deprecated
+    public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes, boolean staticOnly) {
+        return ReflectionMethodResolutionLogic.solveMethod(name, parameterTypes, staticOnly,
+                typeSolver,this, clazz);
+    }
+
+    @Override
+    public String toString() {
+        return "ReflectionInterfaceDeclaration{" +
+                "clazz=" + clazz.getCanonicalName() +
+                '}';
+    }
+
+    public ResolvedType getUsage(Node node) {
+        return new ReferenceTypeImpl(this, typeSolver);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ReflectionInterfaceDeclaration)) return false;
+
+        ReflectionInterfaceDeclaration that = (ReflectionInterfaceDeclaration) o;
+
+        if (!clazz.getCanonicalName().equals(that.clazz.getCanonicalName())) return false;
+
+        if (!getTypeParameters().equals(that.getTypeParameters())) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return clazz.hashCode();
+    }
+
+    public Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> parameterTypes, TypeSolver typeSolver,
+                                                    Context invokationContext, List<ResolvedType> typeParameterValues) {
+        Optional<MethodUsage> res = ReflectionMethodResolutionLogic.solveMethodAsUsage(name, parameterTypes, typeSolver, invokationContext,
+                typeParameterValues, this, clazz);
+        if (res.isPresent()) {
+            // We have to replace method type typeParametersValues here
+            InferenceContext inferenceContext = new InferenceContext(MyObjectProvider.INSTANCE);
+            MethodUsage methodUsage = res.get();
+            int i = 0;
+            List<ResolvedType> parameters = new LinkedList<>();
+            for (ResolvedType actualType : parameterTypes) {
+                ResolvedType formalType = methodUsage.getParamType(i);
+                // We need to replace the class type typeParametersValues (while we derive the method ones)
+
+                parameters.add(inferenceContext.addPair(formalType, actualType));
+                i++;
+            }
+            try {
+                ResolvedType returnType = inferenceContext.addSingle(methodUsage.returnType());
+                for (int j=0;j<parameters.size();j++) {
+                    methodUsage = methodUsage.replaceParamType(j, inferenceContext.resolve(parameters.get(j)));
+                }
+                methodUsage = methodUsage.replaceReturnType(inferenceContext.resolve(returnType));
+                return Optional.of(methodUsage);
+            } catch (ConfilictingGenericTypesException e) {
+                return Optional.empty();
+            }
+        } else {
+            return res;
+        }
+    }
+
+    @Override
+    public boolean canBeAssignedTo(ResolvedReferenceTypeDeclaration other) {
+        if (other instanceof LambdaArgumentTypePlaceholder) {
+            return isFunctionalInterface();
+        }
+        if (other.getQualifiedName().equals(getQualifiedName())) {
+            return true;
+        }
+        if (this.clazz.getSuperclass() != null
+                && new ReflectionInterfaceDeclaration(clazz.getSuperclass(), typeSolver).canBeAssignedTo(other)) {
+            return true;
+        }
+        for (Class interfaze : clazz.getInterfaces()) {
+            if (new ReflectionInterfaceDeclaration(interfaze, typeSolver).canBeAssignedTo(other)) {
+                return true;
+            }
+        }
+
+        if (other.getQualifiedName().equals(Object.class.getCanonicalName())) {
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType type) {
+        if (type instanceof NullType) {
+            return true;
+        }
+        if (type instanceof LambdaArgumentTypePlaceholder) {
+            return isFunctionalInterface();
+        }
+        if (type.isArray()) {
+            return false;
+        }
+        if (type.isPrimitive()) {
+            return false;
+        }
+        if (type.describe().equals(getQualifiedName())) {
+            return true;
+        }
+        if (type instanceof ReferenceTypeImpl) {
+            ReferenceTypeImpl otherTypeDeclaration = (ReferenceTypeImpl) type;
+            return otherTypeDeclaration.getTypeDeclaration().canBeAssignedTo(this);
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isTypeParameter() {
+        return false;
+    }
+
+    @Override
+    public ResolvedFieldDeclaration getField(String name) {
+        return reflectionClassAdapter.getField(name);
+    }
+
+    @Override
+    public List<ResolvedFieldDeclaration> getAllFields() {
+        return reflectionClassAdapter.getAllFields();
+    }
+
+    @Deprecated
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
+        for (Field field : clazz.getFields()) {
+            if (field.getName().equals(name)) {
+                return SymbolReference.solved(new ReflectionFieldDeclaration(field, typeSolver));
+            }
+        }
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getAncestors() {
+        return reflectionClassAdapter.getAncestors();
+    }
+
+    @Override
+    public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+        return reflectionClassAdapter.getDeclaredMethods();
+    }
+
+    @Override
+    public boolean hasField(String name) {
+        return reflectionClassAdapter.hasField(name);
+    }
+
+    @Override
+    public String getName() {
+        return clazz.getSimpleName();
+    }
+
+    @Override
+    public boolean isInterface() {
+        return true;
+    }
+
+    @Override
+    public List<ResolvedReferenceType> getInterfacesExtended() {
+        List<ResolvedReferenceType> res = new ArrayList<>();
+        for (Class i : clazz.getInterfaces()) {
+            res.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(i, typeSolver), typeSolver));
+        }
+        return res;
+    }
+    
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        return reflectionClassAdapter.containerType();
+    }
+
+    @Override
+    public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+        return Arrays.stream(this.clazz.getDeclaredClasses())
+                .map(ic -> ReflectionFactory.typeDeclarationFor(ic, typeSolver))
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public ResolvedInterfaceDeclaration asInterface() {
+        return this;
+    }
+
+    @Override
+    public boolean hasDirectlyAnnotation(String canonicalName) {
+        return reflectionClassAdapter.hasDirectlyAnnotation(canonicalName);
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return reflectionClassAdapter.getTypeParameters();
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return ReflectionFactory.modifiersToAccessLevel(this.clazz.getModifiers());
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java
new file mode 100644
index 0000000..04047c6
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionMethodDeclaration implements ResolvedMethodDeclaration {
+
+    private Method method;
+    private TypeSolver typeSolver;
+
+    public ReflectionMethodDeclaration(Method method, TypeSolver typeSolver) {
+        this.method = method;
+        if (method.isSynthetic() || method.isBridge()) {
+            throw new IllegalArgumentException();
+        }
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public String getName() {
+        return method.getName();
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "ReflectionMethodDeclaration{" +
+                "method=" + method +
+                '}';
+    }
+
+    @Override
+    public boolean isType() {
+        return false;
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration declaringType() {
+        if (method.getDeclaringClass().isInterface()) {
+            return new ReflectionInterfaceDeclaration(method.getDeclaringClass(), typeSolver);
+        }
+        if (method.getDeclaringClass().isEnum()) {
+            return new ReflectionEnumDeclaration(method.getDeclaringClass(), typeSolver);
+        } else {
+            return new ReflectionClassDeclaration(method.getDeclaringClass(), typeSolver);
+        }
+    }
+
+    @Override
+    public ResolvedType getReturnType() {
+        return ReflectionFactory.typeUsageFor(method.getGenericReturnType(), typeSolver);
+    }
+
+    @Override
+    public int getNumberOfParams() {
+        return method.getParameterTypes().length;
+    }
+
+    @Override
+    public ResolvedParameterDeclaration getParam(int i) {
+        boolean variadic = false;
+        if (method.isVarArgs()) {
+            variadic = i == (method.getParameterCount() - 1);
+        }
+        return new ReflectionParameterDeclaration(method.getParameterTypes()[i], method.getGenericParameterTypes()[i], typeSolver, variadic);
+    }
+
+    @Override
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return Arrays.stream(method.getTypeParameters()).map((refTp) -> new ReflectionTypeParameter(refTp, false, typeSolver)).collect(Collectors.toList());
+    }
+
+    public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
+        return new MethodDeclarationCommonLogic(this, typeSolver).resolveTypeVariables(context, parameterTypes);
+    }
+
+    @Override
+    public boolean isAbstract() {
+        return Modifier.isAbstract(method.getModifiers());
+    }
+
+    @Override
+    public boolean isDefaultMethod() {
+        return method.isDefault();
+    }
+
+    @Override
+    public boolean isStatic() {
+        return Modifier.isStatic(method.getModifiers());
+    }
+
+    @Override
+    public AccessSpecifier accessSpecifier() {
+        return ReflectionFactory.modifiersToAccessLevel(this.method.getModifiers());
+    }
+
+    @Override
+    public int getNumberOfSpecifiedExceptions() {
+        return this.method.getExceptionTypes().length;
+    }
+
+    @Override
+    public ResolvedType getSpecifiedException(int index) {
+        if (index < 0 || index >= getNumberOfSpecifiedExceptions()) {
+            throw new IllegalArgumentException();
+        }
+        return ReflectionFactory.typeUsageFor(this.method.getExceptionTypes()[index], typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java
new file mode 100644
index 0000000..acf39c2
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+class ReflectionMethodResolutionLogic {
+
+    static SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<ResolvedType> parameterTypes, boolean staticOnly,
+                                                                  TypeSolver typeSolver, ResolvedReferenceTypeDeclaration scopeType,
+                                                                  Class clazz){
+        List<ResolvedMethodDeclaration> methods = new ArrayList<>();
+        Predicate<Method> staticOnlyCheck = m -> !staticOnly || (staticOnly && Modifier.isStatic(m.getModifiers()));
+        for (Method method : clazz.getMethods()) {
+            if (method.isBridge() || method.isSynthetic() || !method.getName().equals(name)|| !staticOnlyCheck.test(method)) continue;
+            ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver);
+            methods.add(methodDeclaration);
+        }
+
+        for (ResolvedReferenceType ancestor : scopeType.getAncestors()) {
+            SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, parameterTypes, staticOnly, typeSolver);
+            if (ref.isSolved()) {
+                methods.add(ref.getCorrespondingDeclaration());
+            }
+        }
+
+        if (scopeType.getAncestors().isEmpty()){
+            ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+            SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, parameterTypes, staticOnly, typeSolver);
+            if (ref.isSolved()) {
+                methods.add(ref.getCorrespondingDeclaration());
+            }
+        }
+        return MethodResolutionLogic.findMostApplicable(methods, name, parameterTypes, typeSolver);
+    }
+
+    static Optional<MethodUsage> solveMethodAsUsage(String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver,
+                                                    Context invokationContext, List<ResolvedType> typeParameterValues,
+                                                    ResolvedReferenceTypeDeclaration scopeType, Class clazz) {
+        if (typeParameterValues.size() != scopeType.getTypeParameters().size()) {
+            // if it is zero we are going to ignore them
+            if (!scopeType.getTypeParameters().isEmpty()) {
+                // Parameters not specified, so default to Object
+                typeParameterValues = new ArrayList<>();
+                for (int i = 0; i < scopeType.getTypeParameters().size(); i++) {
+                    typeParameterValues.add(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver));
+                }
+            }
+        }
+        List<MethodUsage> methods = new ArrayList<>();
+        for (Method method : clazz.getMethods()) {
+            if (method.getName().equals(name) && !method.isBridge() && !method.isSynthetic()) {
+                ResolvedMethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(method, typeSolver);
+                MethodUsage methodUsage = replaceParams(typeParameterValues, scopeType, methodDeclaration);
+                methods.add(methodUsage);
+            }
+
+        }
+
+        for(ResolvedReferenceType ancestor : scopeType.getAncestors()){
+            SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, typeSolver);
+            if (ref.isSolved()){
+                ResolvedMethodDeclaration correspondingDeclaration = ref.getCorrespondingDeclaration();
+                MethodUsage methodUsage = replaceParams(typeParameterValues, ancestor.getTypeDeclaration(), correspondingDeclaration);
+                methods.add(methodUsage);
+            }
+        }
+
+        if (scopeType.getAncestors().isEmpty()){
+            ReferenceTypeImpl objectClass = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+            SymbolReference<ResolvedMethodDeclaration> ref = MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, argumentsTypes, typeSolver);
+            if (ref.isSolved()) {
+                MethodUsage usage = replaceParams(typeParameterValues, objectClass.getTypeDeclaration(), ref.getCorrespondingDeclaration());
+                methods.add(usage);
+            }
+        }
+
+        final List<ResolvedType> finalTypeParameterValues = typeParameterValues;
+        argumentsTypes = argumentsTypes.stream().map((pt) -> {
+            int i = 0;
+            for (ResolvedTypeParameterDeclaration tp : scopeType.getTypeParameters()) {
+                pt = pt.replaceTypeVariables(tp, finalTypeParameterValues.get(i));
+                i++;
+            }
+            return pt;
+        }).collect(Collectors.toList());
+        return MethodResolutionLogic.findMostApplicableUsage(methods, name, argumentsTypes, typeSolver);
+    }
+
+    private static MethodUsage replaceParams(List<ResolvedType> typeParameterValues, ResolvedReferenceTypeDeclaration typeParametrizable, ResolvedMethodDeclaration methodDeclaration) {
+        MethodUsage methodUsage = new MethodUsage(methodDeclaration);
+        int i = 0;
+
+        // Only replace if we have enough values provided
+        if (typeParameterValues.size() == typeParametrizable.getTypeParameters().size()){
+            for (ResolvedTypeParameterDeclaration tp : typeParametrizable.getTypeParameters()) {
+                methodUsage = methodUsage.replaceTypeParameter(tp, typeParameterValues.get(i));
+                i++;
+            }
+        }
+
+        for (ResolvedTypeParameterDeclaration methodTypeParameter : methodDeclaration.getTypeParameters()) {
+            methodUsage = methodUsage.replaceTypeParameter(methodTypeParameter, new ResolvedTypeVariable(methodTypeParameter));
+        }
+
+        return methodUsage;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java
new file mode 100644
index 0000000..be5e9df
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionParameterDeclaration implements ResolvedParameterDeclaration {
+    private Class<?> type;
+    private java.lang.reflect.Type genericType;
+    private TypeSolver typeSolver;
+    private boolean variadic;
+
+    public ReflectionParameterDeclaration(Class<?> type, java.lang.reflect.Type genericType, TypeSolver typeSolver, boolean variadic) {
+        this.type = type;
+        this.genericType = genericType;
+        this.typeSolver = typeSolver;
+        this.variadic = variadic;
+    }
+
+    @Override
+    public String getName() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String toString() {
+        return "ReflectionParameterDeclaration{" +
+                "type=" + type +
+                '}';
+    }
+
+    @Override
+    public boolean isField() {
+        return false;
+    }
+
+    @Override
+    public boolean isParameter() {
+        return true;
+    }
+
+    @Override
+    public boolean isVariadic() {
+        return variadic;
+    }
+
+    @Override
+    public boolean isType() {
+        return false;
+    }
+
+    @Override
+    public ResolvedType getType() {
+        return ReflectionFactory.typeUsageFor(genericType, typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
new file mode 100644
index 0000000..0532ed6
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParametrizable;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.Method;
+import java.lang.reflect.TypeVariable;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionTypeParameter implements ResolvedTypeParameterDeclaration {
+
+    private TypeVariable typeVariable;
+    private TypeSolver typeSolver;
+    private ResolvedTypeParametrizable container;
+
+    public ReflectionTypeParameter(TypeVariable typeVariable, boolean declaredOnClass, TypeSolver typeSolver) {
+        GenericDeclaration genericDeclaration = typeVariable.getGenericDeclaration();
+        if (genericDeclaration instanceof Class) {
+            container = ReflectionFactory.typeDeclarationFor((Class) genericDeclaration, typeSolver);
+        } else if (genericDeclaration instanceof Method) {
+            container = new ReflectionMethodDeclaration((Method) genericDeclaration, typeSolver);
+        } else if (genericDeclaration instanceof Constructor) {
+            container = new ReflectionConstructorDeclaration((Constructor) genericDeclaration, typeSolver);
+        }
+        this.typeVariable = typeVariable;
+        this.typeSolver = typeSolver;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof ResolvedTypeParameterDeclaration)) return false;
+
+        ResolvedTypeParameterDeclaration that = (ResolvedTypeParameterDeclaration) o;
+
+        if (!getQualifiedName().equals(that.getQualifiedName())) {
+            return false;
+        }
+        if (declaredOnType() != that.declaredOnType()) {
+            return false;
+        }
+        if (declaredOnMethod() != that.declaredOnMethod()) {
+            return false;
+        }
+        // TODO check bounds
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = typeVariable.hashCode();
+        result = 31 * result + container.hashCode();
+        return result;
+    }
+
+    @Override
+    public String getName() {
+        return typeVariable.getName();
+    }
+
+    @Override
+    public String getContainerQualifiedName() {
+        if (container instanceof ResolvedReferenceTypeDeclaration) {
+            return ((ResolvedReferenceTypeDeclaration) container).getQualifiedName();
+        } else {
+            return ((ResolvedMethodLikeDeclaration) container).getQualifiedSignature();
+        }
+    }
+
+    @Override
+    public String getContainerId() {
+        if (container instanceof ResolvedReferenceTypeDeclaration) {
+            return ((ResolvedReferenceTypeDeclaration) container).getId();
+        } else {
+            return ((ResolvedMethodLikeDeclaration) container).getQualifiedSignature();
+        }
+    }
+    
+    @Override
+    public ResolvedTypeParametrizable getContainer() {
+        return this.container;
+    }
+
+    @Override
+    public List<Bound> getBounds() {
+        return Arrays.stream(typeVariable.getBounds()).map((refB) -> Bound.extendsBound(ReflectionFactory.typeUsageFor(refB, typeSolver))).collect(Collectors.toList());
+    }
+
+    @Override
+    public String toString() {
+        return "ReflectionTypeParameter{" +
+                "typeVariable=" + typeVariable +
+                '}';
+    }
+
+    @Override
+    public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+        if (container instanceof ResolvedReferenceTypeDeclaration) {
+            return Optional.of((ResolvedReferenceTypeDeclaration) container);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java
new file mode 100644
index 0000000..e22c204
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator.java
@@ -0,0 +1,25 @@
+package com.github.javaparser.symbolsolver.reflectionmodel.comparators;
+
+import java.util.Comparator;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ClassComparator implements Comparator<Class<?>> {
+
+    @Override
+    public int compare(Class<?> o1, Class<?> o2) {
+        int subCompare;
+        subCompare = o1.getCanonicalName().compareTo(o2.getCanonicalName());
+        if (subCompare != 0) return subCompare;
+        subCompare = Boolean.compare(o1.isAnnotation(), o2.isAnnotation());
+        if (subCompare != 0) return subCompare;
+        subCompare = Boolean.compare(o1.isArray(), o2.isArray());
+        if (subCompare != 0) return subCompare;
+        subCompare = Boolean.compare(o1.isEnum(), o2.isEnum());
+        if (subCompare != 0) return subCompare;
+        subCompare = Boolean.compare(o1.isInterface(), o2.isInterface());
+        if (subCompare != 0) return subCompare;
+        return 0;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java
new file mode 100644
index 0000000..9f2fcb1
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator.java
@@ -0,0 +1,25 @@
+package com.github.javaparser.symbolsolver.reflectionmodel.comparators;
+
+import java.lang.reflect.Method;
+import java.util.Comparator;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class MethodComparator implements Comparator<Method> {
+
+    @Override
+    public int compare(Method o1, Method o2) {
+        int compareName = o1.getName().compareTo(o2.getName());
+        if (compareName != 0) return compareName;
+        int compareNParams = o1.getParameterCount() - o2.getParameterCount();
+        if (compareNParams != 0) return compareNParams;
+        for (int i = 0; i < o1.getParameterCount(); i++) {
+            int compareParam = new ParameterComparator().compare(o1.getParameters()[i], o2.getParameters()[i]);
+            if (compareParam != 0) return compareParam;
+        }
+        int compareResult = new ClassComparator().compare(o1.getReturnType(), o2.getReturnType());
+        if (compareResult != 0) return compareResult;
+        return 0;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java
new file mode 100644
index 0000000..42ed6b8
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator.java
@@ -0,0 +1,19 @@
+package com.github.javaparser.symbolsolver.reflectionmodel.comparators;
+
+import java.lang.reflect.Parameter;
+import java.util.Comparator;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ParameterComparator implements Comparator<Parameter> {
+
+    @Override
+    public int compare(Parameter o1, Parameter o2) {
+        int compareName = o1.getName().compareTo(o2.getName());
+        if (compareName != 0) return compareName;
+        int compareType = new ClassComparator().compare(o1.getType(), o2.getType());
+        if (compareType != 0) return compareType;
+        return 0;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java
new file mode 100644
index 0000000..9e58cbd
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/reflectionmodel/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+/**
+ * Implementation of model based on reflection.
+ */
+package com.github.javaparser.symbolsolver.reflectionmodel;
\ No newline at end of file
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java
new file mode 100644
index 0000000..dfd50ed
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.resolution.MethodAmbiguityException;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author Fred Lefévère-Laoide
+ */
+public class ConstructorResolutionLogic {
+
+    private static List<ResolvedType> groupVariadicParamValues(List<ResolvedType> argumentsTypes, int startVariadic,
+                                                               ResolvedType variadicType) {
+        List<ResolvedType> res = new ArrayList<>(argumentsTypes.subList(0, startVariadic));
+        List<ResolvedType> variadicValues = argumentsTypes.subList(startVariadic, argumentsTypes.size());
+        if (variadicValues.isEmpty()) {
+            // TODO if there are no variadic values we should default to the bound of the formal type
+            res.add(variadicType);
+        } else {
+            ResolvedType componentType = findCommonType(variadicValues);
+            res.add(new ResolvedArrayType(componentType));
+        }
+        return res;
+    }
+
+    private static ResolvedType findCommonType(List<ResolvedType> variadicValues) {
+        if (variadicValues.isEmpty()) {
+            throw new IllegalArgumentException();
+        }
+        // TODO implement this decently
+        return variadicValues.get(0);
+    }
+
+    public static boolean isApplicable(ResolvedConstructorDeclaration constructor, List<ResolvedType> argumentsTypes,
+                                       TypeSolver typeSolver) {
+        return isApplicable(constructor, argumentsTypes, typeSolver, false);
+    }
+
+    private static boolean isApplicable(ResolvedConstructorDeclaration constructor, List<ResolvedType> argumentsTypes,
+                                        TypeSolver typeSolver, boolean withWildcardTolerance) {
+        if (constructor.hasVariadicParameter()) {
+            int pos = constructor.getNumberOfParams() - 1;
+            if (constructor.getNumberOfParams() == argumentsTypes.size()) {
+                // check if the last value is directly assignable as an array
+                ResolvedType expectedType = constructor.getLastParam().getType();
+                ResolvedType actualType = argumentsTypes.get(pos);
+                if (!expectedType.isAssignableBy(actualType)) {
+                    for (ResolvedTypeParameterDeclaration tp : constructor.getTypeParameters()) {
+                        expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
+                    }
+                    if (!expectedType.isAssignableBy(actualType)) {
+                        if (actualType.isArray()
+                                && expectedType.isAssignableBy(actualType.asArrayType().getComponentType())) {
+                            argumentsTypes.set(pos, actualType.asArrayType().getComponentType());
+                        } else {
+                            argumentsTypes = groupVariadicParamValues(argumentsTypes, pos,
+                                    constructor.getLastParam().getType());
+                        }
+                    }
+                } // else it is already assignable, nothing to do
+            } else {
+                if (pos > argumentsTypes.size()) {
+                    return false;
+                }
+                argumentsTypes =
+                        groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType());
+            }
+        }
+
+        if (constructor.getNumberOfParams() != argumentsTypes.size()) {
+            return false;
+        }
+        Map<String, ResolvedType> matchedParameters = new HashMap<>();
+        boolean needForWildCardTolerance = false;
+        for (int i = 0; i < constructor.getNumberOfParams(); i++) {
+            ResolvedType expectedType = constructor.getParam(i).getType();
+            ResolvedType actualType = argumentsTypes.get(i);
+            if ((expectedType.isTypeVariable() && !(expectedType.isWildcard()))
+                    && expectedType.asTypeParameter().declaredOnMethod()) {
+                matchedParameters.put(expectedType.asTypeParameter().getName(), actualType);
+                continue;
+            }
+            boolean isAssignableWithoutSubstitution =
+                    expectedType.isAssignableBy(actualType) || (constructor.getParam(i).isVariadic()
+                            && new ResolvedArrayType(expectedType).isAssignableBy(actualType));
+            if (!isAssignableWithoutSubstitution && expectedType.isReferenceType()
+                    && actualType.isReferenceType()) {
+                isAssignableWithoutSubstitution = MethodResolutionLogic.isAssignableMatchTypeParameters(
+                        expectedType.asReferenceType(), actualType.asReferenceType(), matchedParameters);
+            }
+            if (!isAssignableWithoutSubstitution) {
+                List<ResolvedTypeParameterDeclaration> typeParameters = constructor.getTypeParameters();
+                typeParameters.addAll(constructor.declaringType().getTypeParameters());
+                for (ResolvedTypeParameterDeclaration tp : typeParameters) {
+                    expectedType = MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver);
+                }
+
+                if (!expectedType.isAssignableBy(actualType)) {
+                    if (actualType.isWildcard() && withWildcardTolerance && !expectedType.isPrimitive()) {
+                        needForWildCardTolerance = true;
+                        continue;
+                    }
+                    if (constructor.hasVariadicParameter() && i == constructor.getNumberOfParams() - 1) {
+                        if (new ResolvedArrayType(expectedType).isAssignableBy(actualType)) {
+                            continue;
+                        }
+                    }
+                    return false;
+                }
+            }
+        }
+        return !withWildcardTolerance || needForWildCardTolerance;
+    }
+
+    /**
+     * @param constructors        we expect the methods to be ordered such that inherited methods are later in the list
+     * @param argumentsTypes
+     * @param typeSolver
+     * @return
+     */
+    public static SymbolReference<ResolvedConstructorDeclaration> findMostApplicable(
+            List<ResolvedConstructorDeclaration> constructors, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        SymbolReference<ResolvedConstructorDeclaration> res =
+                findMostApplicable(constructors, argumentsTypes, typeSolver, false);
+        if (res.isSolved()) {
+            return res;
+        }
+        return findMostApplicable(constructors, argumentsTypes, typeSolver, true);
+    }
+
+    public static SymbolReference<ResolvedConstructorDeclaration> findMostApplicable(
+            List<ResolvedConstructorDeclaration> constructors, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, boolean wildcardTolerance) {
+        List<ResolvedConstructorDeclaration> applicableConstructors = constructors.stream().filter((m) -> isApplicable(m, argumentsTypes, typeSolver, wildcardTolerance)).collect(Collectors.toList());
+        if (applicableConstructors.isEmpty()) {
+            return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
+        }
+        if (applicableConstructors.size() == 1) {
+            return SymbolReference.solved(applicableConstructors.get(0));
+        } else {
+            ResolvedConstructorDeclaration winningCandidate = applicableConstructors.get(0);
+            ResolvedConstructorDeclaration other = null;
+            boolean possibleAmbiguity = false;
+            for (int i = 1; i < applicableConstructors.size(); i++) {
+                other = applicableConstructors.get(i);
+                if (isMoreSpecific(winningCandidate, other, typeSolver)) {
+                    possibleAmbiguity = false;
+                } else if (isMoreSpecific(other, winningCandidate, typeSolver)) {
+                    possibleAmbiguity = false;
+                    winningCandidate = other;
+                } else {
+                    if (winningCandidate.declaringType().getQualifiedName()
+                            .equals(other.declaringType().getQualifiedName())) {
+                        possibleAmbiguity = true;
+                    } else {
+                        // we expect the methods to be ordered such that inherited methods are later in the list
+                    }
+                }
+            }
+            if (possibleAmbiguity) {
+                // pick the first exact match if it exists
+                if (!MethodResolutionLogic.isExactMatch(winningCandidate, argumentsTypes)) {
+                    if (MethodResolutionLogic.isExactMatch(other, argumentsTypes)) {
+                        winningCandidate = other;
+                    } else {
+                        throw new MethodAmbiguityException("Ambiguous constructor call: cannot find a most applicable constructor: " + winningCandidate + ", " + other);
+                    }
+                }
+            }
+            return SymbolReference.solved(winningCandidate);
+        }
+    }
+
+    private static boolean isMoreSpecific(ResolvedConstructorDeclaration constructorA,
+                                          ResolvedConstructorDeclaration constructorB, TypeSolver typeSolver) {
+        boolean oneMoreSpecificFound = false;
+        if (constructorA.getNumberOfParams() < constructorB.getNumberOfParams()) {
+            return true;
+        }
+        if (constructorA.getNumberOfParams() > constructorB.getNumberOfParams()) {
+            return false;
+        }
+        for (int i = 0; i < constructorA.getNumberOfParams(); i++) {
+            ResolvedType tdA = constructorA.getParam(i).getType();
+            ResolvedType tdB = constructorB.getParam(i).getType();
+            // B is more specific
+            if (tdB.isAssignableBy(tdA) && !tdA.isAssignableBy(tdB)) {
+                oneMoreSpecificFound = true;
+            }
+            // A is more specific
+            if (tdA.isAssignableBy(tdB) && !tdB.isAssignableBy(tdA)) {
+                return false;
+            }
+            // if it matches a variadic and a not variadic I pick the not variadic
+            // FIXME
+            if (i == (constructorA.getNumberOfParams() - 1) && tdA.arrayLevel() > tdB.arrayLevel()) {
+                return true;
+            }
+        }
+        return oneMoreSpecificFound;
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java
new file mode 100644
index 0000000..01fdfaa
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic.java
@@ -0,0 +1,696 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.resolution.MethodAmbiguityException;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class MethodResolutionLogic {
+
+    private static List<ResolvedType> groupVariadicParamValues(List<ResolvedType> argumentsTypes, int startVariadic, ResolvedType variadicType) {
+        List<ResolvedType> res = new ArrayList<>(argumentsTypes.subList(0, startVariadic));
+        List<ResolvedType> variadicValues = argumentsTypes.subList(startVariadic, argumentsTypes.size());
+        if (variadicValues.isEmpty()) {
+            // TODO if there are no variadic values we should default to the bound of the formal type
+            res.add(variadicType);
+        } else {
+            ResolvedType componentType = findCommonType(variadicValues);
+            res.add(new ResolvedArrayType(componentType));
+        }
+        return res;
+    }
+
+    private static ResolvedType findCommonType(List<ResolvedType> variadicValues) {
+        if (variadicValues.isEmpty()) {
+            throw new IllegalArgumentException();
+        }
+        // TODO implement this decently
+        return variadicValues.get(0);
+    }
+
+    public static boolean isApplicable(ResolvedMethodDeclaration method, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        return isApplicable(method, name, argumentsTypes, typeSolver, false);
+    }
+
+    private static boolean isApplicable(ResolvedMethodDeclaration method, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, boolean withWildcardTolerance) {
+        if (!method.getName().equals(name)) {
+            return false;
+        }
+        if (method.hasVariadicParameter()) {
+            int pos = method.getNumberOfParams() - 1;
+            if (method.getNumberOfParams() == argumentsTypes.size()) {
+                // check if the last value is directly assignable as an array
+                ResolvedType expectedType = method.getLastParam().getType();
+                ResolvedType actualType = argumentsTypes.get(pos);
+                if (!expectedType.isAssignableBy(actualType)) {
+                    for (ResolvedTypeParameterDeclaration tp : method.getTypeParameters()) {
+                        expectedType = replaceTypeParam(expectedType, tp, typeSolver);
+                    }
+                    if (!expectedType.isAssignableBy(actualType)) {
+                        if (actualType.isArray() && expectedType.isAssignableBy(actualType.asArrayType().getComponentType())) {
+                            argumentsTypes.set(pos, actualType.asArrayType().getComponentType());
+                        } else {
+                            argumentsTypes = groupVariadicParamValues(argumentsTypes, pos, method.getLastParam().getType());
+                        }
+                    }
+                } // else it is already assignable, nothing to do
+            } else {
+                if (pos > argumentsTypes.size()) {
+                  return false;
+                }
+                argumentsTypes = groupVariadicParamValues(argumentsTypes, pos, method.getLastParam().getType());
+            }
+        }
+
+        if (method.getNumberOfParams() != argumentsTypes.size()) {
+            return false;
+        }
+        Map<String, ResolvedType> matchedParameters = new HashMap<>();
+        boolean needForWildCardTolerance = false;
+        for (int i = 0; i < method.getNumberOfParams(); i++) {
+            ResolvedType expectedType = method.getParam(i).getType();
+            ResolvedType actualType = argumentsTypes.get(i);
+            if ((expectedType.isTypeVariable() && !(expectedType.isWildcard())) && expectedType.asTypeParameter().declaredOnMethod()) {
+                matchedParameters.put(expectedType.asTypeParameter().getName(), actualType);
+                continue;
+            }
+            boolean isAssignableWithoutSubstitution = expectedType.isAssignableBy(actualType) ||
+                    (method.getParam(i).isVariadic() && new ResolvedArrayType(expectedType).isAssignableBy(actualType));
+            if (!isAssignableWithoutSubstitution && expectedType.isReferenceType() && actualType.isReferenceType()) {
+                isAssignableWithoutSubstitution = isAssignableMatchTypeParameters(
+                        expectedType.asReferenceType(),
+                        actualType.asReferenceType(),
+                        matchedParameters);
+            }
+            if (!isAssignableWithoutSubstitution) {
+                List<ResolvedTypeParameterDeclaration> typeParameters = method.getTypeParameters();
+                typeParameters.addAll(method.declaringType().getTypeParameters());
+                for (ResolvedTypeParameterDeclaration tp : typeParameters) {
+                    expectedType = replaceTypeParam(expectedType, tp, typeSolver);
+                }
+
+                if (!expectedType.isAssignableBy(actualType)) {
+                    if (actualType.isWildcard() && withWildcardTolerance && !expectedType.isPrimitive()) {
+                        needForWildCardTolerance = true;
+                        continue;
+                    }
+                    if (method.hasVariadicParameter() && i == method.getNumberOfParams() - 1) {
+                        if (new ResolvedArrayType(expectedType).isAssignableBy(actualType)) {
+                            continue;
+                        }
+                    }
+                    return false;
+                }
+            }
+        }
+        return !withWildcardTolerance || needForWildCardTolerance;
+    }
+
+    public static boolean isAssignableMatchTypeParameters(ResolvedType expected, ResolvedType actual,
+                                                          Map<String, ResolvedType> matchedParameters) {
+        if (expected.isReferenceType() && actual.isReferenceType()) {
+            return isAssignableMatchTypeParameters(expected.asReferenceType(), actual.asReferenceType(), matchedParameters);
+        } else if (expected.isTypeVariable()) {
+            matchedParameters.put(expected.asTypeParameter().getName(), actual);
+            return true;
+        } else {
+            throw new UnsupportedOperationException(expected.getClass().getCanonicalName() + " " + actual.getClass().getCanonicalName());
+        }
+    }
+
+    public static boolean isAssignableMatchTypeParameters(ResolvedReferenceType expected, ResolvedReferenceType actual,
+                                                          Map<String, ResolvedType> matchedParameters) {
+        if (actual.getQualifiedName().equals(expected.getQualifiedName())) {
+            return isAssignableMatchTypeParametersMatchingQName(expected, actual, matchedParameters);
+        } else {
+            List<ResolvedReferenceType> ancestors = actual.getAllAncestors();
+            for (ResolvedReferenceType ancestor : ancestors) {
+                if (isAssignableMatchTypeParametersMatchingQName(expected, ancestor, matchedParameters)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static boolean isAssignableMatchTypeParametersMatchingQName(ResolvedReferenceType expected, ResolvedReferenceType actual,
+                                                                        Map<String, ResolvedType> matchedParameters) {
+
+        if (!expected.getQualifiedName().equals(actual.getQualifiedName())) {
+            return false;
+        }
+        if (expected.typeParametersValues().size() != actual.typeParametersValues().size()) {
+            throw new UnsupportedOperationException();
+            //return true;
+        }
+        for (int i = 0; i < expected.typeParametersValues().size(); i++) {
+            ResolvedType expectedParam = expected.typeParametersValues().get(i);
+            ResolvedType actualParam = actual.typeParametersValues().get(i);
+
+            // In the case of nested parameterizations eg. List<R> <-> List<Integer>
+            // we should peel off one layer and ensure R <-> Integer
+            if (expectedParam.isReferenceType() && actualParam.isReferenceType()){
+                ResolvedReferenceType r1 = expectedParam.asReferenceType();
+                ResolvedReferenceType r2 = actualParam.asReferenceType();
+
+                return isAssignableMatchTypeParametersMatchingQName(r1, r2, matchedParameters);
+            }
+
+            if (expectedParam.isTypeVariable()) {
+                String expectedParamName = expectedParam.asTypeParameter().getName();
+                if (!actualParam.isTypeVariable() || !actualParam.asTypeParameter().getName().equals(expectedParamName)) {
+                    return matchTypeVariable(expectedParam.asTypeVariable(), actualParam, matchedParameters);
+                }
+            } else if (expectedParam.isReferenceType()) {
+                if (actualParam.isTypeVariable()) {
+                    return matchTypeVariable(actualParam.asTypeVariable(), expectedParam, matchedParameters);
+                } else if (!expectedParam.equals(actualParam)) {
+                    return false;
+                }
+            } else if (expectedParam.isWildcard()) {
+                if (expectedParam.asWildcard().isExtends()) {
+                    return isAssignableMatchTypeParameters(expectedParam.asWildcard().getBoundedType(), actual, matchedParameters);
+                }
+                // TODO verify super bound
+                return true;
+            } else {
+                throw new UnsupportedOperationException(expectedParam.describe());
+            }
+        }
+        return true;
+    }
+
+    private static boolean matchTypeVariable(ResolvedTypeVariable typeVariable, ResolvedType type, Map<String, ResolvedType> matchedParameters) {
+        String typeParameterName = typeVariable.asTypeParameter().getName();
+        if (matchedParameters.containsKey(typeParameterName)) {
+            ResolvedType matchedParameter = matchedParameters.get(typeParameterName);
+            if (matchedParameter.isAssignableBy(type)) {
+                return true;
+            } else if (type.isAssignableBy(matchedParameter)) {
+                // update matchedParameters to contain the more general type
+                matchedParameters.put(typeParameterName, type);
+                return true;
+            }
+            return false;
+        } else {
+            matchedParameters.put(typeParameterName, type);
+        }
+        return true;
+    }
+
+    public static ResolvedType replaceTypeParam(ResolvedType type, ResolvedTypeParameterDeclaration tp, TypeSolver typeSolver) {
+        if (type.isTypeVariable()) {
+            if (type.describe().equals(tp.getName())) {
+                List<ResolvedTypeParameterDeclaration.Bound> bounds = tp.getBounds();
+                if (bounds.size() > 1) {
+                    throw new UnsupportedOperationException();
+                } else if (bounds.size() == 1) {
+                    return bounds.get(0).getType();
+                } else {
+                    return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+                }
+            }
+            return type;
+        } else if (type.isPrimitive()) {
+            return type;
+        } else if (type.isArray()) {
+            return new ResolvedArrayType(replaceTypeParam(type.asArrayType().getComponentType(), tp, typeSolver));
+        } else if (type.isReferenceType()) {
+            ResolvedReferenceType result = type.asReferenceType();
+            result = result.transformTypeParameters(typeParam -> replaceTypeParam(typeParam, tp, typeSolver)).asReferenceType();
+            return result;
+        } else if (type.isWildcard()) {
+            if (type.describe().equals(tp.getName())) {
+                List<ResolvedTypeParameterDeclaration.Bound> bounds = tp.getBounds();
+                if (bounds.size() > 1) {
+                    throw new UnsupportedOperationException();
+                } else if (bounds.size() == 1) {
+                    return bounds.get(0).getType();
+                } else {
+                    return new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+                }
+            }
+            return type;
+        } else {
+            throw new UnsupportedOperationException("Replacing " + type + ", param " + tp + " with " + type.getClass().getCanonicalName());
+        }
+    }
+
+    public static boolean isApplicable(MethodUsage method, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        if (!method.getName().equals(name)) {
+            return false;
+        }
+        // TODO Consider varargs
+        if (method.getNoParams() != argumentsTypes.size()) {
+            return false;
+        }
+        for (int i = 0; i < method.getNoParams(); i++) {
+            ResolvedType expectedType = method.getParamType(i);
+            ResolvedType expectedTypeWithoutSubstitutions = expectedType;
+            ResolvedType expectedTypeWithInference = method.getParamType(i);
+            ResolvedType actualType = argumentsTypes.get(i);
+
+            List<ResolvedTypeParameterDeclaration> typeParameters = method.getDeclaration().getTypeParameters();
+            typeParameters.addAll(method.declaringType().getTypeParameters());
+
+            if (expectedType.describe().equals(actualType.describe())){
+                return true;
+            }
+
+            Map<ResolvedTypeParameterDeclaration, ResolvedType> derivedValues = new HashMap<>();
+            for (int j = 0; j < method.getParamTypes().size(); j++) {
+                ResolvedParameterDeclaration parameter = method.getDeclaration().getParam(i);
+                ResolvedType parameterType = parameter.getType();
+                if (parameter.isVariadic()) {
+                    parameterType = parameterType.asArrayType().getComponentType();
+                }
+                inferTypes(argumentsTypes.get(j), parameterType, derivedValues);
+            }
+
+            for (Map.Entry<ResolvedTypeParameterDeclaration, ResolvedType> entry : derivedValues.entrySet()){
+                ResolvedTypeParameterDeclaration tp = entry.getKey();
+                expectedTypeWithInference = expectedTypeWithInference.replaceTypeVariables(tp, entry.getValue());
+            }
+
+            for (ResolvedTypeParameterDeclaration tp : typeParameters) {
+                if (tp.getBounds().isEmpty()) {
+                    //expectedType = expectedType.replaceTypeVariables(tp.getName(), new ReferenceTypeUsageImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver));
+                    expectedType = expectedType.replaceTypeVariables(tp, ResolvedWildcard.extendsBound(new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver)));
+                } else if (tp.getBounds().size() == 1) {
+                    ResolvedTypeParameterDeclaration.Bound bound = tp.getBounds().get(0);
+                    if (bound.isExtends()) {
+                        //expectedType = expectedType.replaceTypeVariables(tp.getName(), bound.getType());
+                        expectedType = expectedType.replaceTypeVariables(tp, ResolvedWildcard.extendsBound(bound.getType()));
+                    } else {
+                        //expectedType = expectedType.replaceTypeVariables(tp.getName(), new ReferenceTypeUsageImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver));
+                        expectedType = expectedType.replaceTypeVariables(tp, ResolvedWildcard.superBound(bound.getType()));
+                    }
+                } else {
+                    throw new UnsupportedOperationException();
+                }
+            }
+            ResolvedType expectedType2 = expectedTypeWithoutSubstitutions;
+            for (ResolvedTypeParameterDeclaration tp : typeParameters) {
+                if (tp.getBounds().isEmpty()) {
+                    expectedType2 = expectedType2.replaceTypeVariables(tp, new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver));
+                } else if (tp.getBounds().size() == 1) {
+                    ResolvedTypeParameterDeclaration.Bound bound = tp.getBounds().get(0);
+                    if (bound.isExtends()) {
+                        expectedType2 = expectedType2.replaceTypeVariables(tp, bound.getType());
+                    } else {
+                        expectedType2 = expectedType2.replaceTypeVariables(tp, new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver));
+                    }
+                } else {
+                    throw new UnsupportedOperationException();
+                }
+            }
+            if (!expectedType.isAssignableBy(actualType)
+                    && !expectedType2.isAssignableBy(actualType)
+                    && !expectedTypeWithInference.isAssignableBy(actualType)
+                    && !expectedTypeWithoutSubstitutions.isAssignableBy(actualType)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static List<ResolvedMethodDeclaration> getMethodsWithoutDuplicates(List<ResolvedMethodDeclaration> methods) {
+        Set<ResolvedMethodDeclaration> s = new TreeSet<>((m1, m2) -> {
+            if (m1 instanceof JavaParserMethodDeclaration && m2 instanceof JavaParserMethodDeclaration &&
+                    ((JavaParserMethodDeclaration) m1).getWrappedNode().equals(((JavaParserMethodDeclaration) m2).getWrappedNode())) {
+                return 0;
+            }
+            return 1;
+        });
+        s.addAll(methods);
+        List<ResolvedMethodDeclaration> res = new ArrayList<>();
+        Set<String> usedSignatures = new HashSet<>();
+        for (ResolvedMethodDeclaration md : methods) {
+            String signature = md.getQualifiedSignature();
+            if (!usedSignatures.contains(signature)) {
+                usedSignatures.add(signature);
+                res.add(md);
+            }
+        }
+        return res;
+    }
+
+    /**
+     * @param methods        we expect the methods to be ordered such that inherited methods are later in the list
+     * @param name
+     * @param argumentsTypes
+     * @param typeSolver
+     * @return
+     */
+    public static SymbolReference<ResolvedMethodDeclaration> findMostApplicable(List<ResolvedMethodDeclaration> methods,
+                                                                                String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        SymbolReference<ResolvedMethodDeclaration> res = findMostApplicable(methods, name, argumentsTypes, typeSolver, false);
+        if (res.isSolved()) {
+            return res;
+        }
+        return findMostApplicable(methods, name, argumentsTypes, typeSolver, true);
+    }
+
+    public static SymbolReference<ResolvedMethodDeclaration> findMostApplicable(List<ResolvedMethodDeclaration> methods,
+                                                                                String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver, boolean wildcardTolerance) {
+        List<ResolvedMethodDeclaration> applicableMethods = getMethodsWithoutDuplicates(methods).stream().filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver, wildcardTolerance)).collect(Collectors.toList());
+        if (applicableMethods.isEmpty()) {
+            return SymbolReference.unsolved(ResolvedMethodDeclaration.class);
+        }
+
+        if (applicableMethods.size() > 1) {
+          List<Integer> nullParamIndexes = new ArrayList<>();
+          for (int i = 0; i < argumentsTypes.size(); i++) {
+            if (argumentsTypes.get(i).isNull()) {
+              nullParamIndexes.add(i);
+            }
+          }
+          if (!nullParamIndexes.isEmpty()) {
+            // remove method with array param if a non array exists and arg is null
+            Set<ResolvedMethodDeclaration> removeCandidates = new HashSet<>();
+            for (Integer nullParamIndex: nullParamIndexes) {
+              for (ResolvedMethodDeclaration methDecl: applicableMethods) {
+                if (methDecl.getParam(nullParamIndex.intValue()).getType().isArray()) {
+                  removeCandidates.add(methDecl);
+                }
+              }
+            }
+            if (!removeCandidates.isEmpty() && removeCandidates.size() < applicableMethods.size()) {
+              applicableMethods.removeAll(removeCandidates);
+            }
+          }
+        }
+        if (applicableMethods.size() == 1) {
+            return SymbolReference.solved(applicableMethods.get(0));
+        } else {
+            ResolvedMethodDeclaration winningCandidate = applicableMethods.get(0);
+            ResolvedMethodDeclaration other = null;
+            boolean possibleAmbiguity = false;
+            for (int i = 1; i < applicableMethods.size(); i++) {
+                other = applicableMethods.get(i);
+                if (isMoreSpecific(winningCandidate, other, argumentsTypes, typeSolver)) {
+                    possibleAmbiguity = false;
+                } else if (isMoreSpecific(other, winningCandidate, argumentsTypes, typeSolver)) {
+                    possibleAmbiguity = false;
+                    winningCandidate = other;
+                } else {
+                    if (winningCandidate.declaringType().getQualifiedName().equals(other.declaringType().getQualifiedName())) {
+                        possibleAmbiguity = true;
+                    } else {
+                        // we expect the methods to be ordered such that inherited methods are later in the list
+                    }
+                }
+            }
+            if (possibleAmbiguity) {
+              // pick the first exact match if it exists
+              if (!isExactMatch(winningCandidate, argumentsTypes)) {
+                if (isExactMatch(other, argumentsTypes)) {
+                  winningCandidate = other;
+                } else {
+                  throw new MethodAmbiguityException("Ambiguous method call: cannot find a most applicable method: " + winningCandidate + ", " + other);
+                }
+              }
+            }
+            return SymbolReference.solved(winningCandidate);
+        }
+    }
+
+    protected static boolean isExactMatch(ResolvedMethodLikeDeclaration method, List<ResolvedType> argumentsTypes) {
+      for (int i = 0; i < method.getNumberOfParams(); i++) {
+        if (!method.getParam(i).getType().equals(argumentsTypes.get(i))) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    private static boolean isMoreSpecific(ResolvedMethodDeclaration methodA, ResolvedMethodDeclaration methodB,
+                                          List<ResolvedType> argumentTypes, TypeSolver typeSolver) {
+        boolean oneMoreSpecificFound = false;
+        if (methodA.getNumberOfParams() < methodB.getNumberOfParams()) {
+            return true;
+        }
+        if (methodA.getNumberOfParams() > methodB.getNumberOfParams()) {
+            return false;
+        }
+        for (int i = 0; i < methodA.getNumberOfParams(); i++) {
+            ResolvedType tdA = methodA.getParam(i).getType();
+            ResolvedType tdB = methodB.getParam(i).getType();
+            // B is more specific
+            if (tdB.isAssignableBy(tdA) && !tdA.isAssignableBy(tdB)) {
+                oneMoreSpecificFound = true;
+            }
+            // A is more specific
+            if (tdA.isAssignableBy(tdB) && !tdB.isAssignableBy(tdA)) {
+                return false;
+            }
+        }
+
+        if (!oneMoreSpecificFound) {
+            int lastIndex = argumentTypes.size() - 1;
+
+            if (methodA.hasVariadicParameter() && !methodB.hasVariadicParameter()) {
+                // if the last argument is an array then m1 is more specific
+                if (argumentTypes.get(lastIndex).isArray()) {
+                    return true;
+                }
+
+                if (!argumentTypes.get(lastIndex).isArray()) {
+                    return false;
+                }
+            }
+            if (!methodA.hasVariadicParameter() && methodB.hasVariadicParameter()) {
+                // if the last argument is an array and m1 is not variadic then
+                // it is not more specific
+                if (argumentTypes.get(lastIndex).isArray()) {
+                    return false;
+                }
+
+                if (!argumentTypes.get(lastIndex).isArray()) {
+                    return true;
+                }
+            }
+        }
+
+        return oneMoreSpecificFound;
+    }
+
+    private static boolean isMoreSpecific(MethodUsage methodA, MethodUsage methodB, TypeSolver typeSolver) {
+        boolean oneMoreSpecificFound = false;
+        for (int i = 0; i < methodA.getNoParams(); i++) {
+            ResolvedType tdA = methodA.getParamType(i);
+            ResolvedType tdB = methodB.getParamType(i);
+
+            boolean aIsAssignableByB = tdA.isAssignableBy(tdB);
+            boolean bIsAssignableByA = tdB.isAssignableBy(tdA);
+
+            // B is more specific
+            if (bIsAssignableByA && !aIsAssignableByB) {
+                oneMoreSpecificFound = true;
+            }
+            // A is more specific
+            if (aIsAssignableByB && !bIsAssignableByA) {
+                return false;
+            }
+        }
+        return oneMoreSpecificFound;
+    }
+
+    public static Optional<MethodUsage> findMostApplicableUsage(List<MethodUsage> methods, String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        List<MethodUsage> applicableMethods = methods.stream().filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver)).collect(Collectors.toList());
+
+        if (applicableMethods.isEmpty()) {
+            return Optional.empty();
+        }
+        if (applicableMethods.size() == 1) {
+            return Optional.of(applicableMethods.get(0));
+        } else {
+            MethodUsage winningCandidate = applicableMethods.get(0);
+            for (int i = 1; i < applicableMethods.size(); i++) {
+                MethodUsage other = applicableMethods.get(i);
+                if (isMoreSpecific(winningCandidate, other, typeSolver)) {
+                    // nothing to do
+                } else if (isMoreSpecific(other, winningCandidate, typeSolver)) {
+                    winningCandidate = other;
+                } else {
+                    if (winningCandidate.declaringType().getQualifiedName().equals(other.declaringType().getQualifiedName())) {
+                        if (!areOverride(winningCandidate, other)) {
+                            throw new MethodAmbiguityException("Ambiguous method call: cannot find a most applicable method: " + winningCandidate + ", " + other + ". First declared in " + winningCandidate.declaringType().getQualifiedName());
+                        }
+                    } else {
+                        // we expect the methods to be ordered such that inherited methods are later in the list
+                        //throw new UnsupportedOperationException();
+                    }
+                }
+            }
+            return Optional.of(winningCandidate);
+        }
+    }
+
+    private static boolean areOverride(MethodUsage winningCandidate, MethodUsage other) {
+        if (!winningCandidate.getName().equals(other.getName())) {
+            return false;
+        }
+        if (winningCandidate.getNoParams() != other.getNoParams()) {
+            return false;
+        }
+        for (int i = 0; i < winningCandidate.getNoParams(); i++) {
+            if (!winningCandidate.getParamTypes().get(i).equals(other.getParamTypes().get(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static SymbolReference<ResolvedMethodDeclaration> solveMethodInType(ResolvedTypeDeclaration typeDeclaration,
+                                                                               String name, List<ResolvedType> argumentsTypes, TypeSolver typeSolver) {
+        return solveMethodInType(typeDeclaration, name, argumentsTypes, false, typeSolver);
+    }
+
+        /**
+         * Replace TypeDeclaration.solveMethod
+         *
+         * @param typeDeclaration
+         * @param name
+         * @param argumentsTypes
+         * @param staticOnly
+         * @return
+         */
+    public static SymbolReference<ResolvedMethodDeclaration> solveMethodInType(ResolvedTypeDeclaration typeDeclaration,
+                                                                               String name, List<ResolvedType> argumentsTypes, boolean staticOnly,
+                                                                               TypeSolver typeSolver) {
+        if (typeDeclaration instanceof JavaParserClassDeclaration) {
+            Context ctx = ((JavaParserClassDeclaration) typeDeclaration).getContext();
+            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+        }
+        if (typeDeclaration instanceof JavaParserInterfaceDeclaration) {
+            Context ctx = ((JavaParserInterfaceDeclaration) typeDeclaration).getContext();
+            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+        }
+        if (typeDeclaration instanceof JavaParserEnumDeclaration) {
+            if (name.equals("values") && argumentsTypes.isEmpty()) {
+                return SymbolReference.solved(new JavaParserEnumDeclaration.ValuesMethod((JavaParserEnumDeclaration) typeDeclaration, typeSolver));
+            }
+            Context ctx = ((JavaParserEnumDeclaration) typeDeclaration).getContext();
+            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+        }
+        if (typeDeclaration instanceof JavaParserAnonymousClassDeclaration) {
+        	Context ctx = ((JavaParserAnonymousClassDeclaration) typeDeclaration).getContext();
+            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
+        }
+        if (typeDeclaration instanceof ReflectionClassDeclaration) {
+            return ((ReflectionClassDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
+        }
+        if (typeDeclaration instanceof ReflectionInterfaceDeclaration) {
+          return ((ReflectionInterfaceDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
+        }
+          if (typeDeclaration instanceof ReflectionEnumDeclaration) {
+            return ((ReflectionEnumDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
+        }
+        if (typeDeclaration instanceof JavassistInterfaceDeclaration) {
+            return ((JavassistInterfaceDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
+        }
+        if (typeDeclaration instanceof JavassistClassDeclaration) {
+          return ((JavassistClassDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
+        }
+          if (typeDeclaration instanceof JavassistEnumDeclaration) {
+            return ((JavassistEnumDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
+        }
+        throw new UnsupportedOperationException(typeDeclaration.getClass().getCanonicalName());
+    }
+
+    private static void inferTypes(ResolvedType source, ResolvedType target, Map<ResolvedTypeParameterDeclaration, ResolvedType> mappings) {
+
+
+        if (source.equals(target)) {
+            return;
+        }
+        if (source.isReferenceType() && target.isReferenceType()) {
+            ResolvedReferenceType sourceRefType = source.asReferenceType();
+            ResolvedReferenceType targetRefType = target.asReferenceType();
+            if (sourceRefType.getQualifiedName().equals(targetRefType.getQualifiedName())) {
+                if (!sourceRefType.isRawType() && !targetRefType.isRawType()) {
+                    for (int i = 0; i < sourceRefType.typeParametersValues().size(); i++) {
+                        inferTypes(sourceRefType.typeParametersValues().get(i), targetRefType.typeParametersValues().get(i), mappings);
+                    }
+                }
+            }
+            return;
+        }
+        if (source.isReferenceType() && target.isWildcard()) {
+            if (target.asWildcard().isBounded()) {
+                inferTypes(source, target.asWildcard().getBoundedType(), mappings);
+                return;
+            }
+            return;
+        }
+        if (source.isWildcard() && target.isWildcard()) {
+            return;
+        }
+        if (source.isReferenceType() && target.isTypeVariable()) {
+            mappings.put(target.asTypeParameter(), source);
+            return;
+        }
+
+        if (source.isWildcard() && target.isReferenceType()){
+            if (source.asWildcard().isBounded()){
+                inferTypes(source.asWildcard().getBoundedType(), target, mappings);
+            }
+            return;
+        }
+
+        if (source.isWildcard() && target.isTypeVariable()) {
+            mappings.put(target.asTypeParameter(), source);
+            return;
+        }
+        if (source.isTypeVariable() && target.isTypeVariable()) {
+            mappings.put(target.asTypeParameter(), source);
+            return;
+        }
+        if (source.isPrimitive() || target.isPrimitive()) {
+            return;
+        }
+        if (source.isNull()) {
+            return;
+        }
+    }
+
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java
new file mode 100644
index 0000000..322096f
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolDeclarator.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface SymbolDeclarator {
+
+    List<ResolvedValueDeclaration> getSymbolDeclarations();
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java
new file mode 100644
index 0000000..ee4a735
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/SymbolSolver.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class SymbolSolver {
+
+    private TypeSolver typeSolver;
+
+    public SymbolSolver(TypeSolver typeSolver) {
+        if (typeSolver == null) throw new IllegalArgumentException();
+
+        this.typeSolver = typeSolver;
+    }
+
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, Context context) {
+        return context.solveSymbol(name, typeSolver);
+    }
+
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, Node node) {
+        return solveSymbol(name, JavaParserFactory.getContext(node, typeSolver));
+    }
+
+    public Optional<Value> solveSymbolAsValue(String name, Context context) {
+        return context.solveSymbolAsValue(name, typeSolver);
+    }
+
+    public Optional<Value> solveSymbolAsValue(String name, Node node) {
+        Context context = JavaParserFactory.getContext(node, typeSolver);
+        return solveSymbolAsValue(name, context);
+    }
+
+    public SymbolReference<? extends ResolvedTypeDeclaration> solveType(String name, Context context) {
+        return context.solveType(name, typeSolver);
+    }
+
+    public SymbolReference<? extends ResolvedTypeDeclaration> solveType(String name, Node node) {
+        return solveType(name, JavaParserFactory.getContext(node, typeSolver));
+    }
+
+    public MethodUsage solveMethod(String methodName, List<ResolvedType> argumentsTypes, Context context) {
+        SymbolReference<ResolvedMethodDeclaration> decl = context.solveMethod(methodName, argumentsTypes, false, typeSolver);
+        if (!decl.isSolved()) {
+            throw new UnsolvedSymbolException(context.toString(), methodName);
+        }
+        return new MethodUsage(decl.getCorrespondingDeclaration());
+    }
+
+    public MethodUsage solveMethod(String methodName, List<ResolvedType> argumentsTypes, Node node) {
+        return solveMethod(methodName, argumentsTypes, JavaParserFactory.getContext(node, typeSolver));
+    }
+
+    public ResolvedTypeDeclaration solveType(com.github.javaparser.ast.type.Type type) {
+        if (type instanceof ClassOrInterfaceType) {
+
+            // FIXME should call typesolver here!
+
+            String name = ((ClassOrInterfaceType) type).getName().getId();
+            SymbolReference<ResolvedTypeDeclaration> ref = JavaParserFactory.getContext(type, typeSolver).solveType(name, typeSolver);
+            if (!ref.isSolved()) {
+                throw new UnsolvedSymbolException(JavaParserFactory.getContext(type, typeSolver).toString(), name);
+            }
+            return ref.getCorrespondingDeclaration();
+        } else {
+            throw new UnsupportedOperationException(type.getClass().getCanonicalName());
+        }
+    }
+
+    public ResolvedType solveTypeUsage(String name, Context context) {
+        Optional<ResolvedType> genericType = context.solveGenericType(name, typeSolver);
+        if (genericType.isPresent()) {
+            return genericType.get();
+        }
+        ResolvedReferenceTypeDeclaration typeDeclaration = typeSolver.solveType(name);
+        return new ReferenceTypeImpl(typeDeclaration, typeSolver);
+    }
+
+    /**
+     * Solve any possible visible symbols including: fields, internal types, type variables, the type itself or its
+     * containers.
+     * <p>
+     * It should contain its own private fields but not inherited private fields.
+     */
+    public SymbolReference<? extends ResolvedValueDeclaration> solveSymbolInType(ResolvedTypeDeclaration typeDeclaration, String name) {
+        if (typeDeclaration instanceof JavaParserClassDeclaration) {
+            Context ctx = ((JavaParserClassDeclaration) typeDeclaration).getContext();
+            return ctx.solveSymbol(name, typeSolver);
+        }
+        if (typeDeclaration instanceof JavaParserInterfaceDeclaration) {
+            Context ctx = ((JavaParserInterfaceDeclaration) typeDeclaration).getContext();
+            return ctx.solveSymbol(name, typeSolver);
+        }
+        if (typeDeclaration instanceof JavaParserEnumDeclaration) {
+            Context ctx = ((JavaParserEnumDeclaration) typeDeclaration).getContext();
+            return ctx.solveSymbol(name, typeSolver);
+        }
+        if (typeDeclaration instanceof ReflectionClassDeclaration) {
+            return ((ReflectionClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver);
+        }
+        if (typeDeclaration instanceof ReflectionInterfaceDeclaration) {
+            return ((ReflectionInterfaceDeclaration) typeDeclaration).solveSymbol(name, typeSolver);
+        }
+        if (typeDeclaration instanceof JavassistClassDeclaration) {
+            return ((JavassistClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver);
+        }
+        if (typeDeclaration instanceof JavassistEnumDeclaration) {
+            return ((JavassistEnumDeclaration) typeDeclaration).solveSymbol(name, typeSolver);
+        }
+        if (typeDeclaration instanceof JavassistInterfaceDeclaration) {
+            return ((JavassistInterfaceDeclaration) typeDeclaration).solveSymbol(name, typeSolver);
+        }
+        return SymbolReference.unsolved(ResolvedValueDeclaration.class);
+    }
+
+    /**
+     * Try to solve a symbol just in the declaration, it does not delegate to the container.
+     */
+    @Deprecated
+    public SymbolReference<ResolvedTypeDeclaration> solveTypeInType(ResolvedTypeDeclaration typeDeclaration, String name) {
+        if (typeDeclaration instanceof JavaParserClassDeclaration) {
+            return ((JavaParserClassDeclaration) typeDeclaration).solveType(name, typeSolver);
+        }
+        if (typeDeclaration instanceof JavaParserInterfaceDeclaration) {
+            return ((JavaParserInterfaceDeclaration) typeDeclaration).solveType(name, typeSolver);
+        }
+        return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java
new file mode 100644
index 0000000..79c239b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Bound.java
@@ -0,0 +1,106 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.FalseBound;
+
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Bounds are defined for Inference Variables.
+ *
+ * @author Federico Tomassetti
+ */
+public abstract class Bound {
+
+    ///
+    /// Creation of bounds
+    ///
+
+    static Bound falseBound() {
+        return FalseBound.getInstance();
+    }
+
+    ///
+    /// Satisfiability
+    ///
+
+    /**
+     * A bound is satisfied by an inference variable substitution if, after applying the substitution,
+     * the assertion is true.
+     */
+    public abstract boolean isSatisfied(InferenceVariableSubstitution inferenceVariableSubstitution);
+
+    ///
+    /// Classification of bounds
+    ///
+
+    /**
+     * Given a bound of the form α = T or T = α, we say T is an instantiation of α.
+     *
+     * Return empty if it is not an instantiation. Otherwise it returns the variable of which this is an
+     * instantiation.
+     */
+    public Optional<Instantiation> isAnInstantiation() {
+        return Optional.empty();
+    }
+
+    boolean isAnInstantiationFor(InferenceVariable v) {
+        return isAnInstantiation().isPresent() && isAnInstantiation().get().getInferenceVariable().equals(v);
+    }
+
+    /**
+     * Given a bound of the form α <: T, we say T is a proper upper bound of α.
+     *
+     * Return empty if it is not a proper upper bound. Otherwise it returns the variable of which this is an
+     * proper upper bound.
+     */
+    public Optional<ProperUpperBound> isProperUpperBound() {
+        return Optional.empty();
+    }
+
+    /**
+     * Given a bound of the form T <: α, we say T is a proper lower bound of α.
+     *
+     * Return empty if it is not a proper lower bound. Otherwise it returns the variable of which this is an
+     * proper lower bound.
+     */
+    public Optional<ProperLowerBound> isProperLowerBound() {
+        return Optional.empty();
+    }
+
+    Optional<ProperLowerBound> isProperLowerBoundFor(InferenceVariable inferenceVariable) {
+        Optional<ProperLowerBound> partial = isProperLowerBound();
+        if (partial.isPresent() && partial.get().getInferenceVariable().equals(inferenceVariable)) {
+            return partial;
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    Optional<ProperUpperBound> isProperUpperBoundFor(InferenceVariable inferenceVariable) {
+        Optional<ProperUpperBound> partial = isProperUpperBound();
+        if (partial.isPresent() && partial.get().getInferenceVariable().equals(inferenceVariable)) {
+            return partial;
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    /**
+     * Other bounds relate two inference variables, or an inference variable to a type that contains inference
+     * variables. Such bounds, of the form S = T or S <: T, are called dependencies.
+     */
+    public boolean isADependency() {
+        return false;
+    }
+
+    boolean isThrowsBoundOn(InferenceVariable inferenceVariable) {
+        return false;
+    }
+
+    ///
+    /// Other methods
+    ///
+
+    public abstract Set<InferenceVariable> usedInferenceVariables();
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java
new file mode 100644
index 0000000..59e73b1
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/BoundSet.java
@@ -0,0 +1,804 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.*;
+import com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas.TypeSameAsType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas.TypeSubtypeOfType;
+import com.github.javaparser.utils.Pair;
+
+import java.util.*;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.*;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class BoundSet {
+
+    private List<Bound> bounds = new LinkedList<>();
+
+    private static final BoundSet EMPTY = new BoundSet();
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        BoundSet boundSet = (BoundSet) o;
+
+        return new HashSet<>(bounds).equals(new HashSet<>(boundSet.bounds));
+    }
+
+    @Override
+    public int hashCode() {
+        return bounds.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "BoundSet{" +
+                "bounds=" + bounds +
+                '}';
+    }
+
+    /**
+
+     * It is sometimes convenient to refer to an empty bound set with the symbol true; this is merely out of
+     * convenience, and the two are interchangeable.
+     */
+    public boolean isTrue() {
+        return bounds.isEmpty();
+    }
+
+    public static BoundSet empty() {
+        return EMPTY;
+    }
+
+    public BoundSet withBound(Bound bound) {
+        if (this.bounds.contains(bound)) {
+            return this;
+        }
+        BoundSet boundSet = new BoundSet();
+        boundSet.bounds.addAll(this.bounds);
+        boundSet.bounds.add(bound);
+        return boundSet;
+    }
+
+    private Optional<Pair<SameAsBound, SameAsBound>> findPairSameAs(Predicate<Pair<SameAsBound, SameAsBound>> condition) {
+        for (int i=0;i<bounds.size();i++) {
+            Bound bi = bounds.get(i);
+            if (bi instanceof SameAsBound) {
+                SameAsBound si = (SameAsBound)bi;
+                for (int j = i + 1; j < bounds.size(); j++) {
+                    Bound bj = bounds.get(j);
+                    if (bj instanceof SameAsBound) {
+                        SameAsBound sj = (SameAsBound)bj;
+                        Pair<SameAsBound, SameAsBound> pair = new Pair<SameAsBound, SameAsBound>(si, sj);
+                        if (condition.test(pair)) {
+                            return Optional.of(pair);
+                        }
+                    }
+                }
+            }
+        }
+        return Optional.empty();
+    }
+
+    public boolean isEmpty() {
+        return bounds.isEmpty();
+    }
+
+    interface Processor<B1 extends Bound, B2 extends Bound, R> {
+        R process(B1 a, B2 b, R initialValue);
+    }
+
+    private <T> T forEachPairSameAs(Processor<SameAsBound, SameAsBound, T> processor, T initialValue) {
+        T currentValue = initialValue;
+        for (int i=0;i<bounds.size();i++) {
+            Bound bi = bounds.get(i);
+            if (bi instanceof SameAsBound) {
+                SameAsBound si = (SameAsBound)bi;
+                for (int j = i + 1; j < bounds.size(); j++) {
+                    Bound bj = bounds.get(j);
+                    if (bj instanceof SameAsBound) {
+                        SameAsBound sj = (SameAsBound)bj;
+                        currentValue = processor.process(si, sj, currentValue);
+                    }
+                }
+            }
+        }
+        return currentValue;
+    }
+
+    private <T> T forEachPairSameAndSubtype(Processor<SameAsBound, SubtypeOfBound, T> processor, T initialValue) {
+        T currentValue = initialValue;
+        for (int i=0;i<bounds.size();i++) {
+            Bound bi = bounds.get(i);
+            if (bi instanceof SameAsBound) {
+                SameAsBound si = (SameAsBound)bi;
+                for (int j = i + 1; j < bounds.size(); j++) {
+                    Bound bj = bounds.get(j);
+                    if (bj instanceof SubtypeOfBound) {
+                        SubtypeOfBound sj = (SubtypeOfBound)bj;
+                        currentValue = processor.process(si, sj, currentValue);
+                    }
+                }
+            }
+        }
+        return currentValue;
+    }
+
+    private <T> T forEachPairSubtypeAndSubtype(Processor<SubtypeOfBound, SubtypeOfBound, T> processor, T initialValue) {
+        T currentValue = initialValue;
+        for (int i=0;i<bounds.size();i++) {
+            Bound bi = bounds.get(i);
+            if (bi instanceof SubtypeOfBound) {
+                SubtypeOfBound si = (SubtypeOfBound)bi;
+                for (int j = i + 1; j < bounds.size(); j++) {
+                    Bound bj = bounds.get(j);
+                    if (bj instanceof SubtypeOfBound) {
+                        SubtypeOfBound sj = (SubtypeOfBound)bj;
+                        currentValue = processor.process(si, sj, currentValue);
+                    }
+                }
+            }
+        }
+        return currentValue;
+    }
+
+    private boolean areSameTypeInference(ResolvedType a, ResolvedType b) {
+        return isInferenceVariable(a) && isInferenceVariable(b) && a.equals(b);
+    }
+
+    private List<Pair<ResolvedReferenceType, ResolvedReferenceType>> findPairsOfCommonAncestors(ResolvedReferenceType r1, ResolvedReferenceType r2) {
+        List<ResolvedReferenceType> set1 = new LinkedList<>();
+        set1.add(r1);
+        set1.addAll(r1.getAllAncestors());
+        List<ResolvedReferenceType> set2 = new LinkedList<>();
+        set2.add(r2);
+        set2.addAll(r2.getAllAncestors());
+        List<Pair<ResolvedReferenceType, ResolvedReferenceType>> pairs = new LinkedList<>();
+        for (ResolvedReferenceType rtFrom1 : set1) {
+            for (ResolvedReferenceType rtFrom2 : set2) {
+                if (rtFrom1.getTypeDeclaration().equals(rtFrom2.getTypeDeclaration())) {
+                    pairs.add(new Pair<>(rtFrom1, rtFrom2));
+                }
+            }
+        }
+        return pairs;
+    }
+
+    /**
+     * Maintains a set of inference variable bounds, ensuring that these are consistent as new bounds are added.
+     * Because the bounds on one variable can sometimes impact the possible choices for another variable, this process
+     * propagates bounds between such interdependent variables.
+     */
+    public BoundSet incorporate(BoundSet otherBounds, TypeSolver typeSolver) {
+        BoundSet newBoundSet = this;
+        for (Bound b : otherBounds.bounds) {
+            newBoundSet = newBoundSet.withBound(b);
+        }
+        return newBoundSet.deriveImpliedBounds(typeSolver);
+    }
+
+    public BoundSet deriveImpliedBounds(TypeSolver typeSolver) {
+        // As bound sets are constructed and grown during inference, it is possible that new bounds can be inferred
+        // based on the assertions of the original bounds. The process of incorporation identifies these new bounds
+        // and adds them to the bound set.
+        //
+        // Incorporation can happen in two scenarios. One scenario is that the bound set contains complementary pairs
+        // of bounds; this implies new constraint formulas, as specified in §18.3.1. The other scenario is that the
+        // bound set contains a bound involving capture conversion; this implies new bounds and may imply new
+        // constraint formulas, as specified in §18.3.2. In both scenarios, any new constraint formulas are reduced,
+        // and any new bounds are added to the bound set. This may trigger further incorporation; ultimately, the set
+        // will reach a fixed point and no further bounds can be inferred.
+        //
+        // If incorporation of a bound set has reached a fixed point, and the set does not contain the bound false,
+        // then the bound set has the following properties:
+        //
+        // - For each combination of a proper lower bound L and a proper upper bound U of an inference variable, L <: U.
+        //
+        // - If every inference variable mentioned by a bound has an instantiation, the bound is satisfied by the
+        //   corresponding substitution.
+        //
+        // - Given a dependency α = β, every bound of α matches a bound of β, and vice versa.
+        //
+        // - Given a dependency α <: β, every lower bound of α is a lower bound of β, and every upper bound of β is an
+        //   upper bound of α.
+
+        ConstraintFormulaSet newConstraintsSet = ConstraintFormulaSet.empty();
+
+        // SECTION Complementary Pairs of Bounds
+        // (In this section, S and T are inference variables or types, and U is a proper type. For conciseness, a bound
+        // of the form α = T may also match a bound of the form T = α.)
+        //
+        // When a bound set contains a pair of bounds that match one of the following rules, a new constraint formula
+        // is implied:
+        //
+        // - α = S and α = T imply ‹S = T›
+
+        newConstraintsSet = forEachPairSameAs((a, b, currentConstraintSet) -> {
+            if (areSameTypeInference(a.getS(), b.getS())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(a.getT(), b.getT()));
+            }
+            if (areSameTypeInference(a.getS(), b.getT())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(a.getS(), b.getT()));
+            }
+            if (areSameTypeInference(a.getT(), b.getS())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(a.getT(), b.getS()));
+            }
+            if (areSameTypeInference(a.getT(), b.getT())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(a.getS(), b.getS()));
+            }
+            return currentConstraintSet;
+        }, newConstraintsSet);
+
+        // - α = S and α <: T imply ‹S <: T›
+
+        newConstraintsSet = forEachPairSameAndSubtype((a, b, currentConstraintSet) -> {
+            if (areSameTypeInference(a.getS(), b.getS())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSubtypeOfType(typeSolver, a.getT(), b.getT()));
+            }
+            if (areSameTypeInference(a.getT(), b.getS())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSubtypeOfType(typeSolver, a.getS(), b.getT()));
+            }
+            return currentConstraintSet;
+        }, newConstraintsSet);
+
+        // - α = S and T <: α imply ‹T <: S›
+
+        newConstraintsSet = forEachPairSameAndSubtype((a, b, currentConstraintSet) -> {
+            if (areSameTypeInference(a.getS(), b.getT())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSubtypeOfType(typeSolver, b.getS(), a.getT()));
+            }
+            if (areSameTypeInference(a.getT(), b.getT())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSubtypeOfType(typeSolver, b.getS(), a.getS()));
+            }
+            return currentConstraintSet;
+        }, newConstraintsSet);
+
+        // - S <: α and α <: T imply ‹S <: T›
+
+        newConstraintsSet = forEachPairSubtypeAndSubtype((a, b, currentConstraintSet) -> {
+            if (areSameTypeInference(a.getT(), b.getS())) {
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSubtypeOfType(typeSolver, b.getS(), a.getT()));
+            }
+            return currentConstraintSet;
+        }, newConstraintsSet);
+
+        // - α = U and S = T imply ‹S[α:=U] = T[α:=U]›
+
+        newConstraintsSet = forEachPairSameAs((a, b, currentConstraintSet) -> {
+            if (isInferenceVariable(a.getS()) && isProperType(a.getT())) {
+                InferenceVariable alpha = (InferenceVariable)a.getS();
+                ResolvedType U = a.getT();
+                ResolvedType S = b.getS();
+                ResolvedType T = b.getT();
+                Substitution sub = Substitution.empty().withPair(alpha.getTypeParameterDeclaration(), U);
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(sub.apply(S), sub.apply(T)));
+            }
+            if (isInferenceVariable(a.getT()) && isProperType(a.getS())) {
+                InferenceVariable alpha = (InferenceVariable)a.getT();
+                ResolvedType U = a.getS();
+                ResolvedType S = b.getS();
+                ResolvedType T = b.getT();
+                Substitution sub = Substitution.empty().withPair(alpha.getTypeParameterDeclaration(), U);
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(sub.apply(S), sub.apply(T)));
+            }
+            if (isInferenceVariable(b.getS()) && isProperType(b.getT())) {
+                InferenceVariable alpha = (InferenceVariable)b.getS();
+                ResolvedType U = b.getT();
+                ResolvedType S = a.getS();
+                ResolvedType T = a.getT();
+                Substitution sub = Substitution.empty().withPair(alpha.getTypeParameterDeclaration(), U);
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(sub.apply(S), sub.apply(T)));
+            }
+            if (isInferenceVariable(b.getT()) && isProperType(b.getS())) {
+                InferenceVariable alpha = (InferenceVariable)b.getT();
+                ResolvedType U = b.getS();
+                ResolvedType S = a.getS();
+                ResolvedType T = a.getT();
+                Substitution sub = Substitution.empty().withPair(alpha.getTypeParameterDeclaration(), U);
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(sub.apply(S), sub.apply(T)));
+            }
+            return currentConstraintSet;
+        }, newConstraintsSet);
+
+        // - α = U and S <: T imply ‹S[α:=U] <: T[α:=U]›
+
+        newConstraintsSet = forEachPairSameAndSubtype((a, b, currentConstraintSet) -> {
+            if (isInferenceVariable(a.getS()) && isProperType(a.getT())) {
+                InferenceVariable alpha = (InferenceVariable)a.getS();
+                ResolvedType U = a.getT();
+                ResolvedType S = b.getS();
+                ResolvedType T = b.getT();
+                Substitution sub = Substitution.empty().withPair(alpha.getTypeParameterDeclaration(), U);
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSubtypeOfType(typeSolver, sub.apply(S), sub.apply(T)));
+            }
+            if (isInferenceVariable(a.getT()) && isProperType(a.getS())) {
+                InferenceVariable alpha = (InferenceVariable)a.getT();
+                ResolvedType U = a.getS();
+                ResolvedType S = b.getS();
+                ResolvedType T = b.getT();
+                Substitution sub = Substitution.empty().withPair(alpha.getTypeParameterDeclaration(), U);
+                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSubtypeOfType(typeSolver, sub.apply(S), sub.apply(T)));
+            }
+            return currentConstraintSet;
+        }, newConstraintsSet);
+
+        // When a bound set contains a pair of bounds α <: S and α <: T, and there exists a supertype of S of the
+        // form G<S1, ..., Sn> and a supertype of T of the form G<T1, ..., Tn> (for some generic class or interface, G),
+        // then for all i (1 ≤ i ≤ n), if Si and Ti are types (not wildcards), the constraint formula ‹Si = Ti› is
+        // implied.
+
+        newConstraintsSet = forEachPairSubtypeAndSubtype((a, b, currentConstraintSet) -> {
+            if (isInferenceVariable(a.getS()) && isInferenceVariable(b.getS())) {
+                if (a.getT().isReferenceType() && b.getT().isReferenceType()) {
+                    ResolvedReferenceType S = a.getT().asReferenceType();
+                    ResolvedReferenceType T = b.getT().asReferenceType();
+                    List<Pair<ResolvedReferenceType, ResolvedReferenceType>> pairs = findPairsOfCommonAncestors(S, T);
+                    for (Pair<ResolvedReferenceType, ResolvedReferenceType> pair : pairs) {
+                        for (int i=0;i<Math.min(pair.a.typeParametersValues().size(), pair.b.typeParametersValues().size()); i++) {
+                            ResolvedType si = pair.a.typeParametersValues().get(i);
+                            ResolvedType ti = pair.b.typeParametersValues().get(i);
+                            if (!si.isWildcard() && !ti.isWildcard()) {
+                                currentConstraintSet = currentConstraintSet.withConstraint(new TypeSameAsType(si, ti));
+                            }
+                        }
+                    }
+                }
+            }
+            return currentConstraintSet;
+        }, newConstraintsSet);
+
+        // SECTION Bounds Involving Capture Conversion
+        //
+        // When a bound set contains a bound of the form G<α1, ..., αn> = capture(G<A1, ..., An>), new bounds are
+        // implied and new constraint formulas may be implied, as follows.
+
+        for (Bound b : this.bounds.stream().filter(b -> b instanceof CapturesBound).collect(Collectors.toList())) {
+            CapturesBound capturesBound = (CapturesBound)b;
+
+            throw new UnsupportedOperationException();
+
+            // Let P1, ..., Pn represent the type parameters of G and let B1, ..., Bn represent the bounds of these type
+            // parameters. Let θ represent the substitution [P1:=α1, ..., Pn:=αn]. Let R be a type that is not an inference
+            // variable (but is not necessarily a proper type).
+            //
+            // A set of bounds on α1, ..., αn is implied, constructed from the declared bounds of P1, ..., Pn as specified
+            // in §18.1.3.
+            //
+            // In addition, for all i (1 ≤ i ≤ n):
+            //
+            // - If Ai is not a wildcard, then the bound αi = Ai is implied.
+            //
+            // - If Ai is a wildcard of the form ?:
+            //
+            //   - αi = R implies the bound false
+            //
+            //   - αi <: R implies the constraint formula ‹Bi θ <: R›
+            //
+            //   - R <: αi implies the bound false
+            //
+            // - If Ai is a wildcard of the form ? extends T:
+            //
+            //   - αi = R implies the bound false
+            //
+            //   - If Bi is Object, then αi <: R implies the constraint formula ‹T <: R›
+            //
+            //   - If T is Object, then αi <: R implies the constraint formula ‹Bi θ <: R›
+            //
+            //   - R <: αi implies the bound false
+            //
+            // - If Ai is a wildcard of the form ? super T:
+            //
+            //   - αi = R implies the bound false
+            //
+            //   - αi <: R implies the constraint formula ‹Bi θ <: R›
+            //
+            //   - R <: αi implies the constraint formula ‹R <: T›
+        }
+
+        if (newConstraintsSet.isEmpty()) {
+            return this;
+        } else {
+            BoundSet newBounds = newConstraintsSet.reduce(typeSolver);
+            if (newBounds.isEmpty()) {
+                return this;
+            }
+            return this.incorporate(newBounds, typeSolver);
+        }
+    }
+
+    public boolean containsFalse() {
+        return bounds.stream().anyMatch(it -> it instanceof FalseBound);
+    }
+
+    private class VariableDependency {
+        private InferenceVariable depending;
+        private InferenceVariable dependedOn;
+
+        public VariableDependency(InferenceVariable depending, InferenceVariable dependedOn) {
+            this.depending = depending;
+            this.dependedOn = dependedOn;
+        }
+
+        public InferenceVariable getDepending() {
+            return depending;
+        }
+
+        public InferenceVariable getDependedOn() {
+            return dependedOn;
+        }
+
+        public boolean isReflexive() {
+            return dependedOn.equals(depending);
+        }
+    }
+
+    private Set<InferenceVariable> allInferenceVariables() {
+        Set<InferenceVariable> variables = new HashSet<>();
+        for (Bound b : bounds) {
+            variables.addAll(b.usedInferenceVariables());
+        }
+        return variables;
+    }
+
+    private boolean hasInstantiationFor(InferenceVariable v) {
+        for (Bound b : bounds) {
+            if (b.isAnInstantiationFor(v)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Instantiation getInstantiationFor(InferenceVariable v) {
+        for (Bound b : bounds) {
+            if (b.isAnInstantiationFor(v)) {
+                return b.isAnInstantiation().get();
+            }
+        }
+        throw new IllegalArgumentException();
+    }
+
+    private boolean thereIsSomeJSuchThatβequalAlphaJ(Set<InferenceVariable> alphas, InferenceVariable beta) {
+        for (InferenceVariable alphaJ : alphas) {
+            for (Bound b : bounds) {
+                if (b instanceof SameAsBound) {
+                    SameAsBound sameAsBound = (SameAsBound)b;
+                    if (sameAsBound.getS().equals(alphaJ) && sameAsBound.getT().equals(beta)) {
+                        return true;
+                    }
+                    if (sameAsBound.getT().equals(alphaJ) && sameAsBound.getS().equals(beta)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private <T> List<Set<T>> buildAllSubsetsOfSize(Set<T> allElements, int desiredSize) {
+        if (desiredSize == allElements.size()) {
+            return Arrays.asList(allElements);
+        } else {
+            List<Set<T>> res = new LinkedList<>();
+            for (T element : allElements) {
+                Set<T> subset = allButOne(allElements, element);
+                res.addAll(buildAllSubsetsOfSize(subset, desiredSize));
+            }
+            return res;
+        }
+    }
+
+    private <T> Set<T> allButOne(Set<T> elements, T element) {
+        Set<T> set = new HashSet<T>(elements);
+        set.remove(element);
+        return set;
+    }
+
+    /**
+     * there exists no non-empty proper subset of { α1, ..., αn } with this property.
+     */
+    private Optional<Set<InferenceVariable>> smallestSetWithProperty(Set<InferenceVariable> uninstantiatedVariables,
+                                                                     List<VariableDependency> dependencies) {
+        for (int i=1;i<=uninstantiatedVariables.size();i++) {
+            for (Set<InferenceVariable> aSubSet : buildAllSubsetsOfSize(uninstantiatedVariables, i)){
+                if (hasProperty(aSubSet, dependencies)) {
+                    return Optional.of(aSubSet);
+                }
+            }
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * if αi depends on the resolution of a variable β, then either β has an instantiation
+     * or there is some j such that β = αj
+     * @return
+     */
+    private boolean hasProperty(Set<InferenceVariable> alphas, List<VariableDependency> dependencies) {
+        for (InferenceVariable alphaI: alphas) {
+            for (InferenceVariable beta: dependencies.stream()
+                    .filter(d -> d.depending.equals(alphaI))
+                    .filter(d -> !d.isReflexive())
+                    .map(d -> d.dependedOn)
+                    .collect(Collectors.toList())) {
+                if (!hasInstantiationFor(beta) && !thereIsSomeJSuchThatβequalAlphaJ(alphas, beta)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Examines the bounds on an inference variable and determines an instantiation that is compatible with those
+     * bounds. It also decides the order in which interdependent inference variables are to be resolved.
+     */
+    public Optional<InstantiationSet> performResolution(List<InferenceVariable> variablesToResolve, TypeSolver typeSolver) {
+
+        if (this.containsFalse()) {
+            return Optional.empty();
+        }
+
+        List<VariableDependency> dependencies = new LinkedList<>();
+
+        // Given a bound set that does not contain the bound false, a subset of the inference variables mentioned by
+        // the bound set may be resolved. This means that a satisfactory instantiation may be added to the set for each
+        // inference variable, until all the requested variables have instantiations.
+        //
+        // Dependencies in the bound set may require that the variables be resolved in a particular order, or that
+        // additional variables be resolved. Dependencies are specified as follows:
+        //
+        // - Given a bound of one of the following forms, where T is either an inference variable β or a type that
+        // mentions β:
+        //
+        //   - α = T
+        //
+        //   - α <: T
+        //
+        //   - T = α
+        //
+        //   - T <: α
+        //
+        //   If α appears on the left-hand side of another bound of the form G<..., α, ...> = capture(G<...>), then β
+        //   depends on the resolution of α. Otherwise, α depends on the resolution of β.
+
+        for (Bound b : bounds) {
+            if (b instanceof CapturesBound) {
+                throw new UnsupportedOperationException();
+            }
+        }
+
+        // - An inference variable α appearing on the left-hand side of a bound of the form
+        //   G<..., α, ...> = capture(G<...>) depends on the resolution of every other inference variable mentioned in
+        //   this bound (on both sides of the = sign).
+
+        for (Bound b : bounds) {
+            if (b instanceof CapturesBound) {
+                throw new UnsupportedOperationException();
+            }
+        }
+
+        // - An inference variable α depends on the resolution of an inference variable β if there exists an inference
+        //   variable γ such that α depends on the resolution of γ and γ depends on the resolution of β.
+
+        for (int i=0;i<dependencies.size();i++) {
+            VariableDependency di = dependencies.get(i);
+            for (int j=i+1;j<dependencies.size();j++) {
+                VariableDependency dj = dependencies.get(j);
+                if (di.dependedOn.equals(dj.depending)) {
+                    dependencies.add(new VariableDependency(di.getDepending(), dj.getDependedOn()));
+                }
+            }
+        }
+
+        // - An inference variable α depends on the resolution of itself.
+
+        for (InferenceVariable v : allInferenceVariables()) {
+            dependencies.add(new VariableDependency(v, v));
+        }
+
+        // Given a set of inference variables to resolve, let V be the union of this set and all variables upon which
+        // the resolution of at least one variable in this set depends.
+
+        Set<InferenceVariable> V = new HashSet<>();
+        V.addAll(variablesToResolve);
+        for (VariableDependency dependency : dependencies) {
+            if (variablesToResolve.contains(dependency.depending)) {
+                V.add(dependency.dependedOn);
+            }
+        }
+
+        // If every variable in V has an instantiation, then resolution succeeds and this procedure terminates.
+
+        boolean ok = true;
+        for (InferenceVariable v : V) {
+            if (!hasInstantiationFor(v)) {
+                ok = false;
+            }
+        }
+        if (ok) {
+            InstantiationSet instantiationSet = InstantiationSet.empty();
+            for (InferenceVariable v : V) {
+                instantiationSet = instantiationSet.withInstantiation(getInstantiationFor(v));
+            }
+            return Optional.of(instantiationSet);
+        }
+
+        // Otherwise, let { α1, ..., αn } be a non-empty subset of uninstantiated variables in V such that i)
+        // for all i (1 ≤ i ≤ n), if αi depends on the resolution of a variable β, then either β has an instantiation
+        // or there is some j such that β = αj; and ii) there exists no non-empty proper subset of { α1, ..., αn }
+        // with this property.
+
+        Set<InferenceVariable> uninstantiatedPortionOfV = new HashSet<>();
+        for (InferenceVariable v : V) {
+            if (!hasInstantiationFor(v)) {
+                uninstantiatedPortionOfV.add(v);
+            }
+        }
+        for (Set<InferenceVariable> alphas: allSetsWithProperty(uninstantiatedPortionOfV, dependencies)) {
+
+            // Resolution proceeds by generating an instantiation for each of α1, ..., αn based on the
+            // bounds in the bound set:
+
+            boolean hasSomeCaptureForAlphas = alphas.stream().anyMatch(
+                    alphaI -> appearInLeftPartOfCapture(alphaI)
+            );
+
+            // - If the bound set does not contain a bound of the form G<..., αi, ...> = capture(G<...>)
+            //   for all i (1 ≤ i ≤ n), then a candidate instantiation Ti is defined for each αi:
+
+            if (!hasSomeCaptureForAlphas) {
+                BoundSet newBounds = BoundSet.empty();
+                for (InferenceVariable alphaI : alphas) {
+                    Set<ResolvedType> properLowerBounds = bounds.stream()
+                            .filter(b -> b.isProperLowerBoundFor(alphaI).isPresent())
+                            .map(b -> b.isProperLowerBoundFor(alphaI).get().getProperType())
+                            .collect(Collectors.toSet());
+
+                    ResolvedType Ti = null;
+
+                    //   - If αi has one or more proper lower bounds, L1, ..., Lk, then Ti = lub(L1, ..., Lk) (§4.10.4).
+
+                    if (properLowerBounds.size() > 0) {
+                        Ti = leastUpperBound(properLowerBounds);
+                    }
+
+                    //   - Otherwise, if the bound set contains throws αi, and the proper upper bounds of αi are, at most,
+                    //     Exception, Throwable, and Object, then Ti = RuntimeException.
+
+                    boolean throwsBound = bounds.stream().anyMatch(b -> b.isThrowsBoundOn(alphaI));
+                    if (Ti == null && throwsBound && properUpperBoundsAreAtMostExceptionThrowableAndObject(alphaI)) {
+                        Ti = new ReferenceTypeImpl(typeSolver.solveType(RuntimeException.class.getCanonicalName()), typeSolver);
+                    }
+
+                    //   - Otherwise, where αi has proper upper bounds U1, ..., Uk, Ti = glb(U1, ..., Uk) (§5.1.10).
+
+                    if (Ti == null) {
+                        Set<ResolvedType> properUpperBounds = bounds.stream()
+                                .filter(b -> b.isProperUpperBoundFor(alphaI).isPresent())
+                                .map(b -> b.isProperUpperBoundFor(alphaI).get().getProperType())
+                                .collect(Collectors.toSet());
+                        if (properUpperBounds.size() == 0) {
+                            throw new IllegalStateException();
+                        }
+                        Ti = glb(properUpperBounds);
+                    }
+
+                    newBounds = newBounds.withBound(new SameAsBound(alphaI, Ti));
+                }
+
+                //   The bounds α1 = T1, ..., αn = Tn are incorporated with the current bound set.
+
+                BoundSet incorporatedBoundSet = this.incorporate(newBounds, typeSolver);
+
+                //   If the result does not contain the bound false, then the result becomes the new bound set, and resolution
+                //   proceeds by selecting a new set of variables to instantiate (if necessary), as described above.
+
+                if (!incorporatedBoundSet.containsFalse()) {
+                    return incorporatedBoundSet.performResolution(variablesToResolve, typeSolver);
+                }
+
+                //   Otherwise, the result contains the bound false, so a second attempt is made to instantiate { α1, ..., αn }
+                //   by performing the step below.
+
+                throw new UnsupportedOperationException();
+            }
+
+            // - If the bound set contains a bound of the form G<..., αi, ...> = capture(G<...>) for some i (1 ≤ i ≤ n), or;
+
+            else {
+
+                //   If the bound set produced in the step above contains the bound false;
+                //
+                //   then let Y1, ..., Yn be fresh type variables whose bounds are as follows:
+                //
+                //   - For all i (1 ≤ i ≤ n), if αi has one or more proper lower bounds L1, ..., Lk, then let the lower bound
+                //     of Yi be lub(L1, ..., Lk); if not, then Yi has no lower bound.
+                //
+                //   - For all i (1 ≤ i ≤ n), where αi has upper bounds U1, ..., Uk, let the upper bound of Yi be
+                //     glb(U1 θ, ..., Uk θ), where θ is the substitution [α1:=Y1, ..., αn:=Yn].
+                //
+                //   If the type variables Y1, ..., Yn do not have well-formed bounds (that is, a lower bound is not a subtype
+                //   of an upper bound, or an intersection type is inconsistent), then resolution fails.
+                //
+                //   Otherwise, for all i (1 ≤ i ≤ n), all bounds of the form G<..., αi, ...> = capture(G<...>) are removed
+                //   from the current bound set, and the bounds α1 = Y1, ..., αn = Yn are incorporated.
+                //
+                //   If the result does not contain the bound false, then the result becomes the new bound set, and resolution
+                //   proceeds by selecting a new set of variables to instantiate (if necessary), as described above.
+                //
+                //   Otherwise, the result contains the bound false, and resolution fails.
+
+                throw new UnsupportedOperationException();
+            }
+        }
+        return Optional.empty();
+    }
+
+    private Set<Set<InferenceVariable>> allPossibleSetsWithProperty(Set<InferenceVariable> allElements, List<VariableDependency> dependencies) {
+        Set<Set<InferenceVariable>> result = new HashSet<>();
+        for (int i=1;i<=allElements.size();i++) {
+            for (Set<InferenceVariable> aSubSet : buildAllSubsetsOfSize(allElements, i)){
+                if (hasProperty(aSubSet, dependencies)) {
+                    result.add(aSubSet);
+                }
+            }
+        }
+        return result;
+    }
+
+    private boolean thereAreProperSubsets(Set<InferenceVariable> aSet, Set<Set<InferenceVariable>> allPossibleSets) {
+        for (Set<InferenceVariable> anotherSet : allPossibleSets) {
+            if (!anotherSet.equals(aSet)) {
+                if (isTheFirstAProperSubsetOfTheSecond(anotherSet, aSet)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isTheFirstAProperSubsetOfTheSecond(Set<InferenceVariable> subset, Set<InferenceVariable> originalSet) {
+        return originalSet.containsAll(subset) && originalSet.size() > subset.size();
+    }
+
+    private Set<Set<InferenceVariable>> allSetsWithProperty(Set<InferenceVariable> allElements, List<VariableDependency> dependencies) {
+        Set<Set<InferenceVariable>> allPossibleSets = allPossibleSetsWithProperty(allElements, dependencies);
+        Set<Set<InferenceVariable>> selected = new HashSet<>();
+        for (Set<InferenceVariable> aSet : allPossibleSets) {
+            if (!thereAreProperSubsets(aSet, allPossibleSets)) {
+                selected.add(aSet);
+            }
+        }
+        return selected;
+    }
+
+    private boolean properUpperBoundsAreAtMostExceptionThrowableAndObject(InferenceVariable inferenceVariable) {
+        throw new UnsupportedOperationException();
+    }
+
+    private boolean appearInLeftPartOfCapture(InferenceVariable inferenceVariable) {
+        for (Bound b : bounds) {
+            if (b instanceof CapturesBound) {
+                CapturesBound capturesBound = (CapturesBound)b;
+                if (capturesBound.getInferenceVariables().contains(inferenceVariable)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public List<Bound> getProperUpperBoundsFor(InferenceVariable inferenceVariable) {
+        return bounds.stream().filter(b -> b.isProperUpperBoundFor(inferenceVariable).isPresent()).collect(Collectors.toList());
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java
new file mode 100644
index 0000000..3efd04f
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormula.java
@@ -0,0 +1,125 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Constraint formulas are assertions of compatibility or subtyping that may involve inference variables.
+ *
+ * @author Federico Tomassetti
+ */
+public abstract class ConstraintFormula {
+
+    public static class ReductionResult {
+        private BoundSet boundSet;
+        private List<ConstraintFormula> constraintFormulas;
+
+        public BoundSet getBoundSet() {
+            return boundSet;
+        }
+
+        public List<ConstraintFormula> getConstraintFormulas() {
+            return constraintFormulas;
+        }
+
+        public static ReductionResult empty() {
+            return new ReductionResult();
+        }
+
+        public ReductionResult withConstraint(ConstraintFormula constraintFormula) {
+            ReductionResult newInstance = new ReductionResult();
+            newInstance.boundSet = this.boundSet;
+            newInstance.constraintFormulas = new LinkedList<>();
+            newInstance.constraintFormulas.addAll(this.constraintFormulas);
+            newInstance.constraintFormulas.add(constraintFormula);
+            return newInstance;
+        }
+
+        public ReductionResult withBound(Bound bound) {
+            ReductionResult newInstance = new ReductionResult();
+            newInstance.boundSet = this.boundSet.withBound(bound);
+            newInstance.constraintFormulas = this.constraintFormulas;
+            return newInstance;
+        }
+
+        private ReductionResult() {
+            this.boundSet = BoundSet.empty();
+            this.constraintFormulas = new LinkedList<>();
+        }
+
+        public static ReductionResult trueResult() {
+            return empty();
+        }
+
+        public static ReductionResult falseResult() {
+            return empty().withBound(Bound.falseBound());
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            ReductionResult that = (ReductionResult) o;
+
+            if (!boundSet.equals(that.boundSet)) return false;
+            return constraintFormulas.equals(that.constraintFormulas);
+        }
+
+        @Override
+        public int hashCode() {
+            int result = boundSet.hashCode();
+            result = 31 * result + constraintFormulas.hashCode();
+            return result;
+        }
+
+        @Override
+        public String toString() {
+            return "ReductionResult{" +
+                    "boundSet=" + boundSet +
+                    ", constraintFormulas=" + constraintFormulas +
+                    '}';
+        }
+
+        public ConstraintFormula getConstraint(int index) {
+            if (constraintFormulas.size() <= index) {
+                throw new IllegalArgumentException("Constraint with index " + index + " is not available as there are " + constraintFormulas.size() + " constraints");
+            }
+            return constraintFormulas.get(index);
+        }
+
+        public static ReductionResult oneConstraint(ConstraintFormula constraintFormula) {
+            return empty().withConstraint(constraintFormula);
+        }
+
+        public static ReductionResult withConstraints(ConstraintFormula... constraints) {
+            return withConstraints(Arrays.asList(constraints));
+        }
+
+        public static ReductionResult oneBound(Bound bound) {
+            return empty().withBound(bound);
+        }
+
+        public static ReductionResult withConstraints(List<ConstraintFormula> constraints) {
+            ReductionResult reductionResult = new ReductionResult();
+            reductionResult.constraintFormulas.addAll(constraints);
+            return reductionResult;
+        }
+
+        public static ReductionResult bounds(BoundSet bounds) {
+            ReductionResult reductionResult = new ReductionResult();
+            reductionResult.boundSet = bounds;
+            return reductionResult;
+        }
+    }
+
+    /**
+     * A formula is reduced to one or both of:
+     * i) A bound or bound set, which is to be incorporated with the "current" bound set. Initially, the current bound
+     *    set is empty.
+     * ii) Further constraint formulas, which are to be reduced recursively.
+     */
+    public abstract ReductionResult reduce(BoundSet currentBoundSet);
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java
new file mode 100644
index 0000000..bca6e12
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ConstraintFormulaSet.java
@@ -0,0 +1,53 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ConstraintFormulaSet {
+    private List<ConstraintFormula> constraintFormulas;
+
+    public ConstraintFormulaSet withConstraint(ConstraintFormula constraintFormula) {
+        ConstraintFormulaSet newInstance = new ConstraintFormulaSet();
+        newInstance.constraintFormulas.addAll(this.constraintFormulas);
+        newInstance.constraintFormulas.add(constraintFormula);
+        return newInstance;
+    }
+
+    private static final ConstraintFormulaSet EMPTY = new ConstraintFormulaSet();
+
+    public static ConstraintFormulaSet empty() {
+        return EMPTY;
+    }
+
+    private ConstraintFormulaSet() {
+        constraintFormulas = new LinkedList<>();
+    }
+
+    /**
+     * Takes a compatibility assertion about an expression or type, called a constraint formula, and reduces it to a
+     * set of bounds on inference variables. Often, a constraint formula reduces to other constraint formulas,
+     * which must be recursively reduced. A procedure is followed to identify these additional constraint formulas and,
+     * ultimately, to express via a bound set the conditions under which the choices for inferred types would render
+     * each constraint formula true.
+     */
+    public BoundSet reduce(TypeSolver typeSolver) {
+        List<ConstraintFormula> constraints = new LinkedList<>(constraintFormulas);
+        BoundSet boundSet = BoundSet.empty();
+        while (constraints.size() > 0) {
+            ConstraintFormula constraintFormula = constraints.remove(0);
+            ConstraintFormula.ReductionResult reductionResult = constraintFormula.reduce(boundSet);
+            constraints.addAll(reductionResult.getConstraintFormulas());
+            boundSet.incorporate(reductionResult.getBoundSet(), typeSolver);
+        }
+        return boundSet;
+    }
+
+    public boolean isEmpty() {
+        return constraintFormulas.isEmpty();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java
new file mode 100644
index 0000000..56b42e5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ControlFlowLogic.java
@@ -0,0 +1,290 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.GenericVisitorAdapter;
+
+import java.util.List;
+
+/**
+ * Consider Control Flow to determine which statements are reachable.
+ *
+ * Except for the special treatment of while, do, and for statements whose condition expression has the constant value
+ * true, the values of expressions are not taken into account in the flow analysis.
+ *
+ * See JLS 14.21
+ *
+ * @author Federico Tomassetti
+ */
+public class ControlFlowLogic {
+
+    private static ControlFlowLogic instance = new ControlFlowLogic();
+
+    public static ControlFlowLogic getInstance() {
+        return instance;
+    }
+
+    private ControlFlowLogic() {
+
+    }
+
+    /**
+     * A break statement with no label attempts to transfer control to the innermost enclosing switch, while, do, or
+     * for statement of the immediately enclosing method or initializer; this statement, which is called the break
+     * target, then immediately completes normally.
+     *
+     *
+     * A break statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.7)
+     * that has the same Identifier as its label; this statement, which is called the break target, then immediately
+     * completes normally. In this case, the break target need not be a switch, while, do, or for statement.
+     */
+    public Statement breakTarget(BreakStmt breakStmt) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * A reachable break statement exits a statement if, within the break target, either there are no try statements
+     * whose try blocks contain the break statement, or there are try statements whose try blocks contain the break
+     * statement and all finally clauses of those try statements can complete normally.
+     */
+    public boolean exitTheStatement(BreakStmt breakStmt) {
+        if (!isReachable(breakStmt)) {
+            return false;
+        }
+        Statement breakTarget = breakTarget(breakStmt);
+        for (TryStmt tryStmt : containedTryStmts(breakTarget)) {
+            if (contains(tryStmt.getTryBlock(), breakStmt)) {
+                if (!tryStmt.getFinallyBlock().isPresent() && !canCompleteNormally(tryStmt.getFinallyBlock().get())) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public boolean continueADoStatement(ContinueStmt continueStmt, DoStmt doStmt) {
+        for (TryStmt tryStmt : containedTryStmts(continueStmt)) {
+            if (contains(tryStmt.getTryBlock(), continueStmt)) {
+                if (!tryStmt.getFinallyBlock().isPresent() && !canCompleteNormally(tryStmt.getFinallyBlock().get())) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    private boolean contains(Statement container, Statement contained) {
+        throw new UnsupportedOperationException();
+    }
+
+    private List<TryStmt> containedTryStmts(Statement statement) {
+        throw new UnsupportedOperationException();
+    }
+
+    private <P extends Node> boolean parentIs(Node node, Class<P> parentClass) {
+        if (node.getParentNode().isPresent()) {
+            return parentClass.isInstance(node.getParentNode().get());
+        } else {
+            return false;
+        }
+    }
+
+    // See JLS 14.21
+    public boolean canCompleteNormally(Statement statement) {
+        if (!isReachable(statement)) {
+            return false;
+        }
+        GenericVisitor<Boolean, Void> visitor = new GenericVisitorAdapter<Boolean, Void>(){
+            @Override
+            public Boolean visit(BlockStmt n, Void arg) {
+                // An empty block that is not a switch block can complete normally iff it is reachable
+                if (n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
+                    return isReachable(statement);
+                }
+                // A non-empty block that is not a switch block can complete normally iff the last statement in
+                // it can complete normally.
+                if (!n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
+                    return canCompleteNormally(n.getStatement(n.getStatements().size() - 1));
+                }
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public Boolean visit(LabeledStmt n, Void arg) {
+                // A labeled statement can complete normally if at least one of the following is true:
+                // – The contained statement can complete normally.
+                // – There is a reachable break statement that exits the labeled statement.
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public Boolean visit(EmptyStmt n, Void arg) {
+                // An empty statement can complete normally iff it is reachable.
+                return isReachable(n);
+            }
+
+            @Override
+            public Boolean visit(LocalClassDeclarationStmt n, Void arg) {
+                // A local class declaration statement can complete normally iff it is reachable.
+                return isReachable(n);
+            }
+
+            @Override
+            public Boolean visit(IfStmt n, Void arg) {
+                if (n.getElseStmt().isPresent()) {
+                    // An if-then-else statement can complete normally iff the then-statement can
+                    // complete normally or the else-statement can complete normally.
+                    return canCompleteNormally(n.getThenStmt()) || canCompleteNormally(n.getElseStmt().get());
+                } else {
+                    // An if-then statement can complete normally iff it is reachable.
+                    return isReachable(n);
+                }
+            }
+
+            @Override
+            public Boolean visit(AssertStmt n, Void arg) {
+                // An assert statement can complete normally iff it is reachable.
+                return isReachable(n);
+            }
+
+            @Override
+            public Boolean visit(ExpressionStmt n, Void arg) {
+                // A local variable declaration statement can complete normally iff it is reachable.
+                if (n.getExpression() instanceof VariableDeclarationExpr) {
+                    VariableDeclarationExpr expr = (VariableDeclarationExpr) n.getExpression();
+                    return isReachable(n);
+                }
+                // An expression statement can complete normally iff it is reachable.
+                return isReachable(n);
+            }
+        };
+        return statement.accept(visitor, null);
+    }
+
+    private boolean isReachableBecauseOfPosition(Statement statement) {
+        // The first statement in a non-empty block that is not a switch block is reachable iff the block is reachable.
+
+        // Every other statement S in a non-empty block that is not a switch block is reachable iff the statement
+        // preceding S can complete normally.
+
+        // The contained statement of a Labelled Statement is reachable iff the labeled statement is reachable.
+
+        // The then-statement of an if-then statement is reachable iff the if-then statement is reachable.
+
+        // The then-statement of an if-then-else  statement is reachable iff the if-then-else statement is reachable.
+        // The else-statement is reachable iff the if-then-else statement is reachable.
+
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isReachable(Statement statement) {
+
+        GenericVisitor<Boolean, Void> visitor = new GenericVisitorAdapter<Boolean, Void>(){
+            @Override
+            public Boolean visit(BlockStmt n, Void arg) {
+                // The block that is the body of a constructor, method, instance initializer, or static initializer is
+                // reachable
+                if (statement.getParentNode().isPresent()) {
+                    if (statement.getParentNode().get() instanceof ConstructorDeclaration) {
+                        return true;
+                    }
+                    if (statement.getParentNode().get() instanceof MethodDeclaration) {
+                        return true;
+                    }
+                    if (statement.getParentNode().get() instanceof InitializerDeclaration) {
+                        return true;
+                    }
+                }
+                return isReachableBecauseOfPosition(statement);
+            }
+
+            @Override
+            public Boolean visit(LocalClassDeclarationStmt n, Void arg) {
+                return super.visit(n, arg);
+            }
+        };
+        return statement.accept(visitor, null);
+
+        //
+        //
+        //
+        //        A switch statement can complete normally iff at least one of the following is
+        //true:
+        //– The switch block is empty or contains only switch labels.
+        //– The last statement in the switch block can complete normally.
+        //– There is at least one switch label after the last switch block statement group. – The switch block does not contain a default label.
+        //– There is a reachable break statement that exits the switch statement.
+        //        BLOCKS AND STATEMENTS Unreachable Statements 14.21
+        //
+        //A switch block is reachable iff its switch statement is reachable.
+        //
+        //        A statement in a switch block is reachable iff its switch statement is reachable
+        //and at least one of the following is true:
+        //– It bears a case or default label.
+        //– There is a statement preceding it in the switch block and that preceding statement can complete normally.
+        //
+        //A while statement can complete normally iff at least one of the following is true:
+        //– Thewhilestatementisreachableandtheconditionexpressionisnotaconstant
+        //expression (§15.28) with value true.
+        //– There is a reachable break statement that exits the while statement.
+        //        The contained statement is reachable iff the while statement is reachable and the condition expression is not a constant expression whose value is false.
+        //
+        //        A do statement can complete normally iff at least one of the following is true:
+        //– The contained statement can complete normally and the condition expression
+        //is not a constant expression (§15.28) with value true.
+        //– The do statement contains a reachable continue statement with no label, and the do statement is the innermost while, do, or for statement that contains that continue statement, and the continue statement continues that do statement, and the condition expression is not a constant expression with value true.
+        //– The do statement contains a reachable continue statement with a label L, and the do statement has label L, and the continue statement continues that do statement, and the condition expression is not a constant expression with value true.
+        //– There is a reachable break statement that exits the do statement.
+        //        The contained statement is reachable iff the do statement is reachable.
+        //
+        //        A basic for statement can complete normally iff at least one of the following
+        //is true:
+        //– The for statement is reachable, there is a condition expression, and the
+        //condition expression is not a constant expression (§15.28) with value true.
+        //– There is a reachable break statement that exits the for statement.
+        //        The contained statement is reachable iff the for statement is reachable and the condition expression is not a constant expression whose value is false.
+        //
+        //• An enhanced for statement can complete normally iff it is reachable.
+        //
+        //• A break, continue, return, or throw statement cannot complete normally.
+        //
+        //• A synchronized statement can complete normally iff the contained statement can complete normally.
+        //        The contained statement is reachable iff the synchronized statement is reachable.
+        //
+        //• A try statement can complete normally iff both of the following are true:
+        //– The try block can complete normally or any catch block can complete
+        //normally.
+        //– Ifthetrystatementhasafinallyblock,thenthefinallyblockcancomplete normally.
+        //
+        //• The try block is reachable iff the try statement is reachable.
+        //
+        //• A catch block C is reachable iff both of the following are true:
+        //– Either the type of C's parameter is an unchecked exception type or Exception or a superclass of Exception, or some expression or throw statement in the try block is reachable and can throw a checked exception whose type is assignable to the type of C's parameter. (An expression is reachable iff the innermost statement containing it is reachable.)
+        //See §15.6 for normal and abrupt completion of expressions.
+        //– There is no earlier catch block A in the try statement such that the type of C's
+        //parameter is the same as or a subclass of the type of A's parameter.
+        //• The Block of a catch block is reachable iff the catch block is reachable.
+        //• If a finally block is present, it is reachable iff the try statement is reachable.
+        //        One might expect the if statement to be handled in the following manner:
+        //• An if-then statement can complete normally iff at least one of the following is true:
+        //– The if-then statement is reachable and the condition expression is not a constant expression whose value is true.
+        //– The then-statement can complete normally.
+        //        The then-statement is reachable iff the if-then statement is reachable and the
+        //condition expression is not a constant expression whose value is false.
+        //• An if-then-else statement can complete normally iff the then-statement can complete normally or the else-statement can complete normally.
+        //        BLOCKS AND STATEMENTS Unreachable Statements 14.21
+        //The then-statement is reachable iff the if-then-else statement is reachable and the condition expression is not a constant expression whose value is false.
+        //        The else-statement is reachable iff the if-then-else statement is reachable and the condition expression is not a constant expression whose value is true.
+        //        This approach would be consistent with the treatment of other control structures. However, in order to allow the if statement to be used conveniently for "conditional compilation" purposes, the actual rules differ.
+
+        // FIXME
+        //throw new UnsupportedOperationException();
+    }
+
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java
new file mode 100644
index 0000000..8562ece
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ExpressionHelper.java
@@ -0,0 +1,137 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ExpressionHelper {
+
+    /**
+     * See https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.2
+     * @return
+     */
+    public static boolean isStandaloneExpression(Expression expression) {
+        return !isPolyExpression(expression);
+    }
+
+    /**
+     * See https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.2
+     * @return
+     */
+    public static boolean isPolyExpression(Expression expression) {
+        if (expression instanceof EnclosedExpr) {
+            throw new UnsupportedOperationException(expression.toString());
+        }
+        if (expression instanceof ObjectCreationExpr) {
+            // A class instance creation expression is a poly expression (§15.2) if it uses the diamond form for type
+            // arguments to the class, and it appears in an assignment context or an invocation context (§5.2, §5.3).
+            // Otherwise, it is a standalone expression.
+            ObjectCreationExpr objectCreationExpr = (ObjectCreationExpr)expression;
+            if (objectCreationExpr.isUsingDiamondOperator()) {
+                throw new UnsupportedOperationException(expression.toString());
+            } else {
+                return false;
+            }
+        }
+        if (expression instanceof MethodCallExpr) {
+            MethodCallExpr methodCallExpr = (MethodCallExpr)expression;
+
+            // A method invocation expression is a poly expression if all of the following are true:
+            //
+            // 1. The invocation appears in an assignment context or an invocation context (§5.2, §5.3).
+
+            if (!appearsInAssignmentContext(expression) || appearsInInvocationContext(expression)) {
+                return false;
+            }
+
+            // 2. If the invocation is qualified (that is, any form of MethodInvocation except for the first), then
+            //    the invocation elides TypeArguments to the left of the Identifier.
+
+            if (isQualified(methodCallExpr) && !elidesTypeArguments(methodCallExpr)) {
+                return false;
+            }
+
+            // 3. The method to be invoked, as determined by the following subsections, is generic (§8.4.4) and has a
+            //    return type that mentions at least one of the method's type parameters.
+
+            //boolean condition3 =;
+            throw new UnsupportedOperationException(expression.toString());
+
+            // Otherwise, the method invocation expression is a standalone expression.
+            //return true;
+        }
+        if (expression instanceof MethodReferenceExpr) {
+            throw new UnsupportedOperationException(expression.toString());
+        }
+        if (expression instanceof ConditionalExpr) {
+            throw new UnsupportedOperationException(expression.toString());
+        }
+        if (expression instanceof LambdaExpr) {
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean elidesTypeArguments(MethodCallExpr methodCall) {
+        throw new UnsupportedOperationException();
+    }
+
+    private static boolean isQualified(MethodCallExpr methodCall) {
+        throw new UnsupportedOperationException();
+    }
+
+    // Not sure if should look if the parent is an assignment context
+    private static boolean appearsInAssignmentContext(Expression expression) {
+        if (expression.getParentNode().isPresent()) {
+            Node parent = expression.getParentNode().get();
+            if (parent instanceof ExpressionStmt) {
+                return false;
+            }
+            if (parent instanceof MethodCallExpr) {
+                return false;
+            }
+            if (parent instanceof ReturnStmt) {
+                return false;
+            }
+            throw new UnsupportedOperationException(parent.getClass().getCanonicalName());
+        }
+        return false;
+    }
+
+    private static boolean appearsInInvocationContext(Expression expression) {
+        if (expression.getParentNode().isPresent()) {
+            Node parent = expression.getParentNode().get();
+            if (parent instanceof ExpressionStmt) {
+                return false;
+            }
+            if (parent instanceof MethodCallExpr) {
+                return true;
+            }
+            throw new UnsupportedOperationException(parent.getClass().getCanonicalName());
+        }
+        return false;
+    }
+
+    public static boolean isExplicitlyTyped(LambdaExpr lambdaExpr) {
+        return lambdaExpr.getParameters().stream().allMatch(p -> !(p.getType() instanceof UnknownType));
+    }
+
+    public static List<Expression> getResultExpressions(BlockStmt blockStmt) {
+        throw new UnsupportedOperationException();
+    }
+
+    public static boolean isCompatibleInAssignmentContext(Expression expression, ResolvedType type, TypeSolver typeSolver) {
+        return type.isAssignableBy(JavaParserFacade.get(typeSolver).getType(expression, false));
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java
new file mode 100644
index 0000000..18b8d74
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariable.java
@@ -0,0 +1,93 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Are meta-variables for types - that is, they are special names that allow abstract reasoning about types.
+ * To distinguish them from type variables, inference variables are represented with Greek letters, principally α.
+ *
+ * See JLS 18
+ *
+ * @author Federico Tomassetti
+ */
+public class InferenceVariable implements ResolvedType {
+    private static int unnamedInstantiated = 0;
+
+    private String name;
+    private ResolvedTypeParameterDeclaration typeParameterDeclaration;
+
+    public static List<InferenceVariable> instantiate(List<ResolvedTypeParameterDeclaration> typeParameterDeclarations) {
+        List<InferenceVariable> inferenceVariables = new LinkedList<>();
+        for (ResolvedTypeParameterDeclaration tp : typeParameterDeclarations) {
+            inferenceVariables.add(InferenceVariable.unnamed(tp));
+        }
+        return inferenceVariables;
+    }
+
+    public static InferenceVariable unnamed(ResolvedTypeParameterDeclaration typeParameterDeclaration) {
+        return new InferenceVariable("__unnamed__" + (unnamedInstantiated++), typeParameterDeclaration);
+    }
+
+    public InferenceVariable(String name, ResolvedTypeParameterDeclaration typeParameterDeclaration) {
+        this.name = name;
+        this.typeParameterDeclaration = typeParameterDeclaration;
+    }
+
+    @Override
+    public String describe() {
+        return name;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        InferenceVariable that = (InferenceVariable) o;
+
+        if (!name.equals(that.name)) return false;
+        return typeParameterDeclaration != null ? typeParameterDeclaration.equals(that.typeParameterDeclaration)
+                : that.typeParameterDeclaration == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = 31 * result + (typeParameterDeclaration != null ? typeParameterDeclaration.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        if (other.equals(this)) {
+            return true;
+        }
+        throw new UnsupportedOperationException(
+                "We are unable to determine the assignability of an inference variable without knowing the bounds and"
+                        + " constraints");
+    }
+
+    public ResolvedTypeParameterDeclaration getTypeParameterDeclaration() {
+        if (typeParameterDeclaration == null) {
+            throw new IllegalStateException("The type parameter declaration was not specified");
+        }
+        return typeParameterDeclaration;
+    }
+
+    @Override
+    public String toString() {
+        return "InferenceVariable{" +
+                "name='" + name + '\'' +
+                ", typeParameterDeclaration=" + typeParameterDeclaration +
+                '}';
+    }
+
+    @Override
+    public boolean mention(List<ResolvedTypeParameterDeclaration> typeParameters) {
+        return false;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java
new file mode 100644
index 0000000..437358b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InferenceVariableSubstitution.java
@@ -0,0 +1,36 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class InferenceVariableSubstitution {
+
+    private final static InferenceVariableSubstitution EMPTY = new InferenceVariableSubstitution();
+
+    private List<InferenceVariable> inferenceVariables;
+    private List<ResolvedType> types;
+
+    public static InferenceVariableSubstitution empty() {
+        return EMPTY;
+    }
+
+    private InferenceVariableSubstitution() {
+        this.inferenceVariables = new LinkedList<>();
+        this.types = new LinkedList<>();
+    }
+
+    public InferenceVariableSubstitution withPair(InferenceVariable inferenceVariable, ResolvedType type) {
+        InferenceVariableSubstitution newInstance = new InferenceVariableSubstitution();
+        newInstance.inferenceVariables.addAll(this.inferenceVariables);
+        newInstance.types.addAll(this.types);
+        newInstance.inferenceVariables.add(inferenceVariable);
+        newInstance.types.add(type);
+        return newInstance;
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java
new file mode 100644
index 0000000..c4b59e5
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Instantiation.java
@@ -0,0 +1,51 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class Instantiation {
+    private InferenceVariable inferenceVariable;
+    private ResolvedType properType;
+
+    public Instantiation(InferenceVariable inferenceVariable, ResolvedType properType) {
+        this.inferenceVariable = inferenceVariable;
+        this.properType = properType;
+    }
+
+    public InferenceVariable getInferenceVariable() {
+        return inferenceVariable;
+    }
+
+    public ResolvedType getProperType() {
+        return properType;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Instantiation that = (Instantiation) o;
+
+        if (!inferenceVariable.equals(that.inferenceVariable)) return false;
+        return properType.equals(that.properType);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = inferenceVariable.hashCode();
+        result = 31 * result + properType.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "Instantiation{" +
+                "inferenceVariable=" + inferenceVariable +
+                ", properType=" + properType +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java
new file mode 100644
index 0000000..e0bfe3e
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/InstantiationSet.java
@@ -0,0 +1,68 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class InstantiationSet {
+
+    private List<Instantiation> instantiations;
+
+    public boolean allInferenceVariablesAreResolved(BoundSet boundSet) {
+        throw new UnsupportedOperationException();
+    }
+
+    public static InstantiationSet empty() {
+        return EMPTY;
+    }
+
+    private static final InstantiationSet EMPTY = new InstantiationSet();
+
+    private InstantiationSet() {
+        instantiations = new LinkedList<>();
+    }
+
+    public InstantiationSet withInstantiation(Instantiation instantiation) {
+        InstantiationSet newInstance = new InstantiationSet();
+        newInstance.instantiations.addAll(this.instantiations);
+        newInstance.instantiations.add(instantiation);
+        return newInstance;
+    }
+
+    public boolean isEmpty() {
+        return instantiations.isEmpty();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        InstantiationSet that = (InstantiationSet) o;
+
+        return instantiations.equals(that.instantiations);
+    }
+
+    @Override
+    public int hashCode() {
+        return instantiations.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "InstantiationSet{" +
+                "instantiations=" + instantiations +
+                '}';
+    }
+
+    public ResolvedType apply(ResolvedType type) {
+        for (Instantiation instantiation : instantiations) {
+            type = type.replaceTypeVariables(instantiation.getInferenceVariable().getTypeParameterDeclaration(), instantiation.getProperType());
+        }
+        return type;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java
new file mode 100644
index 0000000..87494d4
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/MethodType.java
@@ -0,0 +1,55 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.List;
+
+/**
+ * A MethodType is an ordered 4-tuple consisting of:
+ * 1. type parameters: the declarations of any type parameters of the method member.
+ * 2. argument types: a list of the types of the arguments to the method member.
+ * 3. return type: the return type of the method member.
+ * 4. throws clause: exception types declared in the throws clause of the method member.
+ *
+ * See JLS 8.2
+ *
+ * @author Federico Tomassetti
+ */
+public class MethodType {
+    private List<ResolvedTypeParameterDeclaration> typeParameters;
+    private List<ResolvedType> formalArgumentTypes;
+    private ResolvedType returnType;
+    private List<ResolvedType> exceptionTypes;
+
+    public static MethodType fromMethodUsage(MethodUsage methodUsage) {
+        return new MethodType(methodUsage.getDeclaration().getTypeParameters(), methodUsage.getParamTypes(),
+                methodUsage.returnType(), methodUsage.exceptionTypes());
+    }
+
+    public MethodType(List<ResolvedTypeParameterDeclaration> typeParameters, List<ResolvedType> formalArgumentTypes,
+                      ResolvedType returnType,
+                      List<ResolvedType> exceptionTypes) {
+        this.typeParameters = typeParameters;
+        this.formalArgumentTypes = formalArgumentTypes;
+        this.returnType = returnType;
+        this.exceptionTypes = exceptionTypes;
+    }
+
+    public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+        return typeParameters;
+    }
+
+    public List<ResolvedType> getFormalArgumentTypes() {
+        return formalArgumentTypes;
+    }
+
+    public ResolvedType getReturnType() {
+        return returnType;
+    }
+
+    public List<ResolvedType> getExceptionTypes() {
+        return exceptionTypes;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java
new file mode 100644
index 0000000..03568a7
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperLowerBound.java
@@ -0,0 +1,50 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ProperLowerBound {
+    private InferenceVariable inferenceVariable;
+    private ResolvedType properType;
+
+    public ProperLowerBound(InferenceVariable inferenceVariable, ResolvedType properType) {
+        this.inferenceVariable = inferenceVariable;
+        this.properType = properType;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ProperLowerBound that = (ProperLowerBound) o;
+
+        if (!inferenceVariable.equals(that.inferenceVariable)) return false;
+        return properType.equals(that.properType);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = inferenceVariable.hashCode();
+        result = 31 * result + properType.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "ProperLowerBound{" +
+                "inferenceVariable=" + inferenceVariable +
+                ", properType=" + properType +
+                '}';
+    }
+
+    public InferenceVariable getInferenceVariable() {
+        return inferenceVariable;
+    }
+
+    public ResolvedType getProperType() {
+        return properType;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java
new file mode 100644
index 0000000..07d8cdb
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/ProperUpperBound.java
@@ -0,0 +1,50 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ProperUpperBound {
+    private InferenceVariable inferenceVariable;
+    private ResolvedType properType;
+
+    public ProperUpperBound(InferenceVariable inferenceVariable, ResolvedType properType) {
+        this.inferenceVariable = inferenceVariable;
+        this.properType = properType;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ProperUpperBound that = (ProperUpperBound) o;
+
+        if (!inferenceVariable.equals(that.inferenceVariable)) return false;
+        return properType.equals(that.properType);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = inferenceVariable.hashCode();
+        result = 31 * result + properType.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "ProperUpperBound{" +
+                "inferenceVariable=" + inferenceVariable +
+                ", properType=" + properType +
+                '}';
+    }
+
+    public InferenceVariable getInferenceVariable() {
+        return inferenceVariable;
+    }
+
+    public ResolvedType getProperType() {
+        return properType;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java
new file mode 100644
index 0000000..3632542
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/Substitution.java
@@ -0,0 +1,45 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class Substitution {
+
+    private List<ResolvedTypeParameterDeclaration> typeParameterDeclarations;
+    private List<ResolvedType> types;
+
+    private final static Substitution EMPTY = new Substitution();
+
+    public static Substitution empty() {
+        return EMPTY;
+    }
+
+    public Substitution withPair(ResolvedTypeParameterDeclaration typeParameterDeclaration, ResolvedType type) {
+        Substitution newInstance = new Substitution();
+        newInstance.typeParameterDeclarations.addAll(this.typeParameterDeclarations);
+        newInstance.types.addAll(this.types);
+        newInstance.typeParameterDeclarations.add(typeParameterDeclaration);
+        newInstance.types.add(type);
+        return newInstance;
+
+    }
+
+    private Substitution() {
+        this.typeParameterDeclarations = new LinkedList<>();
+        this.types = new LinkedList<>();
+    }
+
+    public ResolvedType apply(ResolvedType originalType) {
+        ResolvedType result = originalType;
+        for (int i=0;i<typeParameterDeclarations.size();i++) {
+            result = result.replaceTypeVariables(typeParameterDeclarations.get(i), types.get(i));
+        }
+        return result;
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java
new file mode 100644
index 0000000..01d041d
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeHelper.java
@@ -0,0 +1,405 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+import com.github.javaparser.utils.Pair;
+
+import java.util.*;
+
+/**
+ * The term "type" is used loosely in this chapter to include type-like syntax that contains inference variables.
+ *
+ * Assertions that involve inference
+ * variables are assertions about every proper type that can be produced by replacing each inference variable with
+ * a proper type.
+ *
+ * @author Federico Tomassetti
+ */
+public class TypeHelper {
+
+    /**
+     * The term proper type excludes such "types" that mention inference variables.
+     */
+    public static boolean isProperType(ResolvedType type) {
+        if (type instanceof InferenceVariable) {
+            return false;
+        }
+        if (type instanceof ResolvedReferenceType) {
+            ResolvedReferenceType referenceType = (ResolvedReferenceType) type;
+            return referenceType.typeParametersValues().stream().allMatch(it -> isProperType(it));
+        }
+        if (type instanceof ResolvedWildcard) {
+            ResolvedWildcard wildcard = (ResolvedWildcard)type;
+            if (wildcard.isBounded()) {
+                return isProperType(wildcard.getBoundedType());
+            } else {
+                return true;
+            }
+        }
+        if (type.isPrimitive()) {
+            return true;
+        }
+        if (type.isTypeVariable()) {
+            // FIXME I am not sure...
+            return false;
+        }
+        if (type.isArray()) {
+            return isProperType(type.asArrayType().getComponentType());
+        }
+        throw new UnsupportedOperationException(type.toString());
+    }
+
+    /**
+     * see https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.3
+     * @param expression
+     * @param t
+     * @return
+     */
+    public static boolean isCompatibleInAStrictInvocationContext(Expression expression, ResolvedType t) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * see https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.3
+     * @param expression
+     * @param t
+     * @return
+     */
+    public static boolean isCompatibleInALooseInvocationContext(TypeSolver typeSolver, Expression expression, ResolvedType t) {
+        //throw new UnsupportedOperationException("Unable to determine if " + expression + " is compatible in a loose invocation context with type " + t);
+        return isCompatibleInALooseInvocationContext(JavaParserFacade.get(typeSolver).getType(expression), t);
+    }
+
+    /**
+     * see https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.3
+     * @param s
+     * @param t
+     * @return
+     */
+    public static boolean isCompatibleInALooseInvocationContext(ResolvedType s, ResolvedType t) {
+        // Loose invocation contexts allow a more permissive set of conversions, because they are only used for a
+        // particular invocation if no applicable declaration can be found using strict invocation contexts. Loose
+        // invocation contexts allow the use of one of the following:
+        //
+        // - an identity conversion (§5.1.1)
+
+        if (s.equals(t)) {
+            return true;
+        }
+
+        // - a widening primitive conversion (§5.1.2)
+
+        if (s.isPrimitive() && t.isPrimitive() && areCompatibleThroughWideningPrimitiveConversion(s, t)) {
+            return true;
+        }
+
+        // - a widening reference conversion (§5.1.5)
+
+        if (s.isReferenceType() && t.isReferenceType() && areCompatibleThroughWideningReferenceConversion(s, t)) {
+            return true;
+        }
+
+        // - a boxing conversion (§5.1.7) optionally followed by widening reference conversion
+
+        if (s.isPrimitive() && t.isReferenceType() &&
+                areCompatibleThroughWideningReferenceConversion(toBoxedType(s.asPrimitive()), t)) {
+            return true;
+        }
+
+        // - an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion
+
+        if (isUnboxable(s) && s.isReferenceType() && t.isPrimitive() &&
+                areCompatibleThroughWideningPrimitiveConversion(toUnboxedType(s.asReferenceType()), t)) {
+            return true;
+        }
+
+        // If, after the conversions listed for an invocation context have been applied, the resulting type is a raw
+        // type (§4.8), an unchecked conversion (§5.1.9) may then be applied.
+        //
+        // A value of the null type (the null reference is the only such value) may be assigned to any reference type
+        if (s.isNull() && t.isReferenceType()) {
+            return true;
+        }
+
+        //throw new UnsupportedOperationException("isCompatibleInALooseInvocationContext unable to decide on s=" + s + ", t=" + t);
+        // TODO FIXME
+        return t.isAssignableBy(s);
+    }
+
+    private static boolean isUnboxable(ResolvedType referenceType) {
+        if (!referenceType.isReferenceType()) {
+            return false;
+        }
+        return Arrays.stream(ResolvedPrimitiveType.values()).anyMatch(pt -> referenceType.asReferenceType().getQualifiedName().equals(pt.getBoxTypeQName()));
+    }
+
+    private static ResolvedType toUnboxedType(ResolvedReferenceType referenceType) {
+        throw new UnsupportedOperationException(referenceType.toString());
+    }
+
+    private static ResolvedType toBoxedType(ResolvedPrimitiveType primitiveType) {
+        throw new UnsupportedOperationException();
+    }
+
+    private static boolean areCompatibleThroughWideningReferenceConversion(ResolvedType s, ResolvedType t) {
+        Optional<ResolvedPrimitiveType> correspondingPrimitiveTypeForS = Arrays.stream(ResolvedPrimitiveType.values()).filter(pt -> pt.getBoxTypeQName().equals(s.asReferenceType().getQualifiedName())).findFirst();
+        if (!correspondingPrimitiveTypeForS.isPresent()) {
+            return false;
+        }
+        throw new UnsupportedOperationException("areCompatibleThroughWideningReferenceConversion s="+s+", t=" + t);
+    }
+
+    private static boolean areCompatibleThroughWideningPrimitiveConversion(ResolvedType s, ResolvedType t) {
+        if (s.isPrimitive() && t.isPrimitive()) {
+            return s.isAssignableBy(t);
+        } else {
+            return false;
+        }
+    }
+
+    public static boolean isInferenceVariable(ResolvedType type) {
+        return type instanceof InferenceVariable;
+    }
+
+    public static Set<InferenceVariable> usedInferenceVariables(ResolvedType type) {
+        if (isInferenceVariable(type)) {
+            return new HashSet<>(Arrays.asList((InferenceVariable)type));
+        }
+        if (type.isReferenceType()) {
+            Set<InferenceVariable> res = new HashSet<>();
+            for (ResolvedType tp : type.asReferenceType().typeParametersValues()) {
+                res.addAll(usedInferenceVariables(tp));
+            }
+            return res;
+        }
+        throw new UnsupportedOperationException(type.toString());
+    }
+
+    /**
+     * See JLS 4.10.4. Least Upper Bound.
+     */
+    public static ResolvedType leastUpperBound(Set<ResolvedType> types) {
+        if (types.size() == 0) {
+            throw new IllegalArgumentException();
+        }
+
+        // The least upper bound, or "lub", of a set of reference types is a shared supertype that is more specific than
+        // any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound).
+        // This type, lub(U1, ..., Uk), is determined as follows.
+        //
+        // If k = 1, then the lub is the type itself: lub(U) = U.
+
+        if (types.size() == 1) {
+            return types.stream().findFirst().get();
+        }
+
+        //
+        //Otherwise:
+        //
+        //For each Ui (1 ≤ i ≤ k):
+        //
+        //Let ST(Ui) be the set of supertypes of Ui.
+        //
+        //Let EST(Ui), the set of erased supertypes of Ui, be:
+        //
+        //EST(Ui) = { |W| | W in ST(Ui) } where |W| is the erasure of W.
+        //
+        //The reason for computing the set of erased supertypes is to deal with situations where the set of types includes several distinct parameterizations of a generic type.
+        //
+        //For example, given List<String> and List<Object>, simply intersecting the sets ST(List<String>) = { List<String>, Collection<String>, Object } and ST(List<Object>) = { List<Object>, Collection<Object>, Object } would yield a set { Object }, and we would have lost track of the fact that the upper bound can safely be assumed to be a List.
+        //
+        //In contrast, intersecting EST(List<String>) = { List, Collection, Object } and EST(List<Object>) = { List, Collection, Object } yields { List, Collection, Object }, which will eventually enable us to produce List<?>.
+        //
+        //Let EC, the erased candidate set for U1 ... Uk, be the intersection of all the sets EST(Ui) (1 ≤ i ≤ k).
+        //
+        //Let MEC, the minimal erased candidate set for U1 ... Uk, be:
+        //
+        //MEC = { V | V in EC, and for all W ≠ V in EC, it is not the case that W <: V }
+        //
+        //Because we are seeking to infer more precise types, we wish to filter out any candidates that are supertypes of other candidates. This is what computing MEC accomplishes. In our running example, we had EC = { List, Collection, Object }, so MEC = { List }. The next step is to recover type arguments for the erased types in MEC.
+        //
+        //For any element G of MEC that is a generic type:
+        //
+        //Let the "relevant" parameterizations of G, Relevant(G), be:
+        //
+        //Relevant(G) = { V | 1 ≤ i ≤ k: V in ST(Ui) and V = G<...> }
+        //
+        //In our running example, the only generic element of MEC is List, and Relevant(List) = { List<String>, List<Object> }. We will now seek to find a type argument for List that contains (§4.5.1) both String and Object.
+        //
+        //This is done by means of the least containing parameterization (lcp) operation defined below. The first line defines lcp() on a set, such as Relevant(List), as an operation on a list of the elements of the set. The next line defines the operation on such lists, as a pairwise reduction on the elements of the list. The third line is the definition of lcp() on pairs of parameterized types, which in turn relies on the notion of least containing type argument (lcta). lcta() is defined for all possible cases.
+        //
+        //Let the "candidate" parameterization of G, Candidate(G), be the most specific parameterization of the generic type G that contains all the relevant parameterizations of G:
+        //
+        //Candidate(G) = lcp(Relevant(G))
+        //
+        //where lcp(), the least containing invocation, is:
+        //
+        //lcp(S) = lcp(e1, ..., en) where ei (1 ≤ i ≤ n) in S
+        //
+        //lcp(e1, ..., en) = lcp(lcp(e1, e2), e3, ..., en)
+        //
+        //lcp(G<X1, ..., Xn>, G<Y1, ..., Yn>) = G<lcta(X1, Y1), ..., lcta(Xn, Yn)>
+        //
+        //lcp(G<X1, ..., Xn>) = G<lcta(X1), ..., lcta(Xn)>
+        //
+        //and where lcta(), the least containing type argument, is: (assuming U and V are types)
+        //
+        //lcta(U, V) = U if U = V, otherwise ? extends lub(U, V)
+        //
+        //lcta(U, ? extends V) = ? extends lub(U, V)
+        //
+        //lcta(U, ? super V) = ? super glb(U, V)
+        //
+        //lcta(? extends U, ? extends V) = ? extends lub(U, V)
+        //
+        //lcta(? extends U, ? super V) = U if U = V, otherwise ?
+        //
+        //lcta(? super U, ? super V) = ? super glb(U, V)
+        //
+        //lcta(U) = ? if U's upper bound is Object, otherwise ? extends lub(U,Object)
+        //
+        //and where glb() is as defined in §5.1.10.
+        //
+        //Let lub(U1 ... Uk) be:
+        //
+        //Best(W1) & ... & Best(Wr)
+        //
+        //where Wi (1 ≤ i ≤ r) are the elements of MEC, the minimal erased candidate set of U1 ... Uk;
+        //
+        //and where, if any of these elements are generic, we use the candidate parameterization (so as to recover type arguments):
+        //
+        //Best(X) = Candidate(X) if X is generic; X otherwise.
+        //
+        //Strictly speaking, this lub() function only approximates a least upper bound. Formally, there may exist some other type T such that all of U1 ... Uk are subtypes of T and T is a subtype of lub(U1, ..., Uk). However, a compiler for the Java programming language must implement lub() as specified above.
+        //
+        //It is possible that the lub() function yields an infinite type. This is permissible, and a compiler for the Java programming language must recognize such situations and represent them appropriately using cyclic data structures.
+        //
+        //The possibility of an infinite type stems from the recursive calls to lub(). Readers familiar with recursive types should note that an infinite type is not the same as a recursive type
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * See JLS 15.27.3. Type of a Lambda Expression
+     * @return
+     */
+    public static Pair<ResolvedType, Boolean> groundTargetTypeOfLambda(LambdaExpr lambdaExpr, ResolvedType T, TypeSolver typeSolver) {
+        // The ground target type is derived from T as follows:
+        //
+        boolean used18_5_3 = false;
+
+        boolean wildcardParameterized = T.asReferenceType().typeParametersValues().stream()
+                .anyMatch(tp -> tp.isWildcard());
+        if (wildcardParameterized) {
+            // - If T is a wildcard-parameterized functional interface type and the lambda expression is explicitly typed,
+            //   then the ground target type is inferred as described in §18.5.3.
+
+            if (ExpressionHelper.isExplicitlyTyped(lambdaExpr)) {
+                used18_5_3 = true;
+                throw new UnsupportedOperationException();
+            }
+
+            // - If T is a wildcard-parameterized functional interface type and the lambda expression is implicitly typed,
+            //   then the ground target type is the non-wildcard parameterization (§9.9) of T.
+
+            else {
+                return new Pair<>(nonWildcardParameterizationOf(T.asReferenceType(), typeSolver), used18_5_3);
+            }
+        }
+
+        // - Otherwise, the ground target type is T.
+        return new Pair<>(T, used18_5_3);
+    }
+
+    /**
+     * See JLS 9.9
+     */
+    private static ResolvedReferenceType nonWildcardParameterizationOf(ResolvedReferenceType originalType, TypeSolver typeSolver) {
+        List<ResolvedType> TIs = new LinkedList<>();
+        List<ResolvedType> AIs = originalType.typeParametersValues();
+        List<ResolvedTypeParameterDeclaration> TPs = originalType.getTypeDeclaration().getTypeParameters();
+
+        // Let P1...Pn be the type parameters of I with corresponding bounds B1...Bn. For all i (1 ≤ i ≤ n),
+        // Ti is derived according to the form of Ai:
+
+        ResolvedReferenceType object = new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+
+        for (int i=0;i<AIs.size();i++) {
+            ResolvedType Ai = AIs.get(i);
+            ResolvedType Ti = null;
+
+            // - If Ai is a type, then Ti = Ai.
+
+            if (!Ai.isWildcard()) {
+                Ti = Ai;
+            }
+
+            // - If Ai is a wildcard, and the corresponding type parameter's bound, Bi, mentions one of P1...Pn, then
+            //   Ti is undefined and there is no function type.
+
+            if (Ti == null && Ai.isWildcard() && Ai.asWildcard().mention(originalType.getTypeDeclaration().getTypeParameters())) {
+                throw new IllegalArgumentException();
+            }
+
+            // - Otherwise:
+
+            if (Ti == null) {
+
+                ResolvedType Bi = TPs.get(i).hasLowerBound() ? TPs.get(i).getLowerBound() : object;
+
+                //   - If Ai is an unbound wildcard ?, then Ti = Bi.
+
+                if (Ai.isWildcard() && !Ai.asWildcard().isBounded()) {
+                    Ti = Bi;
+                }
+
+                //   - If Ai is a upper-bounded wildcard ? extends Ui, then Ti = glb(Ui, Bi) (§5.1.10).
+
+                else if (Ai.isWildcard() && Ai.asWildcard().isUpperBounded()) {
+                    ResolvedType Ui = Ai.asWildcard().getBoundedType();
+                    Ti = glb(new HashSet<>(Arrays.asList(Ui, Bi)));
+                }
+
+                //   - If Ai is a lower-bounded wildcard ? super Li, then Ti = Li.
+
+                else if (Ai.isWildcard() && Ai.asWildcard().isLowerBounded()) {
+                    Ti = Ai.asWildcard().getBoundedType();
+                }
+
+                else throw new RuntimeException("This should not happen");
+            }
+
+            TIs.add(Ti);
+        }
+
+        return new ReferenceTypeImpl(originalType.getTypeDeclaration(), TIs, typeSolver);
+    }
+
+    public static MethodType getFunctionType(ResolvedType type) {
+        Optional<MethodUsage> mu = FunctionalInterfaceLogic.getFunctionalMethod(type);
+        if (mu.isPresent()) {
+            return MethodType.fromMethodUsage(mu.get());
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
+     * See JLS 5.1.10. Capture Conversion.
+     */
+    public static ResolvedType glb(Set<ResolvedType> types) {
+        if (types.size() == 0) {
+            throw new IllegalArgumentException();
+        }
+        if (types.size() == 1) {
+            return types.iterator().next();
+        }
+        return new ResolvedIntersectionType(types);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java
new file mode 100644
index 0000000..b68c157
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInference.java
@@ -0,0 +1,719 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.SubtypeOfBound;
+import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.ThrowsBound;
+import com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas.ExpressionCompatibleWithType;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.ExpressionHelper.isStandaloneExpression;
+
+/**
+ * The API exposed by the TypeInference subsystem.
+ *
+ * @author Federico Tomassetti
+ */
+public class TypeInference {
+
+    private final ResolvedType object;
+    private TypeSolver typeSolver;
+
+    public TypeInference(TypeSolver typeSolver) {
+        if (typeSolver == null) {
+            throw new NullPointerException();
+        }
+        this.typeSolver = typeSolver;
+        this.object = new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);
+    }
+
+    ///
+    /// Public static methods
+    ///
+
+    public static MethodUsage toMethodUsage(MethodCallExpr call, ResolvedMethodDeclaration methodDeclaration, TypeSolver typeSolver) {
+        TypeInference typeInference = new TypeInference(typeSolver);
+        Optional<InstantiationSet> instantiationSetOpt = typeInference.instantiationInference(call, methodDeclaration);
+        if (instantiationSetOpt.isPresent()) {
+            return instantiationSetToMethodUsage(methodDeclaration, instantiationSetOpt.get());
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    ///
+    /// Public instance methods
+    ///
+
+    public Optional<InstantiationSet> instantiationInference(MethodCallExpr methodCallExpr, ResolvedMethodDeclaration methodDeclaration) {
+        return instantiationInference(methodCallExpr.getArguments(), methodDeclaration);
+    }
+
+    public Optional<InstantiationSet> instantiationInference(List<Expression> argumentExpressions, ResolvedMethodDeclaration methodDeclaration) {
+//        if (methodCallExpr.getTypeArguments().isPresent()) {
+//            throw new IllegalArgumentException("Type inference unnecessary as type arguments have been specified");
+//        }
+
+        // Given a method invocation that provides no explicit type arguments, the process to determine whether a
+        // potentially applicable generic method m is applicable is as follows:
+
+        // - Where P1, ..., Pp (p ≥ 1) are the type parameters of m, let α1, ..., αp be inference variables, and
+        //   let θ be the substitution [P1:=α1, ..., Pp:=αp].
+
+        List<ResolvedTypeParameterDeclaration> Ps = methodDeclaration.getTypeParameters();
+        List<InferenceVariable> alphas = InferenceVariable.instantiate(Ps);
+        Substitution theta = Substitution.empty();
+        for (int i=0;i<Ps.size();i++) {
+            theta = theta.withPair(Ps.get(0), alphas.get(0));
+        }
+
+        // - An initial bound set, B0, is constructed from the declared bounds of P1, ..., Pp, as described in §18.1.3.
+
+        BoundSet B0 = boundSetup(Ps, alphas);
+
+        // - For all i (1 ≤ i ≤ p), if Pi appears in the throws clause of m, then the bound throws αi is implied.
+        //   These bounds, if any, are incorporated with B0 to produce a new bound set, B1.
+
+        BoundSet B1 = B0;
+        for (int i=0;i<Ps.size();i++) {
+            ResolvedTypeParameterDeclaration Pi = Ps.get(i);
+            if (appearInThrowsClause(Pi, methodDeclaration)) {
+                B1 = B1.withBound(new ThrowsBound(alphas.get(i)));
+            }
+        }
+
+        // - A set of constraint formulas, C, is constructed as follows.
+        //
+        //   Let F1, ..., Fn be the formal parameter types of m, and let e1, ..., ek be the actual argument expressions
+        //   of the invocation. Then:
+
+        List<ResolvedType> Fs = formalParameterTypes(methodDeclaration);
+        List<Expression> es = argumentExpressions;
+
+        Optional<ConstraintFormulaSet> C = Optional.empty();
+
+        //   - To test for applicability by strict invocation:
+
+        if (!C.isPresent()) {
+            C = testForApplicabilityByStrictInvocation(Fs, es, theta);
+        }
+
+        //   - To test for applicability by loose invocation:
+
+        if (!C.isPresent()) {
+            C = testForApplicabilityByLooseInvocation(Fs, es, theta);
+        }
+
+        //   - To test for applicability by variable arity invocation:
+
+        if (!C.isPresent()) {
+            C = testForApplicabilityByVariableArityInvocation(Fs, es, theta);
+        }
+
+        if (!C.isPresent()) {
+            return Optional.empty();
+        }
+
+        // - C is reduced (§18.2) and the resulting bounds are incorporated with B1 to produce a new bound set, B2.
+
+        BoundSet resultingBounds = C.get().reduce(typeSolver);
+        BoundSet B2 = B1.incorporate(resultingBounds, typeSolver);
+
+        // - Finally, the method m is applicable if B2 does not contain the bound false and resolution of all the
+        //   inference variables in B2 succeeds (§18.4).
+
+        if (B2.containsFalse()) {
+            return Optional.empty();
+        }
+
+        Optional<InstantiationSet> instantiation = B2.performResolution(alphas, typeSolver);
+        return instantiation;
+    }
+
+    /**
+     * Determine whether a potentially applicable generic method m is applicable for a method invocation that
+     * provides no explicit type arguments.
+     */
+    public boolean invocationApplicabilityInference(MethodCallExpr methodCallExpr, ResolvedMethodDeclaration methodDeclaration) {
+        if (!methodCallExpr.getNameAsString().equals(methodDeclaration.getName())) {
+            throw new IllegalArgumentException();
+        }
+        Optional<InstantiationSet> partial = instantiationInference(methodCallExpr, methodDeclaration);
+        if (!partial.isPresent()) {
+            return false;
+        }
+        int nActualParams = methodCallExpr.getArguments().size();
+        int nFormalParams = methodDeclaration.getNumberOfParams();
+        if (nActualParams != nFormalParams) {
+            if (methodDeclaration.hasVariadicParameter()) {
+                if (nActualParams < (nFormalParams - 1)) {
+                    return false;
+                }
+            } else {
+                return false;
+            }
+        }
+        //MethodUsage methodUsage = instantiationSetToMethodUsage(methodDeclaration, partial.get());
+//        for (int i=0;i<nActualParams;i++) {
+//            int formalIndex = i >= nFormalParams ? nFormalParams - 1 : i;
+//            Type formalType = methodDeclaration.getParam(formalIndex).getType();
+//            Type actualType = JavaParserFacade.get(typeSolver).getType(methodCallExpr.getArgument(i));
+//            //if (!formalType.isAssignableBy(actualType)) {
+//            //    return false;
+//            //}
+//        }
+        return true;
+    }
+
+    public BoundSet invocationTypeInferenceBoundsSetB3() {
+        // Given a method invocation that provides no explicit type arguments, and a corresponding most specific
+        // applicable generic method m, the process to infer the invocation type (§15.12.2.6) of the chosen method is
+        // as follows:
+        //
+        // - Let θ be the substitution [P1:=α1, ..., Pp:=αp] defined in §18.5.1 to replace the type parameters of m with inference variables.
+        //
+        // - Let B2 be the bound set produced by reduction in order to demonstrate that m is applicable in §18.5.1. (While it was necessary in §18.5.1 to demonstrate that the inference variables in B2 could be resolved, in order to establish applicability, the instantiations produced by this resolution step are not considered part of B2.)
+        //
+        // - If the invocation is not a poly expression, let the bound set B3 be the same as B2.
+        //
+        //   If the invocation is a poly expression, let the bound set B3 be derived from B2 as follows. Let R be the
+        //   return type of m, let T be the invocation's target type, and then:
+        //
+        //   - If unchecked conversion was necessary for the method to be applicable during constraint set reduction
+        //     in §18.5.1, the constraint formula ‹|R| → T› is reduced and incorporated with B2.
+        //
+        //   - Otherwise, if R θ is a parameterized type, G<A1, ..., An>, and one of A1, ..., An is a wildcard, then,
+        //     for fresh inference variables β1, ..., βn, the constraint formula ‹G<β1, ..., βn> → T› is reduced and
+        //     incorporated, along with the bound G<β1, ..., βn> = capture(G<A1, ..., An>), with B2.
+        //
+        //   - Otherwise, if R θ is an inference variable α, and one of the following is true:
+        //
+        //     - T is a reference type, but is not a wildcard-parameterized type, and either i) B2 contains a bound of
+        //       one of the forms α = S or S <: α, where S is a wildcard-parameterized type, or ii) B2 contains two
+        //       bounds of the forms S1 <: α and S2 <: α, where S1 and S2 have supertypes that are two different
+        //       parameterizations of the same generic class or interface.
+        //
+        //     - T is a parameterization of a generic class or interface, G, and B2 contains a bound of one of the
+        //       forms α = S or S <: α, where there exists no type of the form G<...> that is a supertype of S, but the
+        //       raw type |G<...>| is a supertype of S.
+        //
+        //     - T is a primitive type, and one of the primitive wrapper classes mentioned in §5.1.7 is an
+        //       instantiation, upper bound, or lower bound for α in B2.
+        //
+        //     then α is resolved in B2, and where the capture of the resulting instantiation of α is U, the constraint
+        //     formula ‹U → T› is reduced and incorporated with B2.
+        //
+        //   - Otherwise, the constraint formula ‹R θ → T› is reduced and incorporated with B2.
+        throw new UnsupportedOperationException();
+    }
+
+    public void invocationTypeInference() {
+        BoundSet B3 = invocationTypeInferenceBoundsSetB3();
+        //
+        //A set of constraint formulas, C, is constructed as follows.
+        //
+        //        Let e1, ..., ek be the actual argument expressions of the invocation. If m is applicable by strict or loose invocation, let F1, ..., Fk be the formal parameter types of m; if m is applicable by variable arity invocation, let F1, ..., Fk the first k variable arity parameter types of m (§15.12.2.4). Then:
+        //
+        //For all i (1 ≤ i ≤ k), if ei is not pertinent to applicability, C contains ‹ei → Fi θ›.
+        //
+        //For all i (1 ≤ i ≤ k), additional constraints may be included, depending on the form of ei:
+        //
+        //If ei is a LambdaExpression, C contains ‹LambdaExpression →throws Fi θ›.
+        //
+        //In addition, the lambda body is searched for additional constraints:
+        //
+        //For a block lambda body, the search is applied recursively to each result expression.
+        //
+        //For a poly class instance creation expression (§15.9) or a poly method invocation expression (§15.12), C contains all the constraint formulas that would appear in the set C generated by §18.5.2 when inferring the poly expression's invocation type.
+        //
+        //For a parenthesized expression, the search is applied recursively to the contained expression.
+        //
+        //For a conditional expression, the search is applied recursively to the second and third operands.
+        //
+        //For a lambda expression, the search is applied recursively to the lambda body.
+        //
+        //If ei is a MethodReference, C contains ‹MethodReference →throws Fi θ›.
+        //
+        //If ei is a poly class instance creation expression (§15.9) or a poly method invocation expression (§15.12), C contains all the constraint formulas that would appear in the set C generated by §18.5.2 when inferring the poly expression's invocation type.
+        //
+        //If ei is a parenthesized expression, these rules are applied recursively to the contained expression.
+        //
+        //If ei is a conditional expression, these rules are applied recursively to the second and third operands.
+        //
+        //While C is not empty, the following process is repeated, starting with the bound set B3 and accumulating new bounds into a "current" bound set, ultimately producing a new bound set, B4:
+        //
+        //A subset of constraints is selected in C, satisfying the property that, for each constraint, no input variable can influence an output variable of another constraint in C. The terms input variable and output variable are defined below. An inference variable α can influence an inference variable β if α depends on the resolution of β (§18.4), or vice versa; or if there exists a third inference variable γ such that α can influence γ and γ can influence β.
+        //
+        //If this subset is empty, then there is a cycle (or cycles) in the graph of dependencies between constraints. In this case, all constraints are considered that participate in a dependency cycle (or cycles) and do not depend on any constraints outside of the cycle (or cycles). A single constraint is selected from the considered constraints, as follows:
+        //
+        //If any of the considered constraints have the form ‹Expression → T›, then the selected constraint is the considered constraint of this form that contains the expression to the left (§3.5) of the expression of every other considered constraint of this form.
+        //
+        //        If no considered constraint has the form ‹Expression → T›, then the selected constraint is the considered constraint that contains the expression to the left of the expression of every other considered constraint.
+        //
+        //        The selected constraint(s) are removed from C.
+        //
+        //        The input variables α1, ..., αm of all the selected constraint(s) are resolved.
+        //
+        //        Where T1, ..., Tm are the instantiations of α1, ..., αm, the substitution [α1:=T1, ..., αm:=Tm] is applied to every constraint.
+        //
+        //        The constraint(s) resulting from substitution are reduced and incorporated with the current bound set.
+        //
+        //Finally, if B4 does not contain the bound false, the inference variables in B4 are resolved.
+        //
+        //If resolution succeeds with instantiations T1, ..., Tp for inference variables α1, ..., αp, let θ' be the substitution [P1:=T1, ..., Pp:=Tp]. Then:
+        //
+        //If unchecked conversion was necessary for the method to be applicable during constraint set reduction in §18.5.1, then the parameter types of the invocation type of m are obtained by applying θ' to the parameter types of m's type, and the return type and thrown types of the invocation type of m are given by the erasure of the return type and thrown types of m's type.
+        //
+        //If unchecked conversion was not necessary for the method to be applicable, then the invocation type of m is obtained by applying θ' to the type of m.
+        //
+        //If B4 contains the bound false, or if resolution fails, then a compile-time error occurs.
+        //
+        //Invocation type inference may require carefully sequencing the reduction of constraint formulas of the forms ‹Expression → T›, ‹LambdaExpression →throws T›, and ‹MethodReference →throws T›. To facilitate this sequencing, the input variables of these constraints are defined as follows:
+        //
+        //For ‹LambdaExpression → T›:
+        //
+        //If T is an inference variable, it is the (only) input variable.
+        //
+        //        If T is a functional interface type, and a function type can be derived from T (§15.27.3), then the input variables include i) if the lambda expression is implicitly typed, the inference variables mentioned by the function type's parameter types; and ii) if the function type's return type, R, is not void, then for each result expression e in the lambda body (or for the body itself if it is an expression), the input variables of ‹e → R›.
+        //
+        //Otherwise, there are no input variables.
+        //
+        //For ‹LambdaExpression →throws T›:
+        //
+        //If T is an inference variable, it is the (only) input variable.
+        //
+        //        If T is a functional interface type, and a function type can be derived, as described in §15.27.3, the input variables include i) if the lambda expression is implicitly typed, the inference variables mentioned by the function type's parameter types; and ii) the inference variables mentioned by the function type's return type.
+        //
+        //        Otherwise, there are no input variables.
+        //
+        //        For ‹MethodReference → T›:
+        //
+        //If T is an inference variable, it is the (only) input variable.
+        //
+        //        If T is a functional interface type with a function type, and if the method reference is inexact (§15.13.1), the input variables are the inference variables mentioned by the function type's parameter types.
+        //
+        //Otherwise, there are no input variables.
+        //
+        //For ‹MethodReference →throws T›:
+        //
+        //If T is an inference variable, it is the (only) input variable.
+        //
+        //        If T is a functional interface type with a function type, and if the method reference is inexact (§15.13.1), the input variables are the inference variables mentioned by the function type's parameter types and the function type's return type.
+        //
+        //        Otherwise, there are no input variables.
+        //
+        //        For ‹Expression → T›, if Expression is a parenthesized expression:
+        //
+        //Where the contained expression of Expression is Expression', the input variables are the input variables of ‹Expression' → T›.
+        //
+        //For ‹ConditionalExpression → T›:
+        //
+        //Where the conditional expression has the form e1 ? e2 : e3, the input variables are the input variables of ‹e2 → T› and ‹e3 → T›.
+        //
+        //For all other constraint formulas, there are no input variables.
+        //
+        //The output variables of these constraints are all inference variables mentioned by the type on the right-hand side of the constraint, T, that are not input variables.
+
+        throw new UnsupportedOperationException();
+    }
+
+    public void functionalInterfaceParameterizationInference(LambdaExpr lambdaExpr,
+                                                             ResolvedInterfaceDeclaration interfaceDeclaration) {
+        // Where a lambda expression with explicit parameter types P1, ..., Pn targets a functional interface
+        // type F<A1, ..., Am> with at least one wildcard type argument, then a parameterization of F may be derived
+        // as the ground target type of the lambda expression as follows.
+
+        int n = lambdaExpr.getParameters().size();
+
+        if (interfaceDeclaration.getTypeParameters().isEmpty()) {
+            throw new IllegalArgumentException("Functional Interface without type arguments");
+        }
+
+        // Let Q1, ..., Qk be the parameter types of the function type of the type F<α1, ..., αm>,
+        // where α1, ..., αm are fresh inference variables.
+
+        int k = interfaceDeclaration.getTypeParameters().size();
+        List<InferenceVariable> alphas = InferenceVariable.instantiate(interfaceDeclaration.getTypeParameters());
+
+        TypeInferenceCache.recordInferenceVariables(typeSolver, lambdaExpr, alphas);
+
+        // If n ≠ k, no valid parameterization exists.
+
+        if (n != k) {
+            throw new IllegalArgumentException("No valida parameterization can exist has n=" + " and k=" + k);
+        }
+
+        // Otherwise, a set of constraint formulas is formed with, for
+        // all i (1 ≤ i ≤ n), ‹Pi = Qi›. This constraint formula set is reduced to form the bound set B.
+
+        ConstraintFormulaSet constraintFormulaSet = ConstraintFormulaSet.empty();
+        for (int i=0; i<n; i++) {
+            throw new UnsupportedOperationException();
+            //Type pi = JavaParserFacade.get(typeSolver).convertToUsage(lambdaExpr.getParameters().get(i).getType(), lambdaExpr);
+            //Type qi = JavaParserFacade.get(typeSolver).convertToUsage(interfaceDeclaration.getm.get(i).getType(), lambdaExpr);
+            //constraintFormulaSet = constraintFormulaSet.withConstraint(new TypeSameAsType(pi, qi));
+        }
+        BoundSet B = constraintFormulaSet.reduce(typeSolver);
+
+        // If B contains the bound false, no valid parameterization exists. Otherwise, a new parameterization of the
+        // functional interface type, F<A'1, ..., A'm>, is constructed as follows, for 1 ≤ i ≤ m:
+        //
+        // - If B contains an instantiation (§18.1.3) for αi, T, then A'i = T.
+        //
+        // - Otherwise, A'i = Ai.
+        //
+        // If F<A'1, ..., A'm> is not a well-formed type (that is, the type arguments are not within their bounds), or if F<A'1, ..., A'm> is not a subtype of F<A1, ..., Am>, no valid parameterization exists. Otherwise, the inferred parameterization is either F<A'1, ..., A'm>, if all the type arguments are types, or the non-wildcard parameterization (§9.9) of F<A'1, ..., A'm>, if one or more type arguments are still wildcards.
+
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Return if m2 is more specific than m1
+     * @param methodCall
+     * @param m1
+     * @param m2
+     */
+    public boolean moreSpecificMethodInference(MethodCallExpr methodCall, ResolvedMethodDeclaration m1, ResolvedMethodDeclaration m2) {
+        // When testing that one applicable method is more specific than another (§15.12.2.5), where the second method
+        // is generic, it is necessary to test whether some instantiation of the second method's type parameters can be
+        // inferred to make the first method more specific than the second.
+
+        if (!m2.isGeneric()) {
+            throw new IllegalArgumentException("M2 is not generic (m2: " + m2 + ")");
+        }
+
+        // Let m1 be the first method and m2 be the second method. Where m2 has type parameters P1, ..., Pp,
+        // let α1, ..., αp be inference variables, and let θ be the substitution [P1:=α1, ..., Pp:=αp].
+        //
+        // Let e1, ..., ek be the argument expressions of the corresponding invocation. Then:
+        //
+        // - If m1 and m2 are applicable by strict or loose invocation (§15.12.2.2, §15.12.2.3), then let S1, ..., Sk be the formal parameter types of m1, and let T1, ..., Tk be the result of θ applied to the formal parameter types of m2.
+        //
+        // - If m1 and m2 are applicable by variable arity invocation (§15.12.2.4), then let S1, ..., Sk be the first k variable arity parameter types of m1, and let T1, ..., Tk be the result of θ applied to the first k variable arity parameter types of m2.
+        //
+        // Note that no substitution is applied to S1, ..., Sk; even if m1 is generic, the type parameters of m1 are treated as type variables, not inference variables.
+        //
+        // The process to determine if m1 is more specific than m2 is as follows:
+        //
+        // - First, an initial bound set, B, is constructed from the declared bounds of P1, ..., Pp, as specified in §18.1.3.
+        //
+        // - Second, for all i (1 ≤ i ≤ k), a set of constraint formulas or bounds is generated.
+        //
+        //   If Ti is a proper type, the result is true if Si is more specific than Ti for ei (§15.12.2.5), and false otherwise. (Note that Si is always a proper type.)
+        //
+        //   Otherwise, if Ti is not a functional interface type, the constraint formula ‹Si <: Ti› is generated.
+        //
+        //   Otherwise, Ti is a parameterization of a functional interface, I. It must be determined whether Si satisfies the following five conditions:
+        //
+        //   1. Si is a functional interface type.
+        //
+        //   2. Si is not a superinterface of I, nor a parameterization of a superinterface of I.
+        //
+        //   3. Si is not a subinterface of I, nor a parameterization of a subinterface of I.
+        //
+        //   4. If Si is an intersection type, at least one element of the intersection is not a superinterface of I, nor a parameterization of a superinterface of I.
+        //
+        //   5. If Si is an intersection type, no element of the intersection is a subinterface of I, nor a parameterization of a subinterface of I.
+        //
+        //   If all five conditions are true, then the following constraint formulas or bounds are generated (where U1 ... Uk and R1 are the parameter types and return type of the function type of the capture of Si, and V1 ... Vk and R2 are the parameter types and return type of the function type of Ti):
+        //
+        //   - If ei is an explicitly typed lambda expression:
+        //
+        //     - For all j (1 ≤ j ≤ k), ‹Uj = Vj›.
+        //
+        //     - If R2 is void, true.
+        //
+        //     - Otherwise, if R1 and R2 are functional interface types, and neither interface is a subinterface of the other, and ei has at least one result expression, then these rules are applied recursively to R1 and R2, for each result expression in ei.
+        //
+        //     - Otherwise, if R1 is a primitive type and R2 is not, and ei has at least one result expression, and each result expression of ei is a standalone expression (§15.2) of a primitive type, true.
+        //
+        //     - Otherwise, if R2 is a primitive type and R1 is not, and ei has at least one result expression, and each result expression of ei is either a standalone expression of a reference type or a poly expression, true.
+        //
+        //     - Otherwise, ‹R1 <: R2›.
+        //
+        //   - If ei is an exact method reference:
+        //
+        //     - For all j (1 ≤ j ≤ k), ‹Uj = Vj›.
+        //
+        //     - If R2 is void, true.
+        //
+        //     - Otherwise, if R1 is a primitive type and R2 is not, and the compile-time declaration for ei has a primitive return type, true.
+        //
+        //     - Otherwise if R2 is a primitive type and R1 is not, and the compile-time declaration for ei has a reference return type, true.
+        //
+        //     - Otherwise, ‹R1 <: R2›.
+        //
+        //   - If ei is a parenthesized expression, these rules are applied recursively to the contained expression.
+        //
+        //   - If ei is a conditional expression, these rules are applied recursively to each of the second and third operands.
+        //
+        //   - Otherwise, false.
+        //
+        //   If the five constraints on Si are not satisfied, the constraint formula ‹Si <: Ti› is generated instead.
+        //
+        // - Third, if m2 is applicable by variable arity invocation and has k+1 parameters, then where Sk+1 is the k+1'th variable arity parameter type of m1 and Tk+1 is the result of θ applied to the k+1'th variable arity parameter type of m2, the constraint ‹Sk+1 <: Tk+1› is generated.
+        //
+        // - Fourth, the generated bounds and constraint formulas are reduced and incorporated with B to produce a bound set B'.
+        //
+        //   If B' does not contain the bound false, and resolution of all the inference variables in B' succeeds, then m1 is more specific than m2.
+        //
+        //   Otherwise, m1 is not more specific than m2.
+
+        throw new UnsupportedOperationException();
+    }
+
+
+    ///
+    /// Private static methods
+    ///
+
+    private static MethodUsage instantiationSetToMethodUsage(ResolvedMethodDeclaration methodDeclaration, InstantiationSet instantiationSet) {
+        if (instantiationSet.isEmpty()) {
+            return new MethodUsage(methodDeclaration);
+        }
+        List<ResolvedType> paramTypes = new LinkedList<>();
+        for (int i=0;i<methodDeclaration.getNumberOfParams();i++) {
+            paramTypes.add(instantiationSet.apply(methodDeclaration.getParam(i).getType()));
+        }
+        ResolvedType returnType = instantiationSet.apply(methodDeclaration.getReturnType());
+        return new MethodUsage(methodDeclaration, paramTypes, returnType);
+    }
+
+    ///
+    /// Private instance methods
+    ///
+
+    /**
+     * When inference begins, a bound set is typically generated from a list of type parameter declarations P1, ..., Pp
+     * and associated inference variables α1, ..., αp
+     *
+     * @param typeParameterDeclarations
+     * @param inferenceVariables
+     * @return
+     */
+    private BoundSet boundSetup(List<ResolvedTypeParameterDeclaration> typeParameterDeclarations, List<InferenceVariable> inferenceVariables) {
+        if (typeParameterDeclarations.size() != inferenceVariables.size()) {
+            throw new IllegalArgumentException();
+        }
+
+        // When inference begins, a bound set is typically generated from a list of
+        // type parameter declarations P1, ..., Pp and associated inference variables α1, ..., αp.
+        // Such a bound set is constructed as follows. For each l (1 ≤ l ≤ p):
+
+        BoundSet boundSet = BoundSet.empty();
+
+        for (int l=0;l<typeParameterDeclarations.size();l++) {
+            ResolvedTypeParameterDeclaration Pl = typeParameterDeclarations.get(l);
+            InferenceVariable alphaL = inferenceVariables.get(l);
+
+            // - If Pl has no TypeBound, the bound αl <: Object appears in the set.
+
+            if (Pl.getBounds().isEmpty()) {
+                boundSet = boundSet.withBound(new SubtypeOfBound(alphaL, object));
+            } else {
+
+                // - Otherwise, for each type T delimited by & in the TypeBound, the bound αl <: T[P1:=α1, ..., Pp:=αp] appears
+                // in the set; if this results in no proper upper bounds for αl (only dependencies), then the
+                // bound αl <: Object also appears in the set.
+
+                for (ResolvedTypeParameterDeclaration.Bound bound : Pl.getBounds()) {
+                    ResolvedType T = bound.getType();
+                    Substitution substitution = Substitution.empty();
+                    for (int j=0;j<typeParameterDeclarations.size();j++) {
+                        substitution = substitution.withPair(typeParameterDeclarations.get(j), inferenceVariables.get(j));
+                    }
+                    ResolvedType TWithSubstitutions = substitution.apply(T);
+
+                    boundSet = boundSet.withBound(new SubtypeOfBound(alphaL, TWithSubstitutions));
+
+                    if (boundSet.getProperUpperBoundsFor(alphaL).isEmpty()) {
+                        boundSet = boundSet.withBound(new SubtypeOfBound(alphaL, object));
+                    }
+                }
+            }
+        }
+
+        return boundSet;
+    }
+
+    private boolean appearInThrowsClause(ResolvedTypeParameterDeclaration p, ResolvedMethodDeclaration methodDeclaration) {
+        for (int j=0;j<methodDeclaration.getNumberOfSpecifiedExceptions();j++) {
+            ResolvedType thrownType = methodDeclaration.getSpecifiedException(j);
+            if (thrownType.isTypeVariable() && thrownType.asTypeVariable().asTypeParameter().equals(p)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private List<ResolvedType> formalParameterTypes(ResolvedMethodDeclaration methodDeclaration) {
+        List<ResolvedType> types = new LinkedList<>();
+        for (int i=0;i<methodDeclaration.getNumberOfParams();i++) {
+            types.add(methodDeclaration.getParam(i).getType());
+        }
+        return types;
+    }
+
+    private boolean isImplicitlyTyped(LambdaExpr lambdaExpr) {
+        return lambdaExpr.getParameters().stream().anyMatch(p -> p.getType() instanceof UnknownType);
+    }
+
+    private boolean isInexact(MethodReferenceExpr methodReferenceExpr) {
+        throw new UnsupportedOperationException();
+    }
+
+    private boolean isPertinentToApplicability(Expression argument) {
+        // An argument expression is considered pertinent to applicability for a potentially applicable method m
+        // unless it has one of the following forms:
+        //
+        // - An implicitly typed lambda expression (§15.27.1).
+
+        if (argument instanceof LambdaExpr) {
+            LambdaExpr lambdaExpr = (LambdaExpr)argument;
+            if (isImplicitlyTyped(lambdaExpr)) {
+                return false;
+            }
+        }
+
+        // - An inexact method reference expression (§15.13.1).
+
+        if (argument instanceof MethodReferenceExpr) {
+            MethodReferenceExpr methodReferenceExpr = (MethodReferenceExpr)argument;
+            if (isInexact(methodReferenceExpr)) {
+                return false;
+            }
+        }
+
+        // - If m is a generic method and the method invocation does not provide explicit type arguments, an
+        //   explicitly typed lambda expression or an exact method reference expression for which the
+        //   corresponding target type (as derived from the signature of m) is a type parameter of m.
+
+        if (argument instanceof LambdaExpr) {
+            throw new UnsupportedOperationException();
+        }
+
+        if (argument instanceof MethodReferenceExpr) {
+            throw new UnsupportedOperationException();
+        }
+
+        // - An explicitly typed lambda expression whose body is an expression that is not pertinent to applicability.
+
+        if (argument instanceof LambdaExpr) {
+            throw new UnsupportedOperationException();
+        }
+
+        // - An explicitly typed lambda expression whose body is a block, where at least one result expression is not
+        //   pertinent to applicability.
+
+        if (argument instanceof LambdaExpr) {
+            throw new UnsupportedOperationException();
+        }
+
+        // - A parenthesized expression (§15.8.5) whose contained expression is not pertinent to applicability.
+
+        if (argument instanceof EnclosedExpr) {
+            EnclosedExpr enclosedExpr = (EnclosedExpr)argument;
+            return isPertinentToApplicability(enclosedExpr.getInner());
+        }
+
+        // - A conditional expression (§15.25) whose second or third operand is not pertinent to applicability.
+
+        if (argument instanceof ConditionalExpr) {
+            ConditionalExpr conditionalExpr = (ConditionalExpr)argument;
+            return isPertinentToApplicability(conditionalExpr.getThenExpr()) &&
+                    isPertinentToApplicability(conditionalExpr.getElseExpr());
+        }
+
+        return true;
+    }
+
+    private Optional<ConstraintFormulaSet> testForApplicabilityByStrictInvocation(List<ResolvedType> Fs, List<Expression> es,
+                                                                                  Substitution theta) {
+        int n = Fs.size();
+        int k = es.size();
+
+        // If k ≠ n, or if there exists an i (1 ≤ i ≤ n) such that ei is pertinent to applicability (§15.12.2.2)
+        // and either:
+        // i) ei is a standalone expression of a primitive type but Fi is a reference type, or
+        // ii) Fi is a primitive type but ei is not a standalone expression of a primitive type;
+        if (k != n) {
+            return Optional.empty();
+        }
+        for (int i=0;i<n;i++) {
+            Expression ei = es.get(i);
+            ResolvedType fi = Fs.get(i);
+            if (isPertinentToApplicability(ei)) {
+                if (isStandaloneExpression(ei) && JavaParserFacade.get(typeSolver).getType(ei).isPrimitive()
+                        && fi.isReferenceType()) {
+                    return Optional.empty();
+                }
+                if (fi.isPrimitive() && (!isStandaloneExpression(ei) || !JavaParserFacade.get(typeSolver).getType(ei).isPrimitive())) {
+                    return Optional.empty();
+                }
+            }
+        }
+        // then the method is not applicable and there is no need to proceed with inference.
+        //
+        // Otherwise, C includes, for all i (1 ≤ i ≤ k) where ei is pertinent to applicability, ‹ei → Fi θ›.
+
+        return Optional.of(constraintSetFromArgumentsSubstitution(Fs, es, theta, k));
+    }
+
+    private ResolvedType typeWithSubstitution(ResolvedType originalType, Substitution substitution) {
+        return substitution.apply(originalType);
+    }
+
+    private Optional<ConstraintFormulaSet> testForApplicabilityByLooseInvocation(List<ResolvedType> Fs, List<Expression> es,
+                                                                                 Substitution theta) {
+        int n = Fs.size();
+        int k = es.size();
+
+        // If k ≠ n, the method is not applicable and there is no need to proceed with inference.
+
+        if (k != n) {
+            return Optional.empty();
+        }
+
+        // Otherwise, C includes, for all i (1 ≤ i ≤ k) where ei is pertinent to applicability, ‹ei → Fi θ›.
+        return Optional.of(constraintSetFromArgumentsSubstitution(Fs, es, theta, k));
+    }
+
+    private ConstraintFormulaSet constraintSetFromArgumentsSubstitution(List<ResolvedType> Fs, List<Expression> es, Substitution theta, int k) {
+        ConstraintFormulaSet constraintFormulaSet = ConstraintFormulaSet.empty();
+        for (int i=0;i<k;i++) {
+            Expression ei = es.get(i);
+            ResolvedType fi = Fs.get(i);
+            ResolvedType fiTheta = typeWithSubstitution(fi, theta);
+            constraintFormulaSet = constraintFormulaSet.withConstraint(
+                    new ExpressionCompatibleWithType(typeSolver, ei, fiTheta));
+        }
+        return constraintFormulaSet;
+    }
+
+    private Optional<ConstraintFormulaSet> testForApplicabilityByVariableArityInvocation(List<ResolvedType> Fs, List<Expression> es,
+                                                                                         Substitution theta) {
+        int k = es.size();
+
+        // Let F'1, ..., F'k be the first k variable arity parameter types of m (§15.12.2.4). C includes,
+        // for all i (1 ≤ i ≤ k) where ei is pertinent to applicability, ‹ei → F'i θ›.
+
+        List<ResolvedType> FsFirst = new LinkedList<>();
+        for (int i=0;i<k;i++) {
+            ResolvedType FFirstI = i < Fs.size() ? Fs.get(i) : Fs.get(Fs.size() - 1);
+            FsFirst.add(FFirstI);
+        }
+
+        return Optional.of(constraintSetFromArgumentsSubstitution(FsFirst, es, theta, k));
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInferenceCache.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInferenceCache.java
new file mode 100644
index 0000000..496aa00
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/TypeInferenceCache.java
@@ -0,0 +1,56 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference;
+
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.*;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class TypeInferenceCache {
+
+    private static Map<TypeSolver, IdentityHashMap<LambdaExpr, Map<String, ResolvedType>>> typeForLambdaParameters = new HashMap<>();
+    private static Map<TypeSolver, IdentityHashMap<LambdaExpr, List<InferenceVariable>>> inferenceVariables = new HashMap<>();
+
+    public static void record(TypeSolver typeSolver, LambdaExpr lambdaExpr, String paramName, ResolvedType type) {
+        if (!typeForLambdaParameters.containsKey(typeSolver)) {
+            typeForLambdaParameters.put(typeSolver, new IdentityHashMap<>());
+        }
+        if (!typeForLambdaParameters.get(typeSolver).containsKey(lambdaExpr)) {
+            typeForLambdaParameters.get(typeSolver).put(lambdaExpr, new HashMap<>());
+        }
+        typeForLambdaParameters.get(typeSolver).get(lambdaExpr).put(paramName, type);
+    }
+
+    public static Optional<ResolvedType> retrieve(TypeSolver typeSolver, LambdaExpr lambdaExpr, String paramName) {
+        if (!typeForLambdaParameters.containsKey(typeSolver)) {
+            return Optional.empty();
+        }
+        if (!typeForLambdaParameters.get(typeSolver).containsKey(lambdaExpr)) {
+            return Optional.empty();
+        }
+        if (!typeForLambdaParameters.get(typeSolver).get(lambdaExpr).containsKey(paramName)) {
+            return Optional.empty();
+        }
+        return Optional.of(typeForLambdaParameters.get(typeSolver).get(lambdaExpr).get(paramName));
+    }
+
+    public static void recordInferenceVariables(TypeSolver typeSolver, LambdaExpr lambdaExpr, List<InferenceVariable> _inferenceVariables) {
+        if (!inferenceVariables.containsKey(typeSolver)) {
+            inferenceVariables.put(typeSolver, new IdentityHashMap<>());
+        }
+        inferenceVariables.get(typeSolver).put(lambdaExpr, _inferenceVariables);
+    }
+
+    public static Optional<List<InferenceVariable>> retrieveInferenceVariables(TypeSolver typeSolver, LambdaExpr lambdaExpr) {
+        if (!inferenceVariables.containsKey(typeSolver)) {
+            return Optional.empty();
+        }
+        if (!inferenceVariables.get(typeSolver).containsKey(lambdaExpr)) {
+            return Optional.empty();
+        }
+        return Optional.of(inferenceVariables.get(typeSolver).get(lambdaExpr));
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/CapturesBound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/CapturesBound.java
new file mode 100644
index 0000000..563bb29
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/CapturesBound.java
@@ -0,0 +1,69 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.bounds;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.Bound;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariableSubstitution;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Capture(G<A1, ..., An>): The variables α1, ..., αn represent the result of capture conversion (§5.1.10)
+ * applied to G<A1, ..., An> (where A1, ..., An may be types or wildcards and may mention inference variables).
+ *
+ * @author Federico Tomassetti
+ */
+public class CapturesBound extends Bound {
+    private List<InferenceVariable> inferenceVariables;
+    private List<ResolvedType> typesOrWildcards;
+
+    public CapturesBound(List<InferenceVariable> inferenceVariables, List<ResolvedType> typesOrWildcards) {
+        this.inferenceVariables = inferenceVariables;
+        this.typesOrWildcards = typesOrWildcards;
+    }
+
+    @Override
+    public boolean isSatisfied(InferenceVariableSubstitution inferenceVariableSubstitution) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Set<InferenceVariable> usedInferenceVariables() {
+        throw new UnsupportedOperationException();
+    }
+
+    public List<InferenceVariable> getInferenceVariables() {
+        return inferenceVariables;
+    }
+
+    public List<ResolvedType> getTypesOrWildcards() {
+        return typesOrWildcards;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        CapturesBound that = (CapturesBound) o;
+
+        if (!inferenceVariables.equals(that.inferenceVariables)) return false;
+        return typesOrWildcards.equals(that.typesOrWildcards);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = inferenceVariables.hashCode();
+        result = 31 * result + typesOrWildcards.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "CapturesBound{" +
+                "inferenceVariables=" + inferenceVariables +
+                ", typesOrWildcards=" + typesOrWildcards +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/FalseBound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/FalseBound.java
new file mode 100644
index 0000000..b1554db
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/FalseBound.java
@@ -0,0 +1,42 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.bounds;
+
+import com.github.javaparser.symbolsolver.resolution.typeinference.Bound;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariableSubstitution;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * No valid choice of inference variables exists.
+ *
+ * @author Federico Tomassetti
+ */
+public class FalseBound extends Bound {
+
+    private static FalseBound INSTANCE = new FalseBound();
+
+    private FalseBound() {
+
+    }
+
+    public static FalseBound getInstance() {
+        return INSTANCE;
+    }
+
+    @Override
+    public String toString() {
+        return "FalseBound{}";
+    }
+
+    @Override
+    public boolean isSatisfied(InferenceVariableSubstitution inferenceVariableSubstitution) {
+        return false;
+    }
+
+    @Override
+    public Set<InferenceVariable> usedInferenceVariables() {
+        return Collections.emptySet();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBound.java
new file mode 100644
index 0000000..4d0756b
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBound.java
@@ -0,0 +1,96 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.bounds;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.Bound;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariableSubstitution;
+import com.github.javaparser.symbolsolver.resolution.typeinference.Instantiation;
+import com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper;
+
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isInferenceVariable;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+
+/**
+ * S = T, where at least one of S or T is an inference variable: S is the same as T.
+ *
+ * @author Federico Tomassetti
+ */
+public class SameAsBound extends Bound {
+    private ResolvedType s;
+    private ResolvedType t;
+
+    public SameAsBound(ResolvedType s, ResolvedType t) {
+        if (!isInferenceVariable(s) && !isInferenceVariable(t)) {
+            throw new IllegalArgumentException("One of S or T should be an inference variable");
+        }
+        this.s = s;
+        this.t = t;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SameAsBound that = (SameAsBound) o;
+
+        if (!s.equals(that.s)) return false;
+        return t.equals(that.t);
+    }
+
+    @Override
+    public String toString() {
+        return "SameAsBound{" +
+                "s=" + s +
+                ", t=" + t +
+                '}';
+    }
+
+    @Override
+    public int hashCode() {
+        int result = s.hashCode();
+        result = 31 * result + t.hashCode();
+        return result;
+    }
+
+    @Override
+    public Set<InferenceVariable> usedInferenceVariables() {
+        Set<InferenceVariable> variables = new HashSet<>();
+        variables.addAll(TypeHelper.usedInferenceVariables(s));
+        variables.addAll(TypeHelper.usedInferenceVariables(t));
+        return variables;
+    }
+
+    public ResolvedType getS() {
+        return s;
+    }
+
+    public ResolvedType getT() {
+        return t;
+    }
+
+    @Override
+    public boolean isADependency() {
+        return !isAnInstantiation().isPresent();
+    }
+
+    @Override
+    public Optional<Instantiation> isAnInstantiation() {
+        if (isInferenceVariable(s) && isProperType(t)) {
+            return Optional.of(new Instantiation((InferenceVariable) s, t));
+        }
+        if (isProperType(s) && isInferenceVariable(t)) {
+            return Optional.of(new Instantiation((InferenceVariable) t, s));
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    public boolean isSatisfied(InferenceVariableSubstitution inferenceVariableSubstitution) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBound.java
new file mode 100644
index 0000000..357e7a0
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBound.java
@@ -0,0 +1,98 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.bounds;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.*;
+import com.github.javaparser.utils.Pair;
+
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isInferenceVariable;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+
+/**
+ * S <: T, where at least one of S or T is an inference variable: S is a subtype of T
+ *
+ * @author Federico Tomassetti
+ */
+public class SubtypeOfBound extends Bound {
+    private ResolvedType s;
+    private ResolvedType t;
+
+    public SubtypeOfBound(ResolvedType s, ResolvedType t) {
+        if (!isInferenceVariable(s) && !isInferenceVariable(t)) {
+            throw new IllegalArgumentException("One of S or T should be an inference variable");
+        }
+        this.s = s;
+        this.t = t;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SubtypeOfBound that = (SubtypeOfBound) o;
+
+        if (!s.equals(that.s)) return false;
+        return t.equals(that.t);
+    }
+
+    @Override
+    public String toString() {
+        return "SubtypeOfBound{" +
+                "s=" + s +
+                ", t=" + t +
+                '}';
+    }
+
+    @Override
+    public int hashCode() {
+        int result = s.hashCode();
+        result = 31 * result + t.hashCode();
+        return result;
+    }
+
+    public ResolvedType getS() {
+        return s;
+    }
+
+    @Override
+    public Set<InferenceVariable> usedInferenceVariables() {
+        Set<InferenceVariable> variables = new HashSet<>();
+        variables.addAll(TypeHelper.usedInferenceVariables(s));
+        variables.addAll(TypeHelper.usedInferenceVariables(t));
+        return variables;
+    }
+
+    public ResolvedType getT() {
+        return t;
+    }
+
+    @Override
+    public Optional<ProperUpperBound> isProperUpperBound() {
+        if (isInferenceVariable(s) && isProperType(t)) {
+            return Optional.of(new ProperUpperBound((InferenceVariable) s, t));
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<ProperLowerBound> isProperLowerBound() {
+        if (isProperType(s) && isInferenceVariable(t)) {
+            return Optional.of(new ProperLowerBound((InferenceVariable) t, s));
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    public boolean isADependency() {
+        return !isProperLowerBound().isPresent() && !isProperUpperBound().isPresent();
+    }
+
+    @Override
+    public boolean isSatisfied(InferenceVariableSubstitution inferenceVariableSubstitution) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/ThrowsBound.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/ThrowsBound.java
new file mode 100644
index 0000000..acea3ba
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/ThrowsBound.java
@@ -0,0 +1,62 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.bounds;
+
+import com.github.javaparser.symbolsolver.resolution.typeinference.Bound;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariableSubstitution;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * The inference variable α appears in a throws clause.
+ *
+ * A bound of the form throws α is purely informational: it directs resolution to optimize the instantiation of α so
+ * that, if possible, it is not a checked exception type.
+ *
+ * @author Federico Tomassetti
+ */
+public class ThrowsBound extends Bound {
+    private InferenceVariable inferenceVariable;
+
+    public ThrowsBound(InferenceVariable inferenceVariable) {
+        this.inferenceVariable = inferenceVariable;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ThrowsBound that = (ThrowsBound) o;
+
+        return inferenceVariable.equals(that.inferenceVariable);
+    }
+
+    @Override
+    public String toString() {
+        return "ThrowsBound{" +
+                "inferenceVariable=" + inferenceVariable +
+                '}';
+    }
+
+    @Override
+    public int hashCode() {
+        return inferenceVariable.hashCode();
+    }
+
+    @Override
+    public Set<InferenceVariable> usedInferenceVariables() {
+        Set<InferenceVariable> variables = new HashSet<>();
+        variables.add(inferenceVariable);
+        return variables;
+    }
+
+    @Override
+    public boolean isSatisfied(InferenceVariableSubstitution inferenceVariableSubstitution) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isThrowsBoundOn(InferenceVariable inferenceVariable) {
+        return inferenceVariable.equals(this.inferenceVariable);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ExpressionCompatibleWithType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ExpressionCompatibleWithType.java
new file mode 100644
index 0000000..30042f8
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ExpressionCompatibleWithType.java
@@ -0,0 +1,335 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.UnknownType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typeinference.*;
+import com.github.javaparser.utils.Pair;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.ExpressionHelper.isPolyExpression;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.ExpressionHelper.isStandaloneExpression;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isCompatibleInALooseInvocationContext;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+import static java.util.stream.Collectors.*;
+
+/**
+ * An expression is compatible in a loose invocation context with type T
+ *
+ * @author Federico Tomassetti
+ */
+public class ExpressionCompatibleWithType extends ConstraintFormula {
+    private TypeSolver typeSolver;
+    private Expression expression;
+    private ResolvedType T;
+
+    public ExpressionCompatibleWithType(TypeSolver typeSolver, Expression expression, ResolvedType T) {
+        this.typeSolver = typeSolver;
+        this.expression = expression;
+        this.T = T;
+    }
+
+    @Override
+    public ReductionResult reduce(BoundSet currentBoundSet) {
+        // If T is a proper type, the constraint reduces to true if the expression is compatible in a loose
+        // invocation context with T (§5.3), and false otherwise.
+
+        if (isProperType(T)) {
+            if (isCompatibleInALooseInvocationContext(typeSolver, expression, T)) {
+                return ReductionResult.trueResult();
+            } else {
+                return ReductionResult.falseResult();
+            }
+        }
+
+        // Otherwise, if the expression is a standalone expression (§15.2) of type S, the constraint reduces
+        // to ‹S → T›.
+
+        if (isStandaloneExpression(expression)) {
+            ResolvedType s = JavaParserFacade.get(typeSolver).getType(expression, false);
+            return ReductionResult.empty().withConstraint(new TypeCompatibleWithType(typeSolver, s, T));
+        }
+
+        // Otherwise, the expression is a poly expression (§15.2). The result depends on the form of the expression:
+
+        if (isPolyExpression(expression)) {
+
+            // - If the expression is a parenthesized expression of the form ( Expression' ), the constraint reduces
+            //   to ‹Expression' → T›.
+
+            if (expression instanceof EnclosedExpr) {
+                EnclosedExpr enclosedExpr = (EnclosedExpr)expression;
+                return ReductionResult.oneConstraint(new ExpressionCompatibleWithType(typeSolver, enclosedExpr.getInner(), T));
+            }
+
+            // - If the expression is a class instance creation expression or a method invocation expression, the
+            //   constraint reduces to the bound set B3 which would be used to determine the expression's invocation
+            //   type when targeting T, as defined in §18.5.2. (For a class instance creation expression, the
+            //   corresponding "method" used for inference is defined in §15.9.3).
+            //
+            //   This bound set may contain new inference variables, as well as dependencies between these new
+            //   variables and the inference variables in T.
+
+            if (expression instanceof ObjectCreationExpr) {
+                BoundSet B3 = new TypeInference(typeSolver).invocationTypeInferenceBoundsSetB3();
+                return ReductionResult.bounds(B3);
+            }
+
+            if (expression instanceof MethodCallExpr) {
+                throw new UnsupportedOperationException();
+            }
+
+            // - If the expression is a conditional expression of the form e1 ? e2 : e3, the constraint reduces to two
+            //   constraint formulas, ‹e2 → T› and ‹e3 → T›.
+
+            if (expression instanceof ConditionalExpr) {
+                ConditionalExpr conditionalExpr = (ConditionalExpr)expression;
+                return ReductionResult.withConstraints(
+                        new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getThenExpr(), T),
+                        new ExpressionCompatibleWithType(typeSolver, conditionalExpr.getElseExpr(), T));
+            }
+
+            // - If the expression is a lambda expression or a method reference expression, the result is specified
+            //   below.
+
+            // A constraint formula of the form ‹LambdaExpression → T›, where T mentions at least one inference variable, is reduced as follows:
+
+            if (expression instanceof LambdaExpr) {
+                LambdaExpr lambdaExpr = (LambdaExpr)expression;
+
+                // - If T is not a functional interface type (§9.8), the constraint reduces to false.
+
+                if (!FunctionalInterfaceLogic.isFunctionalInterfaceType(T)) {
+                    return ReductionResult.falseResult();
+                }
+
+                // - Otherwise, let T' be the ground target type derived from T, as specified in §15.27.3. If §18.5.3
+                //   is used to derive a functional interface type which is parameterized, then the test that
+                //   F<A'1, ..., A'm> is a subtype of F<A1, ..., Am> is not performed (instead, it is asserted with a
+                //   constraint formula below). Let the target function type for the lambda expression be the
+                //   function type of T'. Then:
+
+                Pair<ResolvedType, Boolean> result = TypeHelper.groundTargetTypeOfLambda(lambdaExpr, T, typeSolver);
+                ResolvedType TFirst = result.a;
+                MethodType targetFunctionType = TypeHelper.getFunctionType(TFirst);
+                targetFunctionType = replaceTypeVariablesWithInferenceVariables(targetFunctionType);
+                if (result.b) {
+                    throw new UnsupportedOperationException();
+                }
+
+                //   - If no valid function type can be found, the constraint reduces to false.
+                //
+                //     Federico: THIS SHOULD NOT HAPPEN, IN CASE WE WILL THROW AN EXCEPTION
+                //
+                //   - Otherwise, the congruence of LambdaExpression with the target function type is asserted as
+                //     follows:
+                //
+                //     - If the number of lambda parameters differs from the number of parameter types of the function
+                //       type, the constraint reduces to false.
+
+                if (targetFunctionType.getFormalArgumentTypes().size() != lambdaExpr.getParameters().size()) {
+                    return ReductionResult.falseResult();
+                }
+
+                //     - If the lambda expression is implicitly typed and one or more of the function type's parameter
+                //       types is not a proper type, the constraint reduces to false.
+                //
+                //       This condition never arises in practice, due to the handling of implicitly typed lambda
+                //       expressions in §18.5.1 and the substitution applied to the target type in §18.5.2.
+
+                //     - If the function type's result is void and the lambda body is neither a statement expression
+                //       nor a void-compatible block, the constraint reduces to false.
+
+                if (targetFunctionType.getReturnType().isVoid()) {
+                    throw new UnsupportedOperationException();
+                }
+
+                //     - If the function type's result is not void and the lambda body is a block that is not
+                //       value-compatible, the constraint reduces to false.
+
+                if (!targetFunctionType.getReturnType().isVoid() && lambdaExpr.getBody() instanceof BlockStmt
+                        && !isValueCompatibleBlock(lambdaExpr.getBody())) {
+                    return ReductionResult.falseResult();
+                }
+
+                //     - Otherwise, the constraint reduces to all of the following constraint formulas:
+                List<ConstraintFormula> constraints = new LinkedList<>();
+
+                //       - If the lambda parameters have explicitly declared types F1, ..., Fn and the function type
+                //         has parameter types G1, ..., Gn, then i) for all i (1 ≤ i ≤ n), ‹Fi = Gi›, and ii) ‹T' <: T›.
+
+                boolean hasExplicitlyDeclaredTypes = lambdaExpr.getParameters().stream().anyMatch(p -> !(p.getType() instanceof UnknownType));
+                if (hasExplicitlyDeclaredTypes) {
+                    throw new UnsupportedOperationException();
+                }
+
+                //       - If the function type's return type is a (non-void) type R, assume the lambda's parameter
+                //         types are the same as the function type's parameter types. Then:
+
+                if (!targetFunctionType.getReturnType().isVoid()) {
+
+                    ResolvedType R = targetFunctionType.getReturnType();
+
+                    if (TypeHelper.isProperType(R)) {
+
+                        //         - If R is a proper type, and if the lambda body or some result expression in the lambda body
+                        //           is not compatible in an assignment context with R, then false.
+
+                        if (lambdaExpr.getBody() instanceof BlockStmt) {
+                            List<Expression> resultExpressions = ExpressionHelper.getResultExpressions((BlockStmt)lambdaExpr.getBody());
+                            for (Expression e : resultExpressions) {
+                                if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
+                                    return ReductionResult.falseResult();
+                                }
+                            }
+                        } else {
+                            Expression e = ((ExpressionStmt)lambdaExpr.getBody()).getExpression();
+                            if (!ExpressionHelper.isCompatibleInAssignmentContext(e, R, typeSolver)) {
+                                return ReductionResult.falseResult();
+                            }
+                        }
+                    } else {
+                        //         - Otherwise, if R is not a proper type, then where the lambda body has the form Expression,
+                        //           the constraint ‹Expression → R›; or where the lambda body is a block with result
+                        //           expressions e1, ..., em, for all i (1 ≤ i ≤ m), ‹ei → R›.
+
+                        if (lambdaExpr.getBody() instanceof BlockStmt) {
+                            getAllReturnExpressions((BlockStmt)lambdaExpr.getBody()).forEach(e -> constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R)));
+                        } else {
+                            // FEDERICO: Added - Start
+                            for (int i=0;i<lambdaExpr.getParameters().size();i++) {
+                                ResolvedType paramType = targetFunctionType.getFormalArgumentTypes().get(i);
+                                TypeInferenceCache.record(typeSolver, lambdaExpr, lambdaExpr.getParameter(i).getNameAsString(), paramType);
+                            }
+                            // FEDERICO: Added - End
+                            Expression e = ((ExpressionStmt)lambdaExpr.getBody()).getExpression();
+                            constraints.add(new ExpressionCompatibleWithType(typeSolver, e, R));
+                        }
+                    }
+                }
+
+                return ReductionResult.withConstraints(constraints);
+            }
+
+            // A constraint formula of the form ‹MethodReference → T›, where T mentions at least one inference variable, is reduced as follows:
+
+            if (expression instanceof MethodReferenceExpr) {
+
+                // - If T is not a functional interface type, or if T is a functional interface type that does not have a function type (§9.9), the constraint reduces to false.
+                //
+                // - Otherwise, if there does not exist a potentially applicable method for the method reference when targeting T, the constraint reduces to false.
+                //
+                // - Otherwise, if the method reference is exact (§15.13.1), then let P1, ..., Pn be the parameter types of the function type of T, and let F1, ..., Fk be the parameter types of the potentially applicable method. The constraint reduces to a new set of constraints, as follows:
+                //
+                //   - In the special case where n = k+1, the parameter of type P1 is to act as the target reference of the invocation. The method reference expression necessarily has the form ReferenceType :: [TypeArguments] Identifier. The constraint reduces to ‹P1 <: ReferenceType› and, for all i (2 ≤ i ≤ n), ‹Pi → Fi-1›.
+                //
+                //     In all other cases, n = k, and the constraint reduces to, for all i (1 ≤ i ≤ n), ‹Pi → Fi›.
+                //
+                //   - If the function type's result is not void, let R be its return type. Then, if the result of the potentially applicable compile-time declaration is void, the constraint reduces to false. Otherwise, the constraint reduces to ‹R' → R›, where R' is the result of applying capture conversion (§5.1.10) to the return type of the potentially applicable compile-time declaration.
+                //
+                // - Otherwise, the method reference is inexact, and:
+                //
+                //   - If one or more of the function type's parameter types is not a proper type, the constraint reduces to false.
+                //
+                //     This condition never arises in practice, due to the handling of inexact method references in §18.5.1 and the substitution applied to the target type in §18.5.2.
+                //
+                //   - Otherwise, a search for a compile-time declaration is performed, as specified in §15.13.1. If there is no compile-time declaration for the method reference, the constraint reduces to false. Otherwise, there is a compile-time declaration, and:
+                //
+                //     - If the result of the function type is void, the constraint reduces to true.
+                //
+                //     - Otherwise, if the method reference expression elides TypeArguments, and the compile-time declaration is a generic method, and the return type of the compile-time declaration mentions at least one of the method's type parameters, then the constraint reduces to the bound set B3 which would be used to determine the method reference's invocation type when targeting the return type of the function type, as defined in §18.5.2. B3 may contain new inference variables, as well as dependencies between these new variables and the inference variables in T.
+                //
+                //     - Otherwise, let R be the return type of the function type, and let R' be the result of applying capture conversion (§5.1.10) to the return type of the invocation type (§15.12.2.6) of the compile-time declaration. If R' is void, the constraint reduces to false; otherwise, the constraint reduces to ‹R' → R›.
+
+                throw new UnsupportedOperationException();
+            }
+
+            throw new RuntimeException("This should not happen");
+        }
+
+        throw new RuntimeException("This should not happen");
+    }
+
+    private List<Expression> getAllReturnExpressions(BlockStmt blockStmt) {
+        return blockStmt.findAll(ReturnStmt.class).stream()
+                .filter(r -> r.getExpression().isPresent())
+                .map(r -> r.getExpression().get())
+                .collect(toList());
+    }
+
+    private boolean isValueCompatibleBlock(Statement statement) {
+        // A block lambda body is value-compatible if it cannot complete normally (§14.21) and every return statement
+        // in the block has the form return Expression;.
+
+        if (statement instanceof BlockStmt) {
+            if (!ControlFlowLogic.getInstance().canCompleteNormally(statement)) {
+                return true;
+            }
+            List<ReturnStmt> returnStmts = statement.findAll(ReturnStmt.class);
+            return returnStmts.stream().allMatch(r -> r.getExpression().isPresent());
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ExpressionCompatibleWithType that = (ExpressionCompatibleWithType) o;
+
+        if (!typeSolver.equals(that.typeSolver)) return false;
+        if (!expression.equals(that.expression)) return false;
+        return T.equals(that.T);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = typeSolver.hashCode();
+        result = 31 * result + expression.hashCode();
+        result = 31 * result + T.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "ExpressionCompatibleWithType{" +
+                "typeSolver=" + typeSolver +
+                ", expression=" + expression +
+                ", T=" + T +
+                '}';
+    }
+
+    private MethodType replaceTypeVariablesWithInferenceVariables(MethodType methodType) {
+        // Find all type variable
+        Map<ResolvedTypeVariable, InferenceVariable> correspondences = new HashMap<>();
+        List<ResolvedType> newFormalArgumentTypes = new LinkedList<>();
+        for (ResolvedType formalArg : methodType.getFormalArgumentTypes()) {
+            newFormalArgumentTypes.add(replaceTypeVariablesWithInferenceVariables(formalArg, correspondences));
+        }
+        ResolvedType newReturnType = replaceTypeVariablesWithInferenceVariables(methodType.getReturnType(), correspondences);
+        return new MethodType(methodType.getTypeParameters(), newFormalArgumentTypes, newReturnType, methodType.getExceptionTypes());
+    }
+
+    private ResolvedType replaceTypeVariablesWithInferenceVariables(ResolvedType originalType, Map<ResolvedTypeVariable, InferenceVariable> correspondences) {
+        if (originalType.isTypeVariable()) {
+            if (!correspondences.containsKey(originalType.asTypeVariable())) {
+                correspondences.put(originalType.asTypeVariable(), InferenceVariable.unnamed(originalType.asTypeVariable().asTypeParameter()));
+            }
+            return correspondences.get(originalType.asTypeVariable());
+        }
+        if (originalType.isPrimitive()) {
+            return originalType;
+        }
+        throw new UnsupportedOperationException(originalType.toString());
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/LambdaThrowsCompatibleWithType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/LambdaThrowsCompatibleWithType.java
new file mode 100644
index 0000000..b1c26ec
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/LambdaThrowsCompatibleWithType.java
@@ -0,0 +1,67 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
+import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
+
+/**
+ * The checked exceptions thrown by the body of the LambdaExpression are declared by the throws clause of the
+ * function type derived from T.
+ *
+ * @author Federico Tomassetti
+ */
+public class LambdaThrowsCompatibleWithType extends ConstraintFormula {
+    private LambdaExpr lambdaExpression;
+    private ResolvedType T;
+
+    @Override
+    public ReductionResult reduce(BoundSet currentBoundSet) {
+        // A constraint formula of the form ‹LambdaExpression →throws T› is reduced as follows:
+        //
+        // - If T is not a functional interface type (§9.8), the constraint reduces to false.
+        //
+        // - Otherwise, let the target function type for the lambda expression be determined as specified in §15.27.3. If no valid function type can be found, the constraint reduces to false.
+        //
+        // - Otherwise, if the lambda expression is implicitly typed, and one or more of the function type's parameter types is not a proper type, the constraint reduces to false.
+        //
+        //   This condition never arises in practice, due to the substitution applied to the target type in §18.5.2.
+        //
+        // - Otherwise, if the function type's return type is neither void nor a proper type, the constraint reduces to false.
+        //
+        //   This condition never arises in practice, due to the substitution applied to the target type in §18.5.2.
+        //
+        // - Otherwise, let E1, ..., En be the types in the function type's throws clause that are not proper types. If the lambda expression is implicitly typed, let its parameter types be the function type's parameter types. If the lambda body is a poly expression or a block containing a poly result expression, let the targeted return type be the function type's return type. Let X1, ..., Xm be the checked exception types that the lambda body can throw (§11.2). Then there are two cases:
+        //
+        //   - If n = 0 (the function type's throws clause consists only of proper types), then if there exists some i (1 ≤ i ≤ m) such that Xi is not a subtype of any proper type in the throws clause, the constraint reduces to false; otherwise, the constraint reduces to true.
+        //
+        //   - If n > 0, the constraint reduces to a set of subtyping constraints: for all i (1 ≤ i ≤ m), if Xi is not a subtype of any proper type in the throws clause, then the constraints include, for all j (1 ≤ j ≤ n), ‹Xi <: Ej›. In addition, for all j (1 ≤ j ≤ n), the constraint reduces to the bound throws Ej.
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        LambdaThrowsCompatibleWithType that = (LambdaThrowsCompatibleWithType) o;
+
+        if (!lambdaExpression.equals(that.lambdaExpression)) return false;
+        return T.equals(that.T);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = lambdaExpression.hashCode();
+        result = 31 * result + T.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "LambdaThrowsCompatibleWithType{" +
+                "lambdaExpression=" + lambdaExpression +
+                ", T=" + T +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/MethodReferenceThrowsCompatibleWithType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/MethodReferenceThrowsCompatibleWithType.java
new file mode 100644
index 0000000..a59e3fb
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/MethodReferenceThrowsCompatibleWithType.java
@@ -0,0 +1,62 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
+import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
+
+/**
+ * The checked exceptions thrown by the referenced method are declared by the throws clause of the function type
+ * derived from T.
+ *
+ * @author Federico Tomassetti
+ */
+public class MethodReferenceThrowsCompatibleWithType extends ConstraintFormula {
+    private MethodReferenceExpr methodReference;
+    private ResolvedType T;
+
+    @Override
+    public ReductionResult reduce(BoundSet currentBoundSet) {
+        // A constraint formula of the form ‹MethodReference →throws T› is reduced as follows:
+        //
+        // - If T is not a functional interface type, or if T is a functional interface type but does not have a function type (§9.9), the constraint reduces to false.
+        //
+        // - Otherwise, let the target function type for the method reference expression be the function type of T. If the method reference is inexact (§15.13.1) and one or more of the function type's parameter types is not a proper type, the constraint reduces to false.
+        //
+        // - Otherwise, if the method reference is inexact and the function type's result is neither void nor a proper type, the constraint reduces to false.
+        //
+        // - Otherwise, let E1, ..., En be the types in the function type's throws clause that are not proper types. Let X1, ..., Xm be the checked exceptions in the throws clause of the invocation type of the method reference's compile-time declaration (§15.13.2) (as derived from the function type's parameter types and return type). Then there are two cases:
+        //
+        //   - If n = 0 (the function type's throws clause consists only of proper types), then if there exists some i (1 ≤ i ≤ m) such that Xi is not a subtype of any proper type in the throws clause, the constraint reduces to false; otherwise, the constraint reduces to true.
+        //
+        //   - If n > 0, the constraint reduces to a set of subtyping constraints: for all i (1 ≤ i ≤ m), if Xi is not a subtype of any proper type in the throws clause, then the constraints include, for all j (1 ≤ j ≤ n), ‹Xi <: Ej›. In addition, for all j (1 ≤ j ≤ n), the constraint reduces to the bound throws Ej.
+
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MethodReferenceThrowsCompatibleWithType that = (MethodReferenceThrowsCompatibleWithType) o;
+
+        if (!methodReference.equals(that.methodReference)) return false;
+        return T.equals(that.T);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = methodReference.hashCode();
+        result = 31 * result + T.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "MethodReferenceThrowsCompatibleWithType{" +
+                "methodReference=" + methodReference +
+                ", T=" + T +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeCompatibleWithType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeCompatibleWithType.java
new file mode 100644
index 0000000..1c03064
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeCompatibleWithType.java
@@ -0,0 +1,122 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
+import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isCompatibleInALooseInvocationContext;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+
+/**
+ * A type S is compatible in a loose invocation context with type T
+ *
+ * @author Federico Tomassetti
+ */
+public class TypeCompatibleWithType extends ConstraintFormula {
+    private ResolvedType s;
+    private ResolvedType t;
+    private TypeSolver typeSolver;
+
+    public TypeCompatibleWithType(TypeSolver typeSolver, ResolvedType s, ResolvedType t) {
+        this.typeSolver = typeSolver;
+        this.s = s;
+        this.t = t;
+    }
+
+    @Override
+    public ReductionResult reduce(BoundSet currentBoundSet) {
+        // A constraint formula of the form ‹S → T› is reduced as follows:
+        //
+        // 1. If S and T are proper types, the constraint reduces to true if S is compatible in a loose invocation context with T (§5.3), and false otherwise.
+
+        if (isProperType(s) && isProperType(t)) {
+            if (isCompatibleInALooseInvocationContext(s, t)) {
+                return ReductionResult.trueResult();
+            } else {
+                return ReductionResult.falseResult();
+            }
+        }
+
+        // 2. Otherwise, if S is a primitive type, let S' be the result of applying boxing conversion (§5.1.7) to S. Then the constraint reduces to ‹S' → T›.
+
+        if (s.isPrimitive()) {
+            ReflectionTypeSolver typeSolver = new ReflectionTypeSolver();
+            ResolvedType sFirst = new ReferenceTypeImpl(typeSolver.solveType(s.asPrimitive().getBoxTypeQName()), typeSolver);
+            return ReductionResult.oneConstraint(new TypeCompatibleWithType(typeSolver, sFirst, t));
+        }
+
+        // 3. Otherwise, if T is a primitive type, let T' be the result of applying boxing conversion (§5.1.7) to T. Then the constraint reduces to ‹S = T'›.
+
+        if (t.isPrimitive()) {
+            ReflectionTypeSolver typeSolver = new ReflectionTypeSolver();
+            ResolvedType tFirst = new ReferenceTypeImpl(typeSolver.solveType(t.asPrimitive().getBoxTypeQName()), typeSolver);
+            return ReductionResult.oneConstraint(new TypeSameAsType(s, tFirst));
+        }
+
+        // The fourth and fifth cases are implicit uses of unchecked conversion (§5.1.9). These, along with any use of
+        // unchecked conversion in the first case, may result in compile-time unchecked warnings, and may influence a
+        // method's invocation type (§15.12.2.6).
+
+        // 4. Otherwise, if T is a parameterized type of the form G<T1, ..., Tn>, and there exists no type of the
+        //    form G<...> that is a supertype of S, but the raw type G is a supertype of S, then the constraint reduces
+        //    to true.
+
+        if (t.isReferenceType() && !t.asReferenceType().getTypeDeclaration().getTypeParameters().isEmpty()) {
+            // FIXME I really cannot understand what the specification means...
+
+            // there exists a type of the form G<...> that is a supertype of S?
+            boolean condition1 = t.isAssignableBy(s);
+
+            // the raw type G is a supertype of S
+            ResolvedType G = t.asReferenceType().toRawType();
+            boolean condition2 = G.isAssignableBy(s);
+
+            if (!condition1 && condition2) {
+                return ReductionResult.trueResult();
+            }
+
+            //throw new UnsupportedOperationException();
+        }
+
+        // 5. Otherwise, if T is an array type of the form G<T1, ..., Tn>[]k, and there exists no type of the form
+        //    G<...>[]k that is a supertype of S, but the raw type G[]k is a supertype of S, then the constraint
+        //    reduces to true. (The notation []k indicates an array type of k dimensions.)
+
+        if (t.isArray()) {
+            throw new UnsupportedOperationException();
+        }
+
+        // 6. Otherwise, the constraint reduces to ‹S <: T›
+
+        return ReductionResult.empty().withConstraint(new TypeSubtypeOfType(typeSolver, s, t));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        TypeCompatibleWithType that = (TypeCompatibleWithType) o;
+
+        if (!s.equals(that.s)) return false;
+        return t.equals(that.t);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = s.hashCode();
+        result = 31 * result + t.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "TypeCompatibleWithType{" +
+                "s=" + s +
+                ", t=" + t +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeContainedByType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeContainedByType.java
new file mode 100644
index 0000000..685270a
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeContainedByType.java
@@ -0,0 +1,95 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
+import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+
+/**
+ * A type argument S is contained by a type argument T
+ *
+ * @author Federico Tomassetti
+ */
+public class TypeContainedByType extends ConstraintFormula {
+    private ResolvedType S;
+    private ResolvedType T;
+
+    @Override
+    public ReductionResult reduce(BoundSet currentBoundSet) {
+        // A constraint formula of the form ‹S <= T›, where S and T are type arguments (§4.5.1), is reduced as follows:
+        //
+        // - If T is a type:
+
+        if (isProperType(T) && !T.isWildcard()) {
+
+            //   - If S is a type, the constraint reduces to ‹S = T›.
+            //
+            //   - If S is a wildcard, the constraint reduces to false.
+
+            throw new UnsupportedOperationException();
+        }
+
+        // - If T is a wildcard of the form ?, the constraint reduces to true.
+
+        if (T.isWildcard() && !T.asWildcard().isBounded()) {
+            return ReductionResult.trueResult();
+        }
+
+        // - If T is a wildcard of the form ? extends T':
+
+        if (T.isWildcard() && T.asWildcard().isExtends()) {
+
+            //   - If S is a type, the constraint reduces to ‹S <: T'›.
+            //
+            //   - If S is a wildcard of the form ?, the constraint reduces to ‹Object <: T'›.
+            //
+            //   - If S is a wildcard of the form ? extends S', the constraint reduces to ‹S' <: T'›.
+            //
+            //   - If S is a wildcard of the form ? super S', the constraint reduces to ‹Object = T'›.
+
+            throw new UnsupportedOperationException();
+        }
+
+        // - If T is a wildcard of the form ? super T':
+
+        if (T.isWildcard() && T.asWildcard().isSuper()) {
+
+            //   - If S is a type, the constraint reduces to ‹T' <: S›.
+            //
+            //   - If S is a wildcard of the form ? super S', the constraint reduces to ‹T' <: S'›.
+            //
+            //   - Otherwise, the constraint reduces to false.
+
+            throw new UnsupportedOperationException();
+        }
+
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        TypeContainedByType that = (TypeContainedByType) o;
+
+        if (!S.equals(that.S)) return false;
+        return T.equals(that.T);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = S.hashCode();
+        result = 31 * result + T.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "TypeContainedByType{" +
+                "S=" + S +
+                ", T=" + T +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeSameAsType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeSameAsType.java
new file mode 100644
index 0000000..5fbdc51
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeSameAsType.java
@@ -0,0 +1,140 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
+import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
+import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.SameAsBound;
+
+import java.util.List;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isInferenceVariable;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+
+/**
+ * A type S is the same as a type T (§4.3.4), or a type argument S is the same as type argument T
+ *
+ * @author Federico Tomassetti
+ */
+public class TypeSameAsType extends ConstraintFormula {
+    private ResolvedType S;
+    private ResolvedType T;
+
+    public TypeSameAsType(ResolvedType s, ResolvedType t) {
+        S = s;
+        T = t;
+    }
+
+    @Override
+    public ReductionResult reduce(BoundSet currentBoundSet) {
+        // A constraint formula of the form ‹S = T›, where S and T are types, is reduced as follows:
+
+        if (!S.isWildcard() && !T.isWildcard()) {
+
+            // - If S and T are proper types, the constraint reduces to true if S is the same as T (§4.3.4), and false
+            //   otherwise.
+
+            if (isProperType(S) && isProperType(T)) {
+                if (S.equals(T)) {
+                    return ReductionResult.trueResult();
+                } else {
+                    return ReductionResult.falseResult();
+                }
+            }
+
+            // - Otherwise, if S or T is the null type, the constraint reduces to false.
+
+            if (S.isNull() || T.isNull()) {
+                return ReductionResult.falseResult();
+            }
+
+            // - Otherwise, if S is an inference variable, α, and T is not a primitive type, the constraint reduces to the
+            //   bound α = T.
+
+            if (isInferenceVariable(S) && !T.isPrimitive()) {
+                return ReductionResult.oneBound(new SameAsBound(S, T));
+            }
+
+            // - Otherwise, if T is an inference variable, α, and S is not a primitive type, the constraint reduces to the
+            //   bound S = α.
+
+            if (isInferenceVariable(T) && !S.isPrimitive()) {
+                return ReductionResult.oneBound(new SameAsBound(S, T));
+            }
+
+            // - Otherwise, if S and T are class or interface types with the same erasure, where S has
+            //   type arguments B1, ..., Bn and T has type arguments A1, ..., An, the constraint reduces to the following
+            //   new constraints: for all i (1 ≤ i ≤ n), ‹Bi = Ai›.
+
+            if (S.isReferenceType() && T.isReferenceType()
+                    && S.asReferenceType().toRawType().equals(T.asReferenceType().toRawType())) {
+                ReductionResult res = ReductionResult.empty();
+                List<ResolvedType> Bs = S.asReferenceType().typeParametersValues();
+                List<ResolvedType> As = T.asReferenceType().typeParametersValues();
+                for (int i = 0; i < Bs.size(); i++) {
+                    res = res.withConstraint(new TypeSameAsType(Bs.get(i), As.get(i)));
+                }
+                return res;
+            }
+
+            // - Otherwise, if S and T are array types, S'[] and T'[], the constraint reduces to ‹S' = T'›.
+
+            if (S.isArray() && T.isArray()) {
+                return ReductionResult.oneConstraint(new TypeSameAsType(
+                        S.asArrayType().getComponentType(),
+                        T.asArrayType().getComponentType()));
+            }
+
+            // - Otherwise, the constraint reduces to false.
+
+            return ReductionResult.falseResult();
+        }
+
+        // Note that we do not address intersection types above, because it is impossible for reduction to encounter an
+        // intersection type that is not a proper type.
+
+        // A constraint formula of the form ‹S = T›, where S and T are type arguments (§4.5.1), is reduced as follows:
+        //
+        // - If S and T are types, the constraint is reduced as described above.
+        //
+        // - If S has the form ? and T has the form ?, the constraint reduces to true.
+        //
+        // - If S has the form ? and T has the form ? extends T', the constraint reduces to ‹Object = T'›.
+        //
+        // - If S has the form ? extends S' and T has the form ?, the constraint reduces to ‹S' = Object›.
+        //
+        // - If S has the form ? extends S' and T has the form ? extends T', the constraint reduces to ‹S' = T'›.
+        //
+        // - If S has the form ? super S' and T has the form ? super T', the constraint reduces to ‹S' = T'›.
+        //
+        // - Otherwise, the constraint reduces to false.
+
+
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        TypeSameAsType that = (TypeSameAsType) o;
+
+        if (!S.equals(that.S)) return false;
+        return T.equals(that.T);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = S.hashCode();
+        result = 31 * result + T.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "TypeSameAsType{" +
+                "S=" + S +
+                ", T=" + T +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeSubtypeOfType.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeSubtypeOfType.java
new file mode 100644
index 0000000..6bc7fdc
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/TypeSubtypeOfType.java
@@ -0,0 +1,139 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.resolution.types.ResolvedIntersectionType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.NullType;
+import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
+import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
+import com.github.javaparser.symbolsolver.resolution.typeinference.bounds.SubtypeOfBound;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isInferenceVariable;
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+
+/**
+ * A reference type S is a subtype of a reference type T
+ *
+ * @author Federico Tomassetti
+ */
+public class TypeSubtypeOfType extends ConstraintFormula {
+    private ResolvedType S;
+    private ResolvedType T;
+    private TypeSolver typeSolver;
+
+    public TypeSubtypeOfType(TypeSolver typeSolver, ResolvedType S, ResolvedType T) {
+        this.typeSolver = typeSolver;
+        this.S = S;
+        this.T = T;
+    }
+
+    @Override
+    public ReductionResult reduce(BoundSet currentBoundSet) {
+        // A constraint formula of the form ‹S <: T› is reduced as follows:
+        //
+        // - If S and T are proper types, the constraint reduces to true if S is a subtype of T (§4.10), and false otherwise.
+
+        if (isProperType(S) && isProperType(T)) {
+            if (T.isAssignableBy(S)) {
+                return ReductionResult.trueResult();
+            } else {
+                return ReductionResult.falseResult();
+            }
+        }
+
+        // - Otherwise, if S is the null type, the constraint reduces to true.
+
+        if (S instanceof NullType) {
+            return ReductionResult.trueResult();
+        }
+
+        // - Otherwise, if T is the null type, the constraint reduces to false.
+
+        if (T instanceof NullType) {
+            return ReductionResult.falseResult();
+        }
+
+        // - Otherwise, if S is an inference variable, α, the constraint reduces to the bound α <: T.
+
+        if (isInferenceVariable(S)) {
+            return ReductionResult.oneBound(new SubtypeOfBound(S, T));
+        }
+
+        // - Otherwise, if T is an inference variable, α, the constraint reduces to the bound S <: α.
+
+        if (isInferenceVariable(T)) {
+            return ReductionResult.oneBound(new SubtypeOfBound(S, T));
+        }
+
+        // FEDERICO - Added start
+        //if (T.isTypeVariable()) {
+        //    return ReductionResult.oneBound(new SubtypeOfBound(S, T));
+        //}
+        // FEDERICO - Added end
+
+        // - Otherwise, the constraint is reduced according to the form of T:
+        //
+        //   - If T is a parameterized class or interface type, or an inner class type of a parameterized class or interface type (directly or indirectly), let A1, ..., An be the type arguments of T. Among the supertypes of S, a corresponding class or interface type is identified, with type arguments B1, ..., Bn. If no such type exists, the constraint reduces to false. Otherwise, the constraint reduces to the following new constraints: for all i (1 ≤ i ≤ n), ‹Bi <= Ai›.
+        //
+        //   - If T is any other class or interface type, then the constraint reduces to true if T is among the supertypes of S, and false otherwise.
+        //
+        //   - If T is an array type, T'[], then among the supertypes of S that are array types, a most specific type is identified, S'[] (this may be S itself). If no such array type exists, the constraint reduces to false. Otherwise:
+        //
+        //     - If neither S' nor T' is a primitive type, the constraint reduces to ‹S' <: T'›.
+        //
+        //     - Otherwise, the constraint reduces to true if S' and T' are the same primitive type, and false otherwise.
+        //
+        //   - If T is a type variable, there are three cases:
+
+        if (T.isTypeVariable()) {
+
+            //     - If S is an intersection type of which T is an element, the constraint reduces to true.
+
+            if (S instanceof ResolvedIntersectionType) {
+                throw new UnsupportedOperationException();
+            }
+
+            //     - Otherwise, if T has a lower bound, B, the constraint reduces to ‹S <: B›.
+
+            if (T.asTypeVariable().asTypeParameter().hasLowerBound()) {
+                return ReductionResult.oneConstraint(new TypeSubtypeOfType(typeSolver, S, T.asTypeVariable().asTypeParameter().getLowerBound()));
+            }
+
+            //     - Otherwise, the constraint reduces to false.
+
+            return ReductionResult.falseResult();
+        }
+
+        //
+        //   - If T is an intersection type, I1 & ... & In, the constraint reduces to the following new constraints: for all i (1 ≤ i ≤ n), ‹S <: Ii›.
+        //
+
+        throw new UnsupportedOperationException("S = "+ S + ", T = " + T);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        TypeSubtypeOfType that = (TypeSubtypeOfType) o;
+
+        if (!S.equals(that.S)) return false;
+        return T.equals(that.T);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = S.hashCode();
+        result = 31 * result + T.hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "TypeSubtypeOfType{" +
+                "S=" + S +
+                ", T=" + T +
+                '}';
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolver.java
new file mode 100644
index 0000000..0811ef1
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolver.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class AarTypeSolver implements TypeSolver {
+
+    private TypeSolver parent;
+    private File aarFile;
+    private JarTypeSolver delegate;
+
+    public AarTypeSolver(File aarFile) throws IOException {
+        this.aarFile = aarFile;
+
+        JarFile jarFile = new JarFile(aarFile);
+        ZipEntry classesJarEntry = jarFile.getEntry("classes.jar");
+        if (classesJarEntry == null) {
+            throw new IllegalArgumentException(String.format("The given file (%s) is malformed: entry classes.jar was not found", aarFile.getAbsolutePath()));
+        }
+        delegate = new JarTypeSolver(jarFile.getInputStream(classesJarEntry));
+    }
+
+    @Override
+    public TypeSolver getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(TypeSolver parent) {
+        this.parent = parent;
+    }
+
+    @Override
+    public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+        return delegate.tryToSolveType(name);
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java
new file mode 100644
index 0000000..fe9f375
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class CombinedTypeSolver implements TypeSolver {
+
+    private TypeSolver parent;
+    private List<TypeSolver> elements = new ArrayList<>();
+
+    public CombinedTypeSolver(TypeSolver... elements) {
+        for (TypeSolver el : elements) {
+            add(el);
+        }
+    }
+
+    @Override
+    public TypeSolver getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(TypeSolver parent) {
+        this.parent = parent;
+    }
+
+    public void add(TypeSolver typeSolver) {
+        this.elements.add(typeSolver);
+        typeSolver.setParent(this);
+    }
+
+    @Override
+    public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+        for (TypeSolver ts : elements) {
+            SymbolReference<ResolvedReferenceTypeDeclaration> res = ts.tryToSolveType(name);
+            if (res.isSolved()) {
+                return res;
+            }
+        }
+        return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration solveType(String name) throws UnsolvedSymbolException {
+        SymbolReference<ResolvedReferenceTypeDeclaration> res = tryToSolveType(name);
+        if (res.isSolved()) {
+            return res.getCorrespondingDeclaration();
+        } else {
+            throw new UnsolvedSymbolException(name);
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java
new file mode 100644
index 0000000..9ce9cbb
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.NotFoundException;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JarTypeSolver implements TypeSolver {
+
+    private static JarTypeSolver instance;
+
+    private TypeSolver parent;
+    private Map<String, ClasspathElement> classpathElements = new HashMap<>();
+    private ClassPool classPool = new ClassPool(false);
+
+    public JarTypeSolver(String pathToJar) throws IOException {
+        addPathToJar(pathToJar);
+    }
+
+    public JarTypeSolver(InputStream jarInputStream) throws IOException {
+        addPathToJar(jarInputStream);
+    }
+
+    public static JarTypeSolver getJarTypeSolver(String pathToJar) throws IOException {
+        if (instance == null) {
+            instance = new JarTypeSolver(pathToJar);
+        } else {
+            instance.addPathToJar(pathToJar);
+        }
+        return instance;
+    }
+
+    private File dumpToTempFile(InputStream inputStream) throws IOException {
+        File tempFile = File.createTempFile("jar_file_from_input_stream", ".jar");
+        tempFile.deleteOnExit();
+
+        byte[] buffer = new byte[8 * 1024];
+
+        try {
+            OutputStream output = new FileOutputStream(tempFile);
+            try {
+                int bytesRead;
+                while ((bytesRead = inputStream.read(buffer)) != -1) {
+                    output.write(buffer, 0, bytesRead);
+                }
+            } finally {
+                output.close();
+            }
+        } finally {
+            inputStream.close();
+        }
+        return tempFile;
+    }
+
+    private void addPathToJar(InputStream jarInputStream) throws IOException {
+        addPathToJar(dumpToTempFile(jarInputStream).getAbsolutePath());
+    }
+
+    private void addPathToJar(String pathToJar) throws IOException {
+        try {
+            classPool.appendClassPath(pathToJar);
+            classPool.appendSystemPath();
+        } catch (NotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        JarFile jarFile = new JarFile(pathToJar);
+        JarEntry entry = null;
+        Enumeration<JarEntry> e = jarFile.entries();
+        while (e.hasMoreElements()) {
+            entry = e.nextElement();
+            if (entry != null && !entry.isDirectory() && entry.getName().endsWith(".class")) {
+                String name = entryPathToClassName(entry.getName());
+                classpathElements.put(name, new ClasspathElement(jarFile, entry, name));
+            }
+        }
+    }
+
+    @Override
+    public TypeSolver getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(TypeSolver parent) {
+        this.parent = parent;
+    }
+
+    private String entryPathToClassName(String entryPath) {
+        if (!entryPath.endsWith(".class")) {
+            throw new IllegalStateException();
+        }
+        String className = entryPath.substring(0, entryPath.length() - ".class".length());
+        className = className.replace('/', '.');
+        className = className.replace('$', '.');
+        return className;
+    }
+
+    @Override
+    public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+        try {
+            if (classpathElements.containsKey(name)) {
+                return SymbolReference.solved(
+                        JavassistFactory.toTypeDeclaration(classpathElements.get(name).toCtClass(), getRoot()));
+            } else {
+                return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public ResolvedReferenceTypeDeclaration solveType(String name) throws UnsolvedSymbolException {
+        SymbolReference<ResolvedReferenceTypeDeclaration> ref = tryToSolveType(name);
+        if (ref.isSolved()) {
+            return ref.getCorrespondingDeclaration();
+        } else {
+            throw new UnsolvedSymbolException(name);
+        }
+    }
+
+    private class ClasspathElement {
+        private JarFile jarFile;
+        private JarEntry entry;
+        private String path;
+
+        ClasspathElement(JarFile jarFile, JarEntry entry, String path) {
+            this.jarFile = jarFile;
+            this.entry = entry;
+            this.path = path;
+        }
+
+        CtClass toCtClass() throws IOException {
+            try (InputStream is = jarFile.getInputStream(entry)) {
+                return classPool.makeClass(is);
+            }
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
new file mode 100644
index 0000000..17e335e
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class JavaParserTypeSolver implements TypeSolver {
+
+    private File srcDir;
+
+    private TypeSolver parent;
+
+    private Cache<String, Optional<CompilationUnit>> parsedFiles = CacheBuilder.newBuilder().softValues().build();
+    private Cache<String, List<CompilationUnit>> parsedDirectories = CacheBuilder.newBuilder().softValues().build();
+    private Cache<String, SymbolReference<ResolvedReferenceTypeDeclaration>> foundTypes = CacheBuilder.newBuilder().softValues().build();
+
+    public JavaParserTypeSolver(File srcDir) {
+        if (!srcDir.exists() || !srcDir.isDirectory()) {
+            throw new IllegalStateException("SrcDir does not exist or is not a directory: " + srcDir.getAbsolutePath());
+        }
+        this.srcDir = srcDir;
+    }
+
+    @Override
+    public String toString() {
+        return "JavaParserTypeSolver{" +
+                "srcDir=" + srcDir +
+                ", parent=" + parent +
+                '}';
+    }
+
+    @Override
+    public TypeSolver getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(TypeSolver parent) {
+        this.parent = parent;
+    }
+
+
+    private Optional<CompilationUnit> parse(File srcFile) {
+        try {
+            return parsedFiles.get(srcFile.getAbsolutePath(), () -> {
+                Optional<CompilationUnit> cu;
+                try {
+                    cu = Optional.of(JavaParser.parse(srcFile));
+                } catch (FileNotFoundException e) {
+                    cu = Optional.empty();
+                } catch (RuntimeException e) {
+                    throw new RuntimeException("Issue while parsing " + srcFile.getAbsolutePath(), e);
+                }
+                return cu;
+            });
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private List<CompilationUnit> parseDirectory(File srcDirectory) {
+        try {
+            return parsedDirectories.get(srcDirectory.getAbsolutePath(), () -> {
+                List<CompilationUnit> units = new ArrayList<>();
+                File[] files = srcDirectory.listFiles();
+                if (files != null) {
+                    for (File file : files) {
+                        if (file.getName().toLowerCase().endsWith(".java")) {
+                            Optional<CompilationUnit> unit = parse(file);
+                            if (unit.isPresent()) {
+                                units.add(unit.get());
+                            }
+                        }
+                    }
+                }
+                return units;
+            });
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+        // TODO support enums
+        // TODO support interfaces
+        try {
+            return foundTypes.get(name, () -> {
+                SymbolReference<ResolvedReferenceTypeDeclaration> result = tryToSolveTypeUncached(name);
+                if (result.isSolved()) {
+                    return SymbolReference.solved(result.getCorrespondingDeclaration());
+                }
+                return result;
+            });
+        } catch (ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveTypeUncached(String name) {
+        String[] nameElements = name.split("\\.");
+
+        for (int i = nameElements.length; i > 0; i--) {
+            String filePath = srcDir.getAbsolutePath();
+            for (int j = 0; j < i; j++) {
+                filePath += "/" + nameElements[j];
+            }
+            filePath += ".java";
+
+            String typeName = "";
+            for (int j = i - 1; j < nameElements.length; j++) {
+                if (j != i - 1) {
+                    typeName += ".";
+                }
+                typeName += nameElements[j];
+            }
+
+            File srcFile = new File(filePath);
+            {
+                Optional<CompilationUnit> compilationUnit = parse(srcFile);
+                if (compilationUnit.isPresent()) {
+                    Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator.findType(compilationUnit.get(), typeName);
+                    if (astTypeDeclaration.isPresent()) {
+                        return SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
+                    }
+                }
+            }
+
+            {
+                List<CompilationUnit> compilationUnits = parseDirectory(srcFile.getParentFile());
+                for (CompilationUnit compilationUnit : compilationUnits) {
+                    Optional<com.github.javaparser.ast.body.TypeDeclaration<?>> astTypeDeclaration = Navigator.findType(compilationUnit, typeName);
+                    if (astTypeDeclaration.isPresent()) {
+                        return SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()));
+                    }
+                }
+            }
+        }
+
+        return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java
new file mode 100644
index 0000000..2595c6d
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A TypeSolver which only consider the TypeDeclarations provided to it.
+ *
+ * @author Federico Tomassetti
+ */
+public class MemoryTypeSolver implements TypeSolver {
+
+    private TypeSolver parent;
+    private Map<String, ResolvedReferenceTypeDeclaration> declarationMap = new HashMap<>();
+
+    @Override
+    public String toString() {
+        return "MemoryTypeSolver{" +
+                "parent=" + parent +
+                ", declarationMap=" + declarationMap +
+                '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof MemoryTypeSolver)) return false;
+
+        MemoryTypeSolver that = (MemoryTypeSolver) o;
+
+        if (parent != null ? !parent.equals(that.parent) : that.parent != null) return false;
+        return !(declarationMap != null ? !declarationMap.equals(that.declarationMap) : that.declarationMap != null);
+
+    }
+
+    @Override
+    public int hashCode() {
+        int result = parent != null ? parent.hashCode() : 0;
+        result = 31 * result + (declarationMap != null ? declarationMap.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public TypeSolver getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(TypeSolver parent) {
+        this.parent = parent;
+    }
+
+    public void addDeclaration(String name, ResolvedReferenceTypeDeclaration typeDeclaration) {
+        this.declarationMap.put(name, typeDeclaration);
+    }
+
+    @Override
+    public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+        if (declarationMap.containsKey(name)) {
+            return SymbolReference.solved(declarationMap.get(name));
+        } else {
+            return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+        }
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java
new file mode 100644
index 0000000..8e05473
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory;
+
+import java.util.Optional;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ReflectionTypeSolver implements TypeSolver {
+
+    private TypeSolver parent;
+
+    public ReflectionTypeSolver(boolean jreOnly) {
+        this.jreOnly = jreOnly;
+    }
+
+    public ReflectionTypeSolver() {
+        this(true);
+    }
+
+    private boolean jreOnly;
+
+    @Override
+    public TypeSolver getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(TypeSolver parent) {
+        this.parent = parent;
+    }
+
+    @Override
+    public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+        if (!jreOnly || (name.startsWith("java.") || name.startsWith("javax."))) {
+            try {
+                ClassLoader classLoader = ReflectionTypeSolver.class.getClassLoader();
+
+                // Some implementations could return null when the class was loaded through the bootstrap classloader
+                // see https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getClassLoader--
+                if (classLoader == null) {
+                    throw new RuntimeException("The ReflectionTypeSolver has been probably loaded through the bootstrap class loader. This usage is not supported by the JavaSymbolSolver");
+                }
+
+                Class<?> clazz = classLoader.loadClass(name);
+                return SymbolReference.solved(ReflectionFactory.typeDeclarationFor(clazz, getRoot()));
+            } catch (ClassNotFoundException e) {
+                // it could be an inner class
+                int lastDot = name.lastIndexOf('.');
+                if (lastDot == -1) {
+                    return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+                } else {
+                    String parentName = name.substring(0, lastDot);
+                    String childName = name.substring(lastDot + 1);
+                    SymbolReference<ResolvedReferenceTypeDeclaration> parent = tryToSolveType(parentName);
+                    if (parent.isSolved()) {
+                        Optional<ResolvedReferenceTypeDeclaration> innerClass = parent.getCorrespondingDeclaration().internalTypes()
+                                .stream().filter(it -> it.getName().equals(childName)).findFirst();
+                        if (innerClass.isPresent()) {
+                            return SymbolReference.solved(innerClass.get());
+                        } else {
+                            return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+                        }
+                    } else {
+                        return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+                    }
+                }
+            }
+        } else {
+            return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+        }
+    }
+
+}
diff --git a/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverQuickSetup.java b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverQuickSetup.java
new file mode 100644
index 0000000..e6d3d53
--- /dev/null
+++ b/javaparser-symbol-solver-core/src/main/java/com/github/javaparser/symbolsolver/utils/SymbolSolverQuickSetup.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2018 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.symbolsolver.utils;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseProblemException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.github.javaparser.utils.Log;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.nio.file.FileVisitResult.*;
+
+/**
+ * Utility class to add all jars and roots of java files of the provided path to a TypeSolver instance.
+ * It traverses the file directory tree and adds all files ending in either .java or .jar.
+ */
+public class SymbolSolverQuickSetup {
+
+    public interface DirFilter {
+        boolean filter(Path path);
+    }
+
+    private final Path root;
+    private CombinedTypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(false));
+    private DirFilter dirFilter = path -> false;
+
+    public SymbolSolverQuickSetup(Path root) {
+        assertNotNull(root);
+        if (!Files.isDirectory(root)) {
+            throw new IllegalArgumentException("Only directories are allowed as root path!");
+        }
+        this.root = root.normalize();
+        Log.info("New symbol source root at \"%s\"", this.root);
+    }
+
+    public SymbolSolverQuickSetup(Path root, DirFilter dirFilter) {
+        this(root);
+        this.dirFilter = dirFilter;
+    }
+
+    public TypeSolver walk() throws IOException {
+        Files.walkFileTree(root, new JavaSymbolSolverWalker());
+        Files.walkFileTree(root, new JarVisitor());
+        return typeSolver;
+    }
+
+    public Optional<TypeSolver> tryToWalk() {
+        try {
+            return Optional.of(walk());
+        } catch (IOException e) {
+            Log.error(e, "Unable to walk root " + root);
+            return Optional.empty();
+        }
+    }
+
+    public TypeSolver getTypeSolver() {
+        return typeSolver;
+    }
+
+    /**
+     * The path that was passed in the constructor.
+     */
+    public Path getRoot() {
+        return root;
+    }
+
+    /**
+     * Walks the directory and adds the roots of the java files to the TypeSolver
+     */
+    private class JavaSymbolSolverWalker extends SimpleFileVisitor<Path> {
+
+        private final Set<Path> roots = new HashSet<>();
+
+        @Override
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attr) throws FileNotFoundException {
+            if (attr.isRegularFile()) {
+                PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
+                if (matcher.matches(file)) {
+                    try {
+                        Optional<Path> root = JavaParser.parse(file.toFile()).getStorage()
+                                .map(CompilationUnit.Storage::getSourceRoot);
+                        if (root.isPresent()) {
+                            typeSolver.add(new JavaParserTypeSolver(root.get().toFile()));
+                            if (roots.add(root.get())) {
+                                Log.trace("Added dir " + root.get() + " to the TypeSolver");
+                                return SKIP_SIBLINGS;
+                            }
+                        }
+                    } catch (ParseProblemException e) {
+                        Log.error(e, "Unable to parse file " + file);
+                    }
+                }
+            }
+            return CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
+            if (Files.isHidden(dir) || dirFilter.filter(dir) || roots.stream().anyMatch(dir::startsWith)) {
+                return SKIP_SUBTREE;
+            }
+            return CONTINUE;
+        }
+    }
+
+    private class JarVisitor extends SimpleFileVisitor<Path> {
+
+        @Override
+        public FileVisitResult visitFile(Path file, BasicFileAttributes attr) throws IOException {
+            if (attr.isRegularFile()) {
+                PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.jar");
+                if (matcher.matches(file)) {
+                    typeSolver.add(new JarTypeSolver(file.toString()));
+                }
+            }
+            return CONTINUE;
+        }
+    }
+}
+
diff --git a/javaparser-symbol-solver-logic/.gitignore b/javaparser-symbol-solver-logic/.gitignore
new file mode 100644
index 0000000..8f22fa7
--- /dev/null
+++ b/javaparser-symbol-solver-logic/.gitignore
@@ -0,0 +1,4 @@
+build
+/.classpath
+/.project
+.settings
diff --git a/javaparser-symbol-solver-logic/javaparser-symbol-solver-logic.iml b/javaparser-symbol-solver-logic/javaparser-symbol-solver-logic.iml
new file mode 100644
index 0000000..2a2531a
--- /dev/null
+++ b/javaparser-symbol-solver-logic/javaparser-symbol-solver-logic.iml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Maven: org.javassist:javassist:3.22.0-GA" level="project" />
+    <orderEntry type="module" module-name="javaparser-symbol-solver-model" />
+    <orderEntry type="module" module-name="javaparser-core" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:23.4-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.0.18" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-symbol-solver-logic/pom.xml b/javaparser-symbol-solver-logic/pom.xml
new file mode 100644
index 0000000..25b7856
--- /dev/null
+++ b/javaparser-symbol-solver-logic/pom.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>javaparser-parent</artifactId>
+        <groupId>com.github.javaparser</groupId>
+        <version>3.5.16-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-symbol-solver-logic</artifactId>
+    <packaging>jar</packaging>
+    <description>A Symbol Solver for Java, built on top of JavaParser (logic)</description>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
+            <distribution>repo</distribution>
+        </license>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <build.timestamp>${maven.build.timestamp}</build.timestamp>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-symbol-solver-model</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>animal-sniffer-maven-plugin</artifactId>
+                <version>1.16</version>
+                <configuration>
+                    <signature>
+                        <!-- Make sure only the API of this JDK is used -->
+                        <groupId>org.codehaus.mojo.signature</groupId>
+                        <artifactId>java18</artifactId>
+                        <version>1.0</version>
+                    </signature>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>animal-sniffer</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <version>3.0.0-M1</version>
+                <executions>
+                    <execution>
+                        <id>enforce-versions</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <!-- Make sure a compiler of this version is used -->
+                                    <version>${java.version}</version>
+                                </requireJavaVersion>
+                                <enforceBytecodeVersion>
+                                    <!-- Make sure the dependencies are compiled for our Java version -->
+                                    <maxJdkVersion>${java.version}</maxJdkVersion>
+                                </enforceBytecodeVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>extra-enforcer-rules</artifactId>
+                        <version>1.0-beta-6</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <!-- Set JPMS module name -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Automatic-Module-Name>com.github.javaparser.symbolsolver.logic</Automatic-Module-Name>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java
new file mode 100644
index 0000000..1f770e7
--- /dev/null
+++ b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A common ancestor for all ClassDeclarations.
+ *
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractClassDeclaration extends AbstractTypeDeclaration implements ResolvedClassDeclaration {
+
+    ///
+    /// Public
+    ///
+
+    @Override
+    public boolean hasName() {
+        return getQualifiedName() != null;
+    }
+
+    @Override
+    public final List<ResolvedReferenceType> getAllSuperClasses() {
+        List<ResolvedReferenceType> superclasses = new ArrayList<>();
+        ResolvedReferenceType superClass = getSuperClass();
+        if (superClass != null) {
+            superclasses.add(superClass);
+            superclasses.addAll(superClass.getAllClassesAncestors());
+        }
+
+        if (superclasses.removeIf(s -> s.getQualifiedName().equals(Object.class.getCanonicalName()))) {
+            superclasses.add(object());
+        }
+        return superclasses;
+    }
+
+    @Override
+    public final List<ResolvedReferenceType> getAllInterfaces() {
+        List<ResolvedReferenceType> interfaces = new ArrayList<>();
+        for (ResolvedReferenceType interfaceDeclaration : getInterfaces()) {
+            interfaces.add(interfaceDeclaration);
+            interfaces.addAll(interfaceDeclaration.getAllInterfacesAncestors());
+        }
+        ResolvedReferenceType superClass = this.getSuperClass();
+        if (superClass != null) {
+            interfaces.addAll(superClass.getAllInterfacesAncestors());
+        }
+        return interfaces;
+    }
+
+    @Override
+    public final ResolvedClassDeclaration asClass() {
+        return this;
+    }
+
+    ///
+    /// Protected
+    ///
+
+    /**
+     * An implementation of the Object class.
+     */
+    protected abstract ResolvedReferenceType object();
+
+}
diff --git a/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java
new file mode 100644
index 0000000..b08ff1e
--- /dev/null
+++ b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Common ancestor for most types.
+ *
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractTypeDeclaration implements ResolvedReferenceTypeDeclaration {
+
+    @Override
+    public final Set<MethodUsage> getAllMethods() {
+        Set<MethodUsage> methods = new HashSet<>();
+
+        Set<String> methodsSignatures = new HashSet<>();
+
+        for (ResolvedMethodDeclaration methodDeclaration : getDeclaredMethods()) {
+            methods.add(new MethodUsage(methodDeclaration));
+            methodsSignatures.add(methodDeclaration.getSignature());
+        }
+
+        for (ResolvedReferenceType ancestor : getAllAncestors()) {
+            for (MethodUsage mu : ancestor.getDeclaredMethods()) {
+                String signature = mu.getDeclaration().getSignature();
+                if (!methodsSignatures.contains(signature)) {
+                    methodsSignatures.add(signature);
+                    methods.add(mu);
+                }
+            }
+        }
+
+        return methods;
+    }
+
+    @Override
+    public final boolean isFunctionalInterface() {
+        return FunctionalInterfaceLogic.getFunctionalMethod(this).isPresent();
+    }
+
+}
diff --git a/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java
new file mode 100644
index 0000000..684ffdb
--- /dev/null
+++ b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException.java
@@ -0,0 +1,13 @@
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ConfilictingGenericTypesException extends RuntimeException {
+
+    public ConfilictingGenericTypesException(ResolvedType formalType, ResolvedType actualType) {
+        super(String.format("No matching between %s (formal) and %s (actual)", formalType, actualType));
+    }
+}
diff --git a/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java
new file mode 100644
index 0000000..94ce18b
--- /dev/null
+++ b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public final class FunctionalInterfaceLogic {
+
+    private FunctionalInterfaceLogic() {
+        // prevent instantiation
+    }
+
+    /**
+     * Get the functional method defined by the type, if any.
+     */
+    public static Optional<MethodUsage> getFunctionalMethod(ResolvedType type) {
+        if (type.isReferenceType() && type.asReferenceType().getTypeDeclaration().isInterface()) {
+            return getFunctionalMethod(type.asReferenceType().getTypeDeclaration());
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    /**
+     * Get the functional method defined by the type, if any.
+     */
+    public static Optional<MethodUsage> getFunctionalMethod(ResolvedReferenceTypeDeclaration typeDeclaration) {
+        //We need to find all abstract methods
+        Set<MethodUsage> methods = typeDeclaration.getAllMethods().stream()
+                .filter(m -> m.getDeclaration().isAbstract())
+                // Remove methods inherited by Object:
+                // Consider the case of Comparator which define equals. It would be considered a functional method.
+                .filter(m -> !declaredOnObject(m))
+                .collect(Collectors.toSet());
+
+        if (methods.size() == 1) {
+            return Optional.of(methods.iterator().next());
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    public static boolean isFunctionalInterfaceType(ResolvedType type) {
+        return getFunctionalMethod(type).isPresent();
+    }
+
+    private static String getSignature(Method m) {
+        return String.format("%s(%s)", m.getName(), String.join(", ", Arrays.stream(m.getParameters()).map(p -> toSignature(p)).collect(Collectors.toList())));
+    }
+
+    private static String toSignature(Parameter p) {
+        return p.getType().getCanonicalName();
+    }
+
+    private static List<String> OBJECT_METHODS_SIGNATURES = Arrays.stream(Object.class.getDeclaredMethods())
+            .map(method -> getSignature(method))
+            .collect(Collectors.toList());
+
+    private static boolean declaredOnObject(MethodUsage m) {
+        return OBJECT_METHODS_SIGNATURES.contains(m.getDeclaration().getSignature());
+    }
+}
diff --git a/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceContext.java b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceContext.java
new file mode 100644
index 0000000..4d3df0f
--- /dev/null
+++ b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceContext.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.model.typesystem.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class InferenceContext {
+
+    private int nextInferenceVariableId = 0;
+    private ObjectProvider objectProvider;
+    private List<InferenceVariableType> inferenceVariableTypes = new ArrayList<>();
+
+    public InferenceContext(ObjectProvider objectProvider) {
+        this.objectProvider = objectProvider;
+    }
+
+    private Map<String, InferenceVariableType> inferenceVariableTypeMap = new HashMap<>();
+
+    private InferenceVariableType inferenceVariableTypeForTp(ResolvedTypeParameterDeclaration tp) {
+        if (!inferenceVariableTypeMap.containsKey(tp.getName())) {
+            InferenceVariableType inferenceVariableType = new InferenceVariableType(nextInferenceVariableId++, objectProvider);
+            inferenceVariableTypes.add(inferenceVariableType);
+            inferenceVariableType.setCorrespondingTp(tp);
+            inferenceVariableTypeMap.put(tp.getName(), inferenceVariableType);
+        }
+        return inferenceVariableTypeMap.get(tp.getName());
+    }
+
+    /**
+     *
+     * @return the actual with the inference variable inserted
+     */
+    public ResolvedType addPair(ResolvedType target, ResolvedType actual) {
+        target = placeInferenceVariables(target);
+        actual = placeInferenceVariables(actual);
+        registerCorrespondance(target, actual);
+        return target;
+    }
+
+    public ResolvedType addSingle(ResolvedType actual) {
+        return placeInferenceVariables(actual);
+    }
+
+    private void registerCorrespondance(ResolvedType formalType, ResolvedType actualType) {
+        if (formalType.isReferenceType() && actualType.isReferenceType()) {
+            ResolvedReferenceType formalTypeAsReference = formalType.asReferenceType();
+            ResolvedReferenceType actualTypeAsReference = actualType.asReferenceType();
+
+            if (!formalTypeAsReference.getQualifiedName().equals(actualTypeAsReference.getQualifiedName())) {
+                List<ResolvedReferenceType> ancestors = actualTypeAsReference.getAllAncestors();
+                final String formalParamTypeQName = formalTypeAsReference.getQualifiedName();
+                List<ResolvedType> correspondingFormalType = ancestors.stream().filter((a) -> a.getQualifiedName().equals(formalParamTypeQName)).collect(Collectors.toList());
+                if (correspondingFormalType.isEmpty()) {
+                    ancestors = formalTypeAsReference.getAllAncestors();
+                    final String actualParamTypeQname = actualTypeAsReference.getQualifiedName();
+                    List<ResolvedType> correspondingActualType = ancestors.stream().filter(a -> a.getQualifiedName().equals(actualParamTypeQname)).collect(Collectors.toList());
+                    if (correspondingActualType.isEmpty()){
+                        throw new ConfilictingGenericTypesException(formalType, actualType);
+                    }
+                    correspondingFormalType = correspondingActualType;
+
+                }
+                actualTypeAsReference = correspondingFormalType.get(0).asReferenceType();
+            }
+
+            if (formalTypeAsReference.getQualifiedName().equals(actualTypeAsReference.getQualifiedName())) {
+                if (!formalTypeAsReference.typeParametersValues().isEmpty()) {
+                    if (actualTypeAsReference.isRawType()) {
+                        // nothing to do
+                    } else {
+                        int i = 0;
+                        for (ResolvedType formalTypeParameter : formalTypeAsReference.typeParametersValues()) {
+                            registerCorrespondance(formalTypeParameter, actualTypeAsReference.typeParametersValues().get(i));
+                            i++;
+                        }
+                    }
+                }
+            }
+        } else if (formalType instanceof InferenceVariableType && !actualType.isPrimitive()) {
+            ((InferenceVariableType) formalType).registerEquivalentType(actualType);
+            if (actualType instanceof InferenceVariableType) {
+                ((InferenceVariableType) actualType).registerEquivalentType(formalType);
+            }
+        } else if (actualType.isNull()) {
+            // nothing to do
+        } else if (actualType.equals(formalType)) {
+            // nothing to do
+        } else if (actualType.isArray() && formalType.isArray()) {
+            registerCorrespondance(formalType.asArrayType().getComponentType(), actualType.asArrayType().getComponentType());
+        } else if (formalType.isWildcard()) {
+            // nothing to do
+            if ((actualType instanceof InferenceVariableType) && formalType.asWildcard().isBounded()) {
+                ((InferenceVariableType) actualType).registerEquivalentType(formalType.asWildcard().getBoundedType());
+                if (formalType.asWildcard().getBoundedType() instanceof InferenceVariableType) {
+                    ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualType);
+                }
+            }
+            if (actualType.isWildcard()) {
+                ResolvedWildcard formalWildcard = formalType.asWildcard();
+                ResolvedWildcard actualWildcard = actualType.asWildcard();
+                if (formalWildcard.isBounded() && formalWildcard.getBoundedType() instanceof InferenceVariableType) {
+                    if (formalWildcard.isSuper() && actualWildcard.isSuper()) {
+                        ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualWildcard.getBoundedType());
+                    } else if (formalWildcard.isExtends() && actualWildcard.isExtends()) {
+                        ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualWildcard.getBoundedType());
+                    }
+                }
+            }
+
+            if (actualType.isReferenceType()){
+                if (formalType.asWildcard().isBounded()){
+                    registerCorrespondance(formalType.asWildcard().getBoundedType(), actualType);
+                }
+            }
+        } else if (actualType instanceof InferenceVariableType){
+            if (formalType instanceof ResolvedReferenceType){
+                ((InferenceVariableType) actualType).registerEquivalentType(formalType);
+            } else if (formalType instanceof InferenceVariableType){
+                ((InferenceVariableType) actualType).registerEquivalentType(formalType);
+            }
+        } else if (actualType.isConstraint()){
+            ResolvedLambdaConstraintType constraintType = actualType.asConstraintType();
+            if (constraintType.getBound() instanceof InferenceVariableType){
+                ((InferenceVariableType) constraintType.getBound()).registerEquivalentType(formalType);
+            }
+        } else if (actualType.isPrimitive()) {
+            if (formalType.isPrimitive()) {
+                // nothing to do
+            } else {
+                registerCorrespondance(formalType, objectProvider.byName(actualType.asPrimitive().getBoxTypeQName()));
+            }
+        } else {
+            throw new UnsupportedOperationException(formalType.describe() + " " + actualType.describe());
+        }
+    }
+
+    private ResolvedType placeInferenceVariables(ResolvedType type) {
+        if (type.isWildcard()) {
+            if (type.asWildcard().isExtends()) {
+                return ResolvedWildcard.extendsBound(placeInferenceVariables(type.asWildcard().getBoundedType()));
+            } else if (type.asWildcard().isSuper()) {
+                return ResolvedWildcard.superBound(placeInferenceVariables(type.asWildcard().getBoundedType()));
+            } else {
+                return type;
+            }
+        } else if (type.isTypeVariable()) {
+            return inferenceVariableTypeForTp(type.asTypeParameter());
+        } else if (type.isReferenceType()) {
+            return type.asReferenceType().transformTypeParameters(tp -> placeInferenceVariables(tp));
+        } else if (type.isArray()) {
+            return new ResolvedArrayType(placeInferenceVariables(type.asArrayType().getComponentType()));
+        } else if (type.isNull() || type.isPrimitive() || type.isVoid()) {
+            return type;
+        } else if (type.isConstraint()){
+            return ResolvedLambdaConstraintType.bound(placeInferenceVariables(type.asConstraintType().getBound()));
+        } else if (type instanceof InferenceVariableType) {
+            return type;
+        } else {
+            throw new UnsupportedOperationException(type.describe());
+        }
+    }
+
+    public ResolvedType resolve(ResolvedType type) {
+        if (type instanceof InferenceVariableType) {
+            InferenceVariableType inferenceVariableType = (InferenceVariableType) type;
+            return inferenceVariableType.equivalentType();
+        } else if (type.isReferenceType()) {
+            return type.asReferenceType().transformTypeParameters(tp -> resolve(tp));
+        } else if (type.isNull() || type.isPrimitive() || type.isVoid()) {
+            return type;
+        } else if (type.isArray()) {
+            return new ResolvedArrayType(resolve(type.asArrayType().getComponentType()));
+        } else if (type.isWildcard()) {
+            if (type.asWildcard().isExtends()) {
+                return ResolvedWildcard.extendsBound(resolve(type.asWildcard().getBoundedType()));
+            } else if (type.asWildcard().isSuper()) {
+                return ResolvedWildcard.superBound(resolve(type.asWildcard().getBoundedType()));
+            } else {
+                return type;
+            }
+        } else {
+            throw new UnsupportedOperationException(type.describe());
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java
new file mode 100644
index 0000000..4d2e984
--- /dev/null
+++ b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/InferenceVariableType.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.resolution.types.ResolvedWildcard;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * An element using during type inference.
+ *
+ * @author Federico Tomassetti
+ */
+public class InferenceVariableType implements ResolvedType {
+    @Override
+    public String toString() {
+        return "InferenceVariableType{" +
+                "id=" + id +
+                '}';
+    }
+
+    private int id;
+    private ResolvedTypeParameterDeclaration correspondingTp;
+
+    public void setCorrespondingTp(ResolvedTypeParameterDeclaration correspondingTp) {
+        this.correspondingTp = correspondingTp;
+    }
+
+    private Set<ResolvedType> equivalentTypes = new HashSet<>();
+    private ObjectProvider objectProvider;
+
+    public void registerEquivalentType(ResolvedType type) {
+        this.equivalentTypes.add(type);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof InferenceVariableType)) return false;
+
+        InferenceVariableType that = (InferenceVariableType) o;
+
+        return id == that.id;
+
+    }
+
+    @Override
+    public int hashCode() {
+        return id;
+    }
+
+    private Set<ResolvedType> superTypes = new HashSet<>();
+
+    public InferenceVariableType(int id, ObjectProvider objectProvider) {
+        this.id = id;
+        this.objectProvider = objectProvider;
+    }
+
+    public static InferenceVariableType fromWildcard(ResolvedWildcard wildcard, int id, ObjectProvider objectProvider) {
+        InferenceVariableType inferenceVariableType = new InferenceVariableType(id, objectProvider);
+        if (wildcard.isExtends()) {
+            inferenceVariableType.superTypes.add(wildcard.getBoundedType());
+        }
+        if (wildcard.isSuper()) {
+            // I am not sure about this one...
+            inferenceVariableType.superTypes.add(wildcard.getBoundedType());
+        }
+        return inferenceVariableType;
+    }
+
+    @Override
+    public String describe() {
+        return "InferenceVariable_" + id;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        throw new UnsupportedOperationException();
+    }
+
+    private Set<ResolvedType> concreteEquivalentTypesAlsoIndirectly(Set<InferenceVariableType> considered, InferenceVariableType inferenceVariableType) {
+        considered.add(inferenceVariableType);
+        Set<ResolvedType> result = new HashSet<>();
+        result.addAll(inferenceVariableType.equivalentTypes.stream().filter(t -> !t.isTypeVariable() && !(t instanceof InferenceVariableType)).collect(Collectors.toSet()));
+        inferenceVariableType.equivalentTypes.stream().filter(t -> t instanceof InferenceVariableType).forEach(t -> {
+            InferenceVariableType ivt = (InferenceVariableType)t;
+            if (!considered.contains(ivt)) {
+                result.addAll(concreteEquivalentTypesAlsoIndirectly(considered, ivt));
+            }
+        });
+        return result;
+    }
+
+    public ResolvedType equivalentType() {
+        Set<ResolvedType> concreteEquivalent = concreteEquivalentTypesAlsoIndirectly(new HashSet<>(), this);
+        if (concreteEquivalent.isEmpty()) {
+            if (correspondingTp == null) {
+                return objectProvider.object();
+            } else {
+                return new ResolvedTypeVariable(correspondingTp);
+            }
+        }
+        if (concreteEquivalent.size() == 1) {
+            return concreteEquivalent.iterator().next();
+        }
+        Set<ResolvedType> notTypeVariables = equivalentTypes.stream()
+                                                    .filter(t -> !t.isTypeVariable() && !hasInferenceVariables(t))
+                                                    .collect(Collectors.toSet());
+        if (notTypeVariables.size() == 1) {
+            return notTypeVariables.iterator().next();
+        } else if (notTypeVariables.size() == 0 && !superTypes.isEmpty()) {
+            if (superTypes.size() == 1) {
+                return superTypes.iterator().next();
+            } else {
+                throw new IllegalStateException("Super types are: " + superTypes);
+            }
+        } else {
+            throw new IllegalStateException("Equivalent types are: " + equivalentTypes);
+        }
+    }
+
+    private boolean hasInferenceVariables(ResolvedType type){
+        if (type instanceof InferenceVariableType){
+            return true;
+        }
+
+        if (type.isReferenceType()){
+            ResolvedReferenceType refType = type.asReferenceType();
+            for (ResolvedType t : refType.typeParametersValues()){
+                if (hasInferenceVariables(t)){
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        if (type.isWildcard()){
+            ResolvedWildcard wildcardType = type.asWildcard();
+            return hasInferenceVariables(wildcardType.getBoundedType());
+        }
+
+        return false;
+    }
+}
diff --git a/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java
new file mode 100644
index 0000000..01b5c3c
--- /dev/null
+++ b/javaparser-symbol-solver-logic/src/main/java/com/github/javaparser/symbolsolver/logic/ObjectProvider.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+
+/**
+ * @author Federico Tomassetti
+ */
+public interface ObjectProvider {
+    ResolvedReferenceType object();
+    ResolvedReferenceType byName(String qname);
+}
diff --git a/javaparser-symbol-solver-model/.gitignore b/javaparser-symbol-solver-model/.gitignore
new file mode 100644
index 0000000..2c773c9
--- /dev/null
+++ b/javaparser-symbol-solver-model/.gitignore
@@ -0,0 +1,19 @@
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+.idea
+*.iml
+target
+build
+/.classpath
+/.project
+.settings
diff --git a/javaparser-symbol-solver-model/pom.xml b/javaparser-symbol-solver-model/pom.xml
new file mode 100644
index 0000000..fd824e3
--- /dev/null
+++ b/javaparser-symbol-solver-model/pom.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>javaparser-parent</artifactId>
+        <groupId>com.github.javaparser</groupId>
+        <version>3.5.16-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-symbol-solver-model</artifactId>
+    <packaging>jar</packaging>
+    <description>A Symbol Solver for Java, built on top of JavaParser (model)</description>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
+            <distribution>repo</distribution>
+        </license>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <build.timestamp>${maven.build.timestamp}</build.timestamp>
+    </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.github.javaparser</groupId>
+      <artifactId>javaparser-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.javassist</groupId>
+      <artifactId>javassist</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+  </dependencies>    
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>animal-sniffer-maven-plugin</artifactId>
+                <configuration>
+                    <signature>
+                        <!-- Make sure only the API of this JDK is used -->
+                        <groupId>org.codehaus.mojo.signature</groupId>
+                        <artifactId>java18</artifactId>
+                        <version>1.0</version>
+                    </signature>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>animal-sniffer</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>enforce-versions</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <!-- Make sure a compiler of this version is used -->
+                                    <version>${java.version}</version>
+                                </requireJavaVersion>
+                                <enforceBytecodeVersion>
+                                    <!-- Make sure the dependencies are compiled for our Java version -->
+                                    <maxJdkVersion>${java.version}</maxJdkVersion>
+                                </enforceBytecodeVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>extra-enforcer-rules</artifactId>
+                        <version>1.0-beta-6</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+            <!-- Set JPMS module name -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifestEntries>
+                            <Automatic-Module-Name>com.github.javaparser.symbolsolver.model</Automatic-Module-Name>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+
+
+</project>
diff --git a/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java
new file mode 100644
index 0000000..f454f8a
--- /dev/null
+++ b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/SymbolReference.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.resolution;
+
+import com.github.javaparser.resolution.declarations.ResolvedDeclaration;
+
+import java.util.Optional;
+
+/**
+ * A reference to a symbol. It can solved or not solved. If solved the corresponding
+ * declaration will be provided.
+ *
+ * @author Federico Tomassetti
+ */
+public class SymbolReference<S extends ResolvedDeclaration> {
+
+    private Optional<? extends S> correspondingDeclaration;
+
+    private SymbolReference(Optional<? extends S> correspondingDeclaration) {
+        this.correspondingDeclaration = correspondingDeclaration;
+    }
+
+    /**
+     * Create a solve reference to the given symbol.
+     */
+    public static <S extends ResolvedDeclaration, S2 extends S> SymbolReference<S> solved(S2 symbolDeclaration) {
+        return new SymbolReference<S>(Optional.of(symbolDeclaration));
+    }
+
+    /**
+     * Create an unsolved reference specifying the type of the value expected.
+     */
+    public static <S extends ResolvedDeclaration, S2 extends S> SymbolReference<S> unsolved(Class<S2> clazz) {
+        return new SymbolReference<>(Optional.empty());
+    }
+
+    @Override
+    public String toString() {
+        return "SymbolReference{" + correspondingDeclaration + "}";
+    }
+
+    /**
+     * The corresponding declaration. If not solve this throws UnsupportedOperationException.
+     */
+    public S getCorrespondingDeclaration() {
+        if (!isSolved()) {
+            throw new UnsupportedOperationException("CorrespondingDeclaration not available for unsolved symbol.");
+        }
+        return correspondingDeclaration.get();
+    }
+
+    /**
+     * Is the reference solved?
+     */
+    public boolean isSolved() {
+        return correspondingDeclaration.isPresent();
+    }
+
+    public static <O extends ResolvedDeclaration> SymbolReference<O> adapt(SymbolReference<? extends O> ref, Class<O> clazz) {
+        if (ref.isSolved()) {
+            return SymbolReference.solved(ref.getCorrespondingDeclaration());
+        } else {
+            return SymbolReference.unsolved(clazz);
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java
new file mode 100644
index 0000000..bfa43ae
--- /dev/null
+++ b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/TypeSolver.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.resolution;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * An element able to find TypeDeclaration from their name.
+ * TypeSolvers are organized in hierarchies.
+ *
+ * @author Federico Tomassetti
+ */
+public interface TypeSolver {
+
+    /**
+     * Get the root of the hierarchy of type solver.
+     */
+    default TypeSolver getRoot() {
+        if (getParent() == null) {
+            return this;
+        } else {
+            return getParent().getRoot();
+        }
+    }
+
+    /**
+     * Parent of the this TypeSolver. This can return null.
+     */
+    TypeSolver getParent();
+
+    /**
+     * Set the parent of this TypeSolver.
+     */
+    void setParent(TypeSolver parent);
+
+    /**
+     * Try to solve the type with the given name. It always return a SymbolReference which can be solved
+     * or unsolved.
+     */
+    SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name);
+
+    /**
+     * Solve the given type. Either the type is found and returned or an UnsolvedSymbolException is thrown.
+     */
+    default ResolvedReferenceTypeDeclaration solveType(String name) throws UnsolvedSymbolException {
+        SymbolReference<ResolvedReferenceTypeDeclaration> ref = tryToSolveType(name);
+        if (ref.isSolved()) {
+            return ref.getCorrespondingDeclaration();
+        } else {
+            throw new UnsolvedSymbolException(name, this.toString());
+        }
+    }
+
+}
diff --git a/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/Value.java b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/Value.java
new file mode 100644
index 0000000..3c5388e
--- /dev/null
+++ b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/resolution/Value.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.resolution;
+
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * Any type of value.
+ *
+ * @author Federico Tomassetti
+ */
+public class Value {
+    private ResolvedType type;
+    private String name;
+
+    public Value(ResolvedType type, String name) {
+        this.type = type;
+        this.name = name;
+    }
+
+    /**
+     * Create a Value from a ValueDeclaration.
+     */
+    public static Value from(ResolvedValueDeclaration decl) {
+        ResolvedType type = decl.getType();
+        return new Value(type, decl.getName());
+    }
+
+    @Override
+    public String toString() {
+        return "Value{" +
+                "typeUsage=" + type +
+                ", name='" + name + '\'' +
+                '}';
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public ResolvedType getType() {
+        return type;
+    }
+
+}
diff --git a/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/NullType.java b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/NullType.java
new file mode 100644
index 0000000..4fccfaa
--- /dev/null
+++ b/javaparser-symbol-solver-model/src/main/java/com/github/javaparser/symbolsolver/model/typesystem/NullType.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+
+/**
+ * This is a virtual type used to represent null values.
+ *
+ * @author Federico Tomassetti
+ */
+public class NullType implements ResolvedType {
+
+    public static final NullType INSTANCE = new NullType();
+
+    private NullType() {
+        // prevent instantiation
+    }
+
+    @Override
+    public boolean isArray() {
+        return false;
+    }
+
+    @Override
+    public boolean isPrimitive() {
+        return false;
+    }
+
+    public boolean isNull() {
+        return true;
+    }
+
+    @Override
+    public boolean isReferenceType() {
+        return false;
+    }
+
+    @Override
+    public String describe() {
+        return "null";
+    }
+
+    @Override
+    public boolean isTypeVariable() {
+        return false;
+    }
+
+    @Override
+    public boolean isAssignableBy(ResolvedType other) {
+        throw new UnsupportedOperationException("It does not make sense to assign a value to null, it can only be assigned");
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/.gitignore b/javaparser-symbol-solver-testing/.gitignore
new file mode 100644
index 0000000..b114bf5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/.gitignore
@@ -0,0 +1,5 @@
+target
+build
+/.classpath
+/.project
+.settings
diff --git a/javaparser-symbol-solver-testing/javaparser-symbol-solver-testing.iml b/javaparser-symbol-solver-testing/javaparser-symbol-solver-testing.iml
new file mode 100644
index 0000000..bf53f2c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/javaparser-symbol-solver-testing.iml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="module" module-name="javaparser-symbol-solver-logic" />
+    <orderEntry type="library" name="Maven: org.javassist:javassist:3.22.0-GA" level="project" />
+    <orderEntry type="library" name="Maven: com.google.guava:guava:23.4-jre" level="project" />
+    <orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
+    <orderEntry type="library" name="Maven: com.google.errorprone:error_prone_annotations:2.0.18" level="project" />
+    <orderEntry type="library" name="Maven: com.google.j2objc:j2objc-annotations:1.1" level="project" />
+    <orderEntry type="library" name="Maven: org.codehaus.mojo:animal-sniffer-annotations:1.14" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.13.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy:1.7.9" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.7.9" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
+    <orderEntry type="module" module-name="javaparser-symbol-solver-model" />
+    <orderEntry type="module" module-name="javaparser-core" />
+    <orderEntry type="module" module-name="javaparser-symbol-solver-core" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/pom.xml b/javaparser-symbol-solver-testing/pom.xml
new file mode 100644
index 0000000..6e042d2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/pom.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>javaparser-parent</artifactId>
+        <groupId>com.github.javaparser</groupId>
+        <version>3.5.16-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-symbol-solver-testing</artifactId>
+    <description>A Symbol Solver for Java, built on top of JavaParser (tests)</description>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
+            <distribution>repo</distribution>
+        </license>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <profiles>
+        <profile>
+            <id>NonSlowTests</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <excludedGroups>com.github.javaparser.SlowTest</excludedGroups>
+                            <parallel>methods</parallel>
+                            <threadCount>4</threadCount>
+                        </configuration>
+                    </plugin>
+                </plugins>
+
+            </build>
+        </profile>
+        <profile>
+            <id>AlsoSlowTests</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <parallel>methods</parallel>
+                            <threadCount>4</threadCount>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>jacoco-initialize</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>jacoco-site</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-resources</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <encoding>UTF-8</encoding>
+                            <outputDirectory>${basedir}/target/classes</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>../javaparser-core/target/classes</directory>
+                                    <filtering>false</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>unpack-test-jss-sources</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>com.github.javaparser</groupId>
+                                    <artifactId>java-symbol-solver-core</artifactId>
+                                    <version>0.6.0</version>
+                                    <classifier>sources</classifier>
+                                    <outputDirectory>
+                                        ${project.build.directory}/test-classes/javasymbolsolver_0_6_0/src/java-symbol-solver-core
+                                    </outputDirectory>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>com.github.javaparser</groupId>
+                                    <artifactId>java-symbol-solver-logic</artifactId>
+                                    <version>0.6.0</version>
+                                    <classifier>sources</classifier>
+                                    <outputDirectory>
+                                        ${project.build.directory}/test-classes/javasymbolsolver_0_6_0/src/java-symbol-solver-logic
+                                    </outputDirectory>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>com.github.javaparser</groupId>
+                                    <artifactId>java-symbol-solver-model</artifactId>
+                                    <version>0.6.0</version>
+                                    <classifier>sources</classifier>
+                                    <outputDirectory>
+                                        ${project.build.directory}/test-classes/javasymbolsolver_0_6_0/src/java-symbol-solver-model
+                                    </outputDirectory>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy-test-jss-libs</id>
+                        <phase>test-compile</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>com.google.guava</groupId>
+                                    <artifactId>guava</artifactId>
+                                    <version>21.0</version>
+                                    <outputDirectory>
+                                        ${project.build.directory}/test-classes/javasymbolsolver_0_6_0/lib
+                                    </outputDirectory>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>com.github.javaparser</groupId>
+                                    <artifactId>javaparser-core</artifactId>
+                                    <version>3.5.10</version>
+                                    <outputDirectory>
+                                        ${project.build.directory}/test-classes/javasymbolsolver_0_6_0/lib
+                                    </outputDirectory>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>io.javaslang</groupId>
+                                    <artifactId>javaslang</artifactId>
+                                    <version>2.0.3</version>
+                                    <outputDirectory>
+                                        ${project.build.directory}/test-classes/javasymbolsolver_0_6_0/lib
+                                    </outputDirectory>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.javassist</groupId>
+                                    <artifactId>javassist</artifactId>
+                                    <version>3.19.0-GA</version>
+                                    <outputDirectory>
+                                        ${project.build.directory}/test-classes/javasymbolsolver_0_6_0/lib
+                                    </outputDirectory>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <!-- no need to release this module -->
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-symbol-solver-logic</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-symbol-solver-model</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-symbol-solver-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/SlowTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/SlowTest.java
new file mode 100644
index 0000000..db79147
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/SlowTest.java
@@ -0,0 +1,7 @@
+package com.github.javaparser;
+
+/**
+ * Test category marker.
+ */
+public interface SlowTest {
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/resolution/types/ResolvedPrimitiveTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/resolution/types/ResolvedPrimitiveTypeTest.java
new file mode 100644
index 0000000..494b2b2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/resolution/types/ResolvedPrimitiveTypeTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.resolution.types;
+
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ResolvedPrimitiveTypeTest extends AbstractResolutionTest {
+
+    private String exampleOfSwitch(ResolvedPrimitiveType rpt) {
+        switch (rpt) {
+            case INT:
+                return "I";
+            case BYTE:
+                return "B";
+            case DOUBLE:
+                return "D";
+            default:
+                return "U";
+        }
+    }
+
+    @Test
+    public void tryTheSwitchStatement() {
+        assertEquals("U", exampleOfSwitch(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals("U", exampleOfSwitch(ResolvedPrimitiveType.CHAR));
+        assertEquals("B", exampleOfSwitch(ResolvedPrimitiveType.BYTE));
+        assertEquals("U", exampleOfSwitch(ResolvedPrimitiveType.SHORT));
+        assertEquals("I", exampleOfSwitch(ResolvedPrimitiveType.INT));
+        assertEquals("U", exampleOfSwitch(ResolvedPrimitiveType.LONG));
+        assertEquals("U", exampleOfSwitch(ResolvedPrimitiveType.FLOAT));
+        assertEquals("D", exampleOfSwitch(ResolvedPrimitiveType.DOUBLE));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/AbstractTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/AbstractTest.java
new file mode 100644
index 0000000..911211b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/AbstractTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import java.io.File;
+
+public abstract class AbstractTest {
+
+    protected static File adaptPath(File path) {
+        if (path.exists()) {
+            return path;
+        } else {
+            File underJavaParserCore = new File("javaparser-symbol-solver-testing/" + path.getPath());
+            if (underJavaParserCore.exists()) {
+                return underJavaParserCore;
+            } else {
+                throw new IllegalArgumentException("I cannot adapt the path " + path.getAbsolutePath());
+            }
+        }
+    }
+
+    protected static String adaptPath(String path) {
+        return adaptPath(new File(path)).getPath();
+    }
+
+    protected boolean isJava9() {
+        return System.getProperty("java.version").startsWith("9.");
+    }
+
+    protected boolean isJava8() {
+        return System.getProperty("java.version").startsWith("1.8.");
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/FindingAllFields.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/FindingAllFields.java
new file mode 100644
index 0000000..c0b70e9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/FindingAllFields.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Test;
+
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class FindingAllFields extends AbstractResolutionTest {
+
+    @Test
+    public void findAllInheritedFields() {
+        CompilationUnit cu = parseSample("AClassWithFields");
+        ClassOrInterfaceDeclaration classC = Navigator.demandClass(cu, "C");
+        ResolvedReferenceTypeDeclaration typeDeclaration = JavaParserFacade.get(new ReflectionTypeSolver()).getTypeDeclaration(classC);
+        assertEquals(3, typeDeclaration.getAllFields().size());
+        assertEquals(ImmutableSet.of("a", "b", "c"),
+                typeDeclaration.getAllFields().stream().map(ResolvedDeclaration::getName).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void findAllInheritedFieldsAndGenerics() {
+        CompilationUnit cu = parseSample("AClassWithFieldsAndGenerics");
+        ClassOrInterfaceDeclaration classC = Navigator.demandClass(cu, "C");
+        ResolvedReferenceTypeDeclaration typeDeclaration = JavaParserFacade.get(new ReflectionTypeSolver()).getTypeDeclaration(classC);
+        assertEquals(3, typeDeclaration.getAllFields().size());
+        assertEquals(ImmutableSet.of("a", "b", "c"),
+                typeDeclaration.getAllFields().stream().map(ResolvedDeclaration::getName).collect(Collectors.toSet()));
+        assertEquals("java.util.List<java.lang.String>", typeDeclaration.getField("b").getType().describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue113.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue113.java
new file mode 100644
index 0000000..e57a2e1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue113.java
@@ -0,0 +1,53 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue113 extends AbstractTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() throws IOException {
+        typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(adaptPath(new File("src/test/resources/issue113"))));
+    }
+
+    @Test
+    public void issue113providedCodeDoesNotCrash() throws FileNotFoundException {
+        String pathToSourceFile = adaptPath("src/test/resources/issue113/com/foo/Widget.java");
+        CompilationUnit cu = JavaParser.parse(new File(pathToSourceFile));
+
+        JavaParserFacade parserFacade = JavaParserFacade.get(typeSolver);
+        MethodDeclaration methodDeclaration = cu.findAll(MethodDeclaration.class).stream()
+                .filter(node -> node.getName().getIdentifier().equals("doSomething")).findAny().orElse(null);
+        methodDeclaration.findAll(MethodCallExpr.class).forEach(parserFacade::solve);
+    }
+
+    @Test
+    public void issue113superClassIsResolvedCorrectly() throws FileNotFoundException {
+        String pathToSourceFile = adaptPath("src/test/resources/issue113/com/foo/Widget.java");
+        CompilationUnit cu = JavaParser.parse(new File(pathToSourceFile));
+
+        JavaParserClassDeclaration jssExtendedWidget = new JavaParserClassDeclaration(cu.getClassByName("Widget").get(), typeSolver);
+        ResolvedReferenceType superClass = jssExtendedWidget.getSuperClass();
+        assertEquals("com.foo.base.Widget", superClass.getQualifiedName());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue116.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue116.java
new file mode 100644
index 0000000..d8d346d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue116.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue116 extends AbstractResolutionTest {
+
+    @Test
+    public void arrayTypeIsNotPartOfTheTree() {
+        CompilationUnit cu = parseSample("Issue116");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "JavaTest");
+        MethodDeclaration methodDeclaration = Navigator.demandMethod(clazz, "foo");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        com.github.javaparser.ast.type.Type typeNode = methodDeclaration.getParameters().get(0).getType();
+        ResolvedType type = javaParserFacade.convert(typeNode, typeNode);
+        assertEquals("java.lang.String[]", type.describe());
+
+        ExpressionStmt expressionStmt = (ExpressionStmt) methodDeclaration.getBody().get().getStatements().get(0);
+        Expression argRef = expressionStmt.getExpression();
+        assertEquals("java.lang.String[]", javaParserFacade.getType(argRef).describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue128.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue128.java
new file mode 100644
index 0000000..38f8b7c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue128.java
@@ -0,0 +1,50 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue128 extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() throws IOException {
+        File srcDir = adaptPath(new File("src/test/resources/issue128"));
+        typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(srcDir));
+    }
+
+    @Test
+    public void verifyJavaTestClassIsSolved() {
+        typeSolver.solveType("foo.JavaTest");
+    }
+
+    @Test
+    public void loopOnStaticallyImportedType() {
+        CompilationUnit cu = parseSampleWithStandardExtension("issue128/foo/Issue128");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "JavaTest");
+        ExpressionStmt expressionStmt = (ExpressionStmt)clazz.getMethodsByName("test").get(0).getBody().get().getStatement(0);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) expressionStmt.getExpression();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        assertEquals(false, javaParserFacade.solve(methodCallExpr).isSolved());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue1364.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue1364.java
new file mode 100644
index 0000000..67086b0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue1364.java
@@ -0,0 +1,91 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParseStart;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.Providers;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Dominik Hardtke
+ * @since 02.02.2018
+ */
+public class Issue1364 extends AbstractResolutionTest {
+    private JavaParser javaParser;
+
+    @Before
+    public void setup() {
+        ClassOrInterfaceDeclaration fakeObject = new ClassOrInterfaceDeclaration();
+        fakeObject.setName(new SimpleName("java.lang.Object"));
+
+        TypeSolver typeSolver = new TypeSolver() {
+            @Override
+            public TypeSolver getParent() {
+                return null;
+            }
+
+            @Override
+            public void setParent(TypeSolver parent) {
+            }
+
+            @Override
+            public SymbolReference<ResolvedReferenceTypeDeclaration> tryToSolveType(String name) {
+                if ("java.lang.Object".equals(name)) {
+                    // custom handling
+                    return SymbolReference.solved(new JavaParserClassDeclaration(fakeObject, this));
+                }
+
+                return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
+            }
+        };
+
+        ParserConfiguration config = new ParserConfiguration();
+        config.setSymbolResolver(new JavaSymbolSolver(typeSolver));
+        javaParser = new JavaParser(config);
+    }
+
+    @Test(timeout = 1000)
+    public void resolveSubClassOfObject() {
+        String code = String.join(System.lineSeparator(),
+                "package graph;",
+                "public class Vertex {",
+                "    public static void main(String[] args) {",
+                "        System.out.println();",
+                "    }",
+                "}"
+        );
+
+        ParseResult<CompilationUnit> parseResult = javaParser.parse(ParseStart.COMPILATION_UNIT, Providers.provider(code));
+        assertTrue(parseResult.isSuccessful());
+        assertTrue(parseResult.getResult().isPresent());
+
+        List<MethodCallExpr> methodCallExprs = parseResult.getResult().get().findAll(MethodCallExpr.class);
+        assertEquals(1, methodCallExprs.size());
+
+        try {
+            methodCallExprs.get(0).calculateResolvedType();
+            fail("An UnsolvedSymbolException should be thrown");
+        } catch (UnsolvedSymbolException ignored) {
+            // all is fine if an UnsolvedSymbolException is thrown
+        }
+    }
+}
+
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue144.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue144.java
new file mode 100644
index 0000000..74c8ff7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue144.java
@@ -0,0 +1,70 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue144 extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() throws IOException {
+        File srcDir = adaptPath(new File("src/test/resources/issue144"));
+        typeSolver = new JavaParserTypeSolver(srcDir);
+    }
+
+    @Test(expected = UnsolvedSymbolException.class)
+    public void issue144() {
+        CompilationUnit cu = parseSampleWithStandardExtension("issue144/HelloWorld");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "HelloWorld");
+        ExpressionStmt expressionStmt = (ExpressionStmt)clazz.getMethodsByName("main").get(0).getBody().get().getStatement(0);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) expressionStmt.getExpression();
+        Expression firstParameter = methodCallExpr.getArgument(0);
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        javaParserFacade.solve(firstParameter).isSolved();
+    }
+
+    @Test
+    public void issue144WithReflectionTypeSolver() {
+        CompilationUnit cu = parseSampleWithStandardExtension("issue144/HelloWorld");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "HelloWorld");
+        ExpressionStmt expressionStmt = (ExpressionStmt)clazz.getMethodsByName("main").get(0).getBody().get().getStatement(0);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) expressionStmt.getExpression();
+        Expression firstParameter = methodCallExpr.getArgument(0);
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver(true));
+
+        assertEquals(true, javaParserFacade.solve(firstParameter).isSolved());
+    }
+
+    @Test
+    public void issue144WithCombinedTypeSolver() {
+        CompilationUnit cu = parseSampleWithStandardExtension("issue144/HelloWorld");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "HelloWorld");
+        ExpressionStmt expressionStmt = (ExpressionStmt)clazz.getMethodsByName("main").get(0).getBody().get().getStatement(0);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) expressionStmt.getExpression();
+        Expression firstParameter = methodCallExpr.getArgument(0);
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new CombinedTypeSolver(typeSolver, new ReflectionTypeSolver(true)));
+
+        assertEquals(true, javaParserFacade.solve(firstParameter).isSolved());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue156.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue156.java
new file mode 100644
index 0000000..b500af7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue156.java
@@ -0,0 +1,37 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue156 extends AbstractResolutionTest {
+
+    @Test
+    public void testFieldAccessThroughClassAndThis() {
+
+        CompilationUnit cu = parseSample("Issue156");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Issue156");
+        List<MethodCallExpr> methods = clazz.getChildNodes().get(2).getChildNodes().get(1).findAll(MethodCallExpr.class);
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        assertEquals("char", javaParserFacade.getType(methods.get(0)).describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue18.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue18.java
new file mode 100644
index 0000000..af0dd18
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue18.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue18 extends AbstractResolutionTest {
+
+    @Test
+    public void typeDeclarationSuperClassImplicitlyIncludeObject() {
+        CompilationUnit cu = parseSample("Issue18");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo");
+        MethodDeclaration methodDeclaration = Navigator.demandMethod(clazz, "bar");
+        ExpressionStmt expr = (ExpressionStmt) methodDeclaration.getBody().get().getStatements().get(1);
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        ResolvedType type = javaParserFacade.getType(expr.getExpression());
+        assertEquals("java.lang.Object", type.describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue185.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue185.java
new file mode 100644
index 0000000..c0ad0b1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue185.java
@@ -0,0 +1,35 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+
+public class Issue185 extends AbstractResolutionTest {
+
+    @Test
+    public void testIssue() throws FileNotFoundException {
+        File src = adaptPath(new File("src/test/resources/recursion-issue"));
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        CompilationUnit agendaCu = JavaParser.parse(adaptPath(new File("src/test/resources/recursion-issue/Usage.java")));
+        MethodCallExpr foo = Navigator.findMethodCall(agendaCu, "foo").get();
+        assertNotNull(foo);
+        JavaParserFacade.get(combinedTypeSolver).getType(foo);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue186.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue186.java
new file mode 100644
index 0000000..2590e9e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue186.java
@@ -0,0 +1,50 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue186 extends AbstractResolutionTest {
+
+    @Test
+    public void lambdaFlatMapIssue() {
+        CompilationUnit cu = parseSample("Issue186");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "JavaTest");
+        MethodDeclaration methodDeclaration = Navigator.demandMethod(clazz, "foo");
+        MethodCallExpr methodCallExpr = Navigator.findMethodCall(methodDeclaration, "flatMap").get();
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        assertEquals("java.util.stream.Stream<java.lang.String>", javaParserFacade.getType(methodCallExpr).describe());
+
+    }
+
+    @Test
+    public void lambdaPrimitivesIssue() {
+        CompilationUnit cu = parseSample("Issue186");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "JavaTest");
+        MethodDeclaration methodDeclaration = Navigator.demandMethod(clazz, "bar");
+        List<LambdaExpr> lambdas = methodDeclaration.findAll(LambdaExpr.class);
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        assertEquals("java.util.function.Predicate<? super java.lang.String>", javaParserFacade.getType(lambdas.get(0)).describe());
+        assertEquals("java.util.function.Function<? super java.lang.String, ? extends java.lang.Integer>", javaParserFacade.getType(lambdas.get(1)).describe());
+        assertEquals("java.util.function.Predicate<? super java.lang.Integer>", javaParserFacade.getType(lambdas.get(2)).describe());
+
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue200.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue200.java
new file mode 100644
index 0000000..ff35987
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue200.java
@@ -0,0 +1,33 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue200 extends AbstractResolutionTest {
+
+    @Test
+    public void issue200() {
+        CompilationUnit cu = parseSample("Issue200");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "JavaTest");
+        MethodDeclaration methodDeclaration = Navigator.demandMethod(clazz, "foo");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        List<ReturnStmt> nodesByType = methodDeclaration.findAll(ReturnStmt.class);
+        assertEquals("java.util.stream.Stream<JavaTest.Solved>", javaParserFacade.getType((nodesByType.get(0)).getExpression().get()).describe());
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue228.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue228.java
new file mode 100644
index 0000000..7ed5bdb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue228.java
@@ -0,0 +1,31 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class Issue228 extends AbstractResolutionTest{
+
+    @Test
+    public void testSolvingMethodWitPrimitiveParameterTypeAsUsage() {
+        String code = 
+                  "class Test { "
+                + "  long l = call(1); "
+                + "  long call(final long i) { "
+                + "    return i; "
+                + "  }"
+                + "}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodCallExpr methodCall = cu.findAll(MethodCallExpr.class).get(0);
+        JavaParserFacade parserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        MethodUsage solvedCall = parserFacade.solveMethodAsUsage(methodCall);
+        assertEquals("long", solvedCall.getParamType(0).describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue232.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue232.java
new file mode 100644
index 0000000..cb4550d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue232.java
@@ -0,0 +1,27 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+public class Issue232 extends AbstractResolutionTest {
+    @Test
+    public void issue232() {
+        CompilationUnit cu = parseSample("Issue232");
+        ClassOrInterfaceDeclaration cls = Navigator.demandClassOrInterface(cu, "OfDouble");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        Context context = JavaParserFactory.getContext(cls, typeSolver);
+        SymbolReference<ResolvedTypeDeclaration> reference = context.solveType("OfPrimitive<Double, DoubleConsumer, OfDouble>", typeSolver);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue235.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue235.java
new file mode 100644
index 0000000..0e4d1aa
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue235.java
@@ -0,0 +1,51 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+@RunWith(Parameterized.class)
+public class Issue235 extends AbstractResolutionTest{
+    private final String method;
+
+    public Issue235(String method) {
+        this.method = method;
+    }
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Collection<String> data() throws Exception {
+        return Arrays.asList(
+                "new_Bar_Baz_direct",
+                "new_Bar_Baz",
+                "new_Bar",
+                "new_Foo_Bar"
+        );
+    }
+
+    @Test
+    public void issue235() {
+        CompilationUnit cu = parseSample("Issue235");
+        ClassOrInterfaceDeclaration cls = Navigator.demandClassOrInterface(cu, "Foo");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        MethodDeclaration m = Navigator.demandMethod(cls, this.method);
+        ExpressionStmt stmt = (ExpressionStmt) m.getBody().get().getStatements().get(0);
+        ObjectCreationExpr expression = (ObjectCreationExpr) stmt.getExpression();
+        Assert.assertNotNull(javaParserFacade.convertToUsage(expression.getType()));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue241.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue241.java
new file mode 100644
index 0000000..9b42314
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue241.java
@@ -0,0 +1,40 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue241 extends AbstractResolutionTest{
+
+    @Test
+    public void testSolveStaticallyImportedMemberType() {
+        File src = adaptPath(new File("src/test/resources"));
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(src));
+        		
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        
+        CompilationUnit cu = parseSample("Issue241");
+        ClassOrInterfaceDeclaration cls = Navigator.demandClassOrInterface(cu, "Main");
+        VariableDeclarator v = Navigator.demandVariableDeclaration(cls, "foo").get();
+        
+        Type t = v.getType();
+        ResolvedType t2 = javaParserFacade.convert(t, t);
+        String typeName = t2.asReferenceType().getQualifiedName();
+       
+        assertEquals("issue241.TypeWithMemberType.MemberInterface", typeName);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue251.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue251.java
new file mode 100644
index 0000000..d8dc0a7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue251.java
@@ -0,0 +1,31 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class Issue251 extends AbstractResolutionTest{
+
+    @Test
+    public void testSolveStaticallyImportedMemberType() {
+        CompilationUnit cu = parseSample("Issue251");
+        ClassOrInterfaceDeclaration cls = Navigator.demandClassOrInterface(cu, "Main");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        MethodDeclaration m = Navigator.demandMethod(cls, "bar");
+        ExpressionStmt stmt = (ExpressionStmt) m.getBody().get().getStatements().get(1);
+        MethodCallExpr expression = (MethodCallExpr) stmt.getExpression();
+        Assert.assertNotNull(javaParserFacade.solve(expression));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue276.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue276.java
new file mode 100644
index 0000000..6baaab0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue276.java
@@ -0,0 +1,41 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodContext;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class Issue276 extends AbstractResolutionTest{
+
+    @Test
+    public void testSolveStaticallyImportedMemberType() throws FileNotFoundException {
+        CompilationUnit cu = JavaParser.parse(new File(adaptPath("src/test/resources/issue276/foo/C.java")));
+        ClassOrInterfaceDeclaration cls = Navigator.demandClassOrInterface(cu, "C");
+        TypeSolver typeSolver = new CombinedTypeSolver(
+        		new ReflectionTypeSolver(), 
+        		new JavaParserTypeSolver(adaptPath(new File("src/test/resources/issue276"))));
+        List<MethodDeclaration> methods = cls.findAll(MethodDeclaration.class);
+        boolean isSolved = false;
+        for (MethodDeclaration method: methods) {
+        	if (method.getNameAsString().equals("overrideMe")) {
+        		MethodContext context = new MethodContext(method, typeSolver);
+        		isSolved = context.solveType("FindMeIfYouCan", typeSolver).isSolved();
+        	}
+        }
+        Assert.assertTrue(isSolved);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue300.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue300.java
new file mode 100644
index 0000000..da19b8d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue300.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class Issue300 extends AbstractResolutionTest {
+
+    @Test
+    public void fieldAccessIssue() throws ParseException, FileNotFoundException {
+        String pathToSourceFile = adaptPath("src/test/resources/issue300/Issue300.java");
+        CompilationUnit cu = JavaParser.parse(new File(pathToSourceFile));
+
+        final FieldAccessExpr fieldAccess = Navigator.findNodeOfGivenClass(cu, FieldAccessExpr.class);
+        assertNotNull(fieldAccess);
+
+        TypeSolver typeSolver = new CombinedTypeSolver(
+                new ReflectionTypeSolver(),
+                new JavaParserTypeSolver(adaptPath(new File("src/test/resources/issue300"))));
+        final JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        final SymbolReference<? extends ResolvedValueDeclaration> ref = javaParserFacade.solve(fieldAccess);
+        assertEquals(ResolvedPrimitiveType.INT, ref.getCorrespondingDeclaration().getType().asPrimitive());
+    }
+}
+
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue314.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue314.java
new file mode 100644
index 0000000..b20ff79
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue314.java
@@ -0,0 +1,58 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.FileNotFoundException;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue314 extends AbstractResolutionTest{
+
+    private TypeSolver typeResolver;
+    private JavaParserFacade javaParserFacade;
+
+    private ResolvedType getExpressionType(TypeSolver typeSolver, Expression expression) {
+        return JavaParserFacade.get(typeSolver).getType(expression);
+    }
+
+    @Before
+    public void setup() {
+        typeResolver = new ReflectionTypeSolver();
+        javaParserFacade = JavaParserFacade.get(typeResolver);
+    }
+
+    @Test
+    public void resolveReferenceToFieldInheritedByInterface() {
+        String code = "package foo.bar;\n"+
+                "interface  A {\n" +
+                "        int a = 0;\n" +
+                "    }\n" +
+                "    \n" +
+                "    class B implements A {\n" +
+                "        int getA() {\n" +
+                "            return a;\n" +
+                "        }\n" +
+                "    }";
+        CompilationUnit cu = JavaParser.parse(code);
+        NameExpr refToA = Navigator.findNameExpression(Navigator.demandClass(cu, "B"), "a").get();
+        SymbolReference<? extends ResolvedValueDeclaration> symbolReference = javaParserFacade.solve(refToA);
+        assertEquals(true, symbolReference.isSolved());
+        assertEquals(true, symbolReference.getCorrespondingDeclaration().isField());
+        assertEquals("a", symbolReference.getCorrespondingDeclaration().getName());
+    }
+
+
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue343.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue343.java
new file mode 100644
index 0000000..3c34c6a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue343.java
@@ -0,0 +1,60 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue343 extends AbstractResolutionTest{
+
+    private TypeSolver typeResolver;
+    private JavaParserFacade javaParserFacade;
+
+    private ResolvedType getExpressionType(TypeSolver typeSolver, Expression expression) {
+        return JavaParserFacade.get(typeSolver).getType(expression);
+    }
+
+    @Before
+    public void setup() {
+        typeResolver = new ReflectionTypeSolver();
+        javaParserFacade = JavaParserFacade.get(typeResolver);
+    }
+
+    @Test
+    public void resolveStringLiteralOutsideAST() {
+        assertEquals(javaParserFacade.classToResolvedType(String.class), getExpressionType(typeResolver, new StringLiteralExpr("")));
+    }
+
+    @Test
+    public void resolveIntegerLiteralOutsideAST() {
+        assertEquals(javaParserFacade.classToResolvedType(int.class), getExpressionType(typeResolver, new IntegerLiteralExpr(2)));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void toResolveDoubleWeNeedTheAST() {
+        getExpressionType(typeResolver, JavaParser.parseExpression("new Double[]{2.0d, 3.0d}[1]"));
+    }
+
+
+    @Test(expected = IllegalStateException.class)
+    public void toResolveFloatWeNeedTheAST() {
+        getExpressionType(typeResolver, JavaParser.parseExpression("new Float[]{2.0d, 3.0d}"));
+    }
+
+    @Test
+    public void resolveMethodCallOnStringLiteralOutsideAST() {
+        assertEquals(javaParserFacade.classToResolvedType(int.class), getExpressionType(typeResolver, new MethodCallExpr(new StringLiteralExpr("hello"), "length")));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void resolveLocaleOutsideAST() {
+        getExpressionType(typeResolver, new FieldAccessExpr(new NameExpr("Locale"), "US"));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue347.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue347.java
new file mode 100644
index 0000000..88755be
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue347.java
@@ -0,0 +1,55 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodContext;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue347 extends AbstractResolutionTest{
+
+    private TypeSolver typeSolver;
+    private JavaParserFacade javaParserFacade;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        javaParserFacade = JavaParserFacade.get(typeSolver);
+    }
+
+    @Test
+    public void resolvingReferenceToEnumDeclarationInSameFile() {
+        String code = "package foo.bar;\nenum Foo {\n" +
+                "    FOO_A, FOO_B\n" +
+                "}\n" +
+                "\n" +
+                "class UsingFoo {\n" +
+                "    Foo myFooField;\n" +
+                "}";
+        CompilationUnit cu = JavaParser.parse(code);
+        FieldDeclaration fieldDeclaration = Navigator.findNodeOfGivenClass(cu, FieldDeclaration.class);
+        ResolvedType fieldType = javaParserFacade.getType(fieldDeclaration);
+        assertEquals(true, fieldType.isReferenceType());
+        assertEquals(true, fieldType.asReferenceType().getTypeDeclaration().isEnum());
+        assertEquals("foo.bar.Foo", fieldType.asReferenceType().getQualifiedName());
+    }
+}
+
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue84.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue84.java
new file mode 100644
index 0000000..ddb920b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/Issue84.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class Issue84 extends AbstractResolutionTest {
+
+    @Test
+    public void variadicIssue() {
+        CompilationUnit cu = parseSample("Issue84");
+        final MethodCallExpr methodCall = Navigator.findMethodCall(cu, "variadicMethod").get();
+
+        final JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        final ResolvedType type = javaParserFacade.getType(methodCall);
+        assertEquals(String.class.getCanonicalName(), type.asReferenceType().getQualifiedName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/JavaParserAPIIntegrationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/JavaParserAPIIntegrationTest.java
new file mode 100644
index 0000000..eb30722
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/JavaParserAPIIntegrationTest.java
@@ -0,0 +1,158 @@
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseStart;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.StreamProvider;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavaParserAPIIntegrationTest extends AbstractTest {
+
+    private TypeSolver typeSolver;
+    private ResolvedReferenceType string;
+    private ResolvedReferenceType listOfBoolean;
+
+    @Before
+    public void setup() {
+        File src = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+        CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver();
+        combinedTypeSolverNewCode.add(new ReflectionTypeSolver());
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(src));
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        typeSolver = combinedTypeSolverNewCode;
+
+        TypeSolver ts = new ReflectionTypeSolver();
+        string = new ReferenceTypeImpl(ts.solveType(String.class.getCanonicalName()), ts);
+        ResolvedReferenceType booleanC = new ReferenceTypeImpl(ts.solveType(Boolean.class.getCanonicalName()), ts);
+        listOfBoolean = new ReferenceTypeImpl(ts.solveType(List.class.getCanonicalName()), ImmutableList.of(booleanC), ts);
+    }
+
+    @Test
+    public void annotationDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/resources/Annotations.java.txt"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        AnnotationDeclaration declaration = (AnnotationDeclaration)cu.getType(0);
+        assertEquals("MyAnnotation", declaration.getNameAsString());
+        ResolvedAnnotationDeclaration resolvedDeclaration = declaration.resolve();
+    }
+
+    @Test
+    public void annotationMemberDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/resources/Annotations.java.txt"));
+        ParserConfiguration parserConfiguration = new ParserConfiguration();
+        parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
+        CompilationUnit cu = new JavaParser(parserConfiguration).parse(ParseStart.COMPILATION_UNIT, new StreamProvider(new FileInputStream(f))).getResult().get();
+        AnnotationDeclaration declaration = (AnnotationDeclaration)cu.getType(2);
+        assertEquals("MyAnnotationWithFields", declaration.getNameAsString());
+        AnnotationMemberDeclaration memberDeclaration = (AnnotationMemberDeclaration)declaration.getMember(0);
+        ResolvedAnnotationMemberDeclaration resolvedDeclaration = memberDeclaration.resolve();
+    }
+
+    @Test
+    public void classDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        ClassOrInterfaceDeclaration declaration = (ClassOrInterfaceDeclaration)cu.getType(0);
+        declaration.resolve();
+    }
+
+    @Test
+    public void interfaceDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/resources/MethodTypeParams.java.txt"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        ClassOrInterfaceDeclaration declaration = (ClassOrInterfaceDeclaration)cu.getType(1);
+        assertEquals("VoidVisitor", declaration.getNameAsString());
+        assertEquals(true, declaration.isInterface());
+        declaration.resolve();
+    }
+
+    private CompilationUnit parseWithSymbolResolution(File f) throws IOException {
+        ParserConfiguration parserConfiguration = new ParserConfiguration();
+        parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
+        return new JavaParser(parserConfiguration).parse(ParseStart.COMPILATION_UNIT, new StreamProvider(new FileInputStream(f))).getResult().get();
+    }
+
+    @Test
+    public void constructorDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = (ClassOrInterfaceDeclaration)cu.getType(0);
+        ConstructorDeclaration constructorDeclaration = classOrInterfaceDeclaration.getDefaultConstructor().get();
+        ResolvedConstructorDeclaration resolvedConstructorDeclaration = constructorDeclaration.resolve();
+    }
+    @Test
+    public void enumDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/AccessSpecifier.java"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        EnumDeclaration declaration = (EnumDeclaration) cu.getType(0);
+        assertEquals("AccessSpecifier", declaration.getNameAsString());
+        ResolvedEnumDeclaration resolvedDeclaration = declaration.resolve();
+    }
+
+    @Test
+    public void enumConstantDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/AccessSpecifier.java"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        EnumDeclaration enumDeclaration = (EnumDeclaration) cu.getType(0);
+        assertEquals("AccessSpecifier", enumDeclaration.getNameAsString());
+        EnumConstantDeclaration declaration = enumDeclaration.getEntry(0);
+        assertEquals("PUBLIC", declaration.getNameAsString());
+        ResolvedEnumConstantDeclaration resolvedDeclaration = declaration.resolve();
+    }
+
+    @Test
+    public void fieldDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        ClassOrInterfaceDeclaration classDeclaration = (ClassOrInterfaceDeclaration) cu.getType(0);
+        assertEquals("CompilationUnit", classDeclaration.getNameAsString());
+        FieldDeclaration declaration = classDeclaration.getFields().get(0);
+        ResolvedFieldDeclaration resolvedDeclaration = declaration.resolve();
+    }
+
+    // TODO make VariableDeclarator resolvable
+
+    @Test
+    public void methodDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java"));
+        CompilationUnit cu = parseWithSymbolResolution(f);
+        ClassOrInterfaceDeclaration classDeclaration = (ClassOrInterfaceDeclaration) cu.getType(0);
+        assertEquals("CompilationUnit", classDeclaration.getNameAsString());
+        MethodDeclaration declaration = classDeclaration.getMethodsByName("getComments").get(0);
+        ResolvedMethodDeclaration resolvedDeclaration = declaration.resolve();
+        assertEquals("getComments", resolvedDeclaration.getName());
+        assertEquals(0, resolvedDeclaration.getNumberOfParams());
+    }
+
+    @Test
+    public void parameterDeclarationResolve() throws IOException {
+        File f = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java"));
+        ParserConfiguration parserConfiguration = new ParserConfiguration();
+        parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
+        CompilationUnit cu = new JavaParser(parserConfiguration).parse(ParseStart.COMPILATION_UNIT, new StreamProvider(new FileInputStream(f))).getResult().get();
+        ClassOrInterfaceDeclaration classDeclaration = (ClassOrInterfaceDeclaration) cu.getType(0);
+        assertEquals("CompilationUnit", classDeclaration.getNameAsString());
+        MethodDeclaration methodDeclaration = classDeclaration.getMethodsByName("setComments").get(0);
+        Parameter declaration = methodDeclaration.getParameter(0);
+        ResolvedParameterDeclaration resolvedDeclaration = declaration.resolve();
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/JavaSymbolSolverTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/JavaSymbolSolverTest.java
new file mode 100644
index 0000000..998a904
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/JavaSymbolSolverTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Test;
+
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavaSymbolSolverTest extends AbstractResolutionTest {
+
+    @Test
+    public void resolveMethodDeclaration() {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        CompilationUnit cu = parseSample("SymbolResolverExample");
+        new JavaSymbolSolver(typeSolver).inject(cu);
+
+        MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMethods().get(0);
+        ResolvedMethodDeclaration resolvedMethodDeclaration = methodDeclaration.resolve();
+        assertEquals("foo", resolvedMethodDeclaration.getName());
+        assertEquals("A[]", resolvedMethodDeclaration.getReturnType().describe());
+        assertEquals("java.lang.String[]", resolvedMethodDeclaration.getParam(0).getType().describe());
+        assertEquals("int[]", resolvedMethodDeclaration.getParam(1).getType().describe());
+    }
+
+    @Test
+    public void resolveArrayType() {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        CompilationUnit cu = parseSample("SymbolResolverExample");
+        new JavaSymbolSolver(typeSolver).inject(cu);
+
+        MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMethods().get(0);
+        ResolvedType resolvedType = methodDeclaration.getType().resolve();
+        assertEquals("A[]", resolvedType.describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/ConvertToUsageTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/ConvertToUsageTest.java
new file mode 100644
index 0000000..44eda27
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/ConvertToUsageTest.java
@@ -0,0 +1,40 @@
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class ConvertToUsageTest extends AbstractResolutionTest {
+
+    private final TypeSolver typeSolver = new ReflectionTypeSolver();
+
+    @Test
+    public void testConvertTypeToUsage() {
+        CompilationUnit cu = parseSample("LocalTypeDeclarations");
+        List<NameExpr> n = cu.findAll(NameExpr.class);
+
+        assertEquals("int", usageDescribe(n, "a"));
+        assertEquals("java.lang.Integer", usageDescribe(n, "b"));
+        assertEquals("java.lang.Class<java.lang.Integer>", usageDescribe(n, "c"));
+        assertEquals("java.lang.Class<? super java.lang.Integer>", usageDescribe(n, "d"));
+        assertEquals("java.lang.Class<? extends java.lang.Integer>", usageDescribe(n, "e"));
+        assertEquals("java.lang.Class<? extends java.lang.Class<? super java.lang.Class<? extends java.lang.Integer>>>", usageDescribe(n, "f"));
+        assertEquals("java.lang.Class<? super java.lang.Class<? extends java.lang.Class<? super java.lang.Integer>>>", usageDescribe(n, "g"));
+    }
+
+    private String usageDescribe(List<NameExpr> n, String name){
+        return n.stream().filter(x -> x.getNameAsString().equals(name))
+                .map(JavaParserFacade.get(typeSolver)::getType)
+                .map(ResolvedType::describe)
+                .findFirst().orElse(null);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/DifferentiateDotExpressionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/DifferentiateDotExpressionTest.java
new file mode 100644
index 0000000..cf5a87b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/DifferentiateDotExpressionTest.java
@@ -0,0 +1,100 @@
+package com.github.javaparser.symbolsolver.javaparsermodel;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+
+public class DifferentiateDotExpressionTest extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/resources/differentiate_dot_expressions"))));
+        typeSolver = combinedTypeSolver;
+    }
+
+    @Test
+    public void methodCallsFromFieldObjects() {
+        ClassOrInterfaceDeclaration clazz = ((JavaParserClassDeclaration) typeSolver.solveType("FieldDotExpressions")).getWrappedNode();
+        MethodDeclaration mainMethod = Navigator.demandMethod(clazz, "main");
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        MethodCallExpr firstFieldMethodCall = Navigator.findMethodCall(mainMethod, "firstContainerMethod").get();
+        MethodCallExpr secondFieldMethodCall = Navigator.findMethodCall(mainMethod, "secondContainerMethod").get();
+        MethodCallExpr thirdFieldMethodCall = Navigator.findMethodCall(mainMethod, "thirdContainerMethod").get();
+
+        assertEquals(true, javaParserFacade.solve(firstFieldMethodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(secondFieldMethodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(thirdFieldMethodCall).isSolved());
+    }
+
+    @Test
+    public void staticMethodCallsFromInnerClasses() {
+        ClassOrInterfaceDeclaration clazz = ((JavaParserClassDeclaration) typeSolver.solveType("InnerClassDotExpressions")).getWrappedNode();
+        MethodDeclaration mainMethod = Navigator.demandMethod(clazz, "main");
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        MethodCallExpr methodCall = Navigator.findMethodCall(mainMethod, "methodCall").get();
+        MethodCallExpr innerMethodCall = Navigator.findMethodCall(mainMethod, "innerMethodCall").get();
+        MethodCallExpr innerInnerMethodCall = Navigator.findMethodCall(mainMethod, "innerInnerMethodCall").get();
+
+        assertEquals(true, javaParserFacade.solve(methodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(innerMethodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(innerInnerMethodCall).isSolved());
+    }
+
+    @Test
+    public void staticFieldCallsFromInnerClasses() {
+        ClassOrInterfaceDeclaration clazz = ((JavaParserClassDeclaration) typeSolver.solveType("InnerStaticClassFieldDotExpressions")).getWrappedNode();
+        MethodDeclaration mainMethod = Navigator.demandMethod(clazz, "main");
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        MethodCallExpr methodCallWithNestedStaticFieldParam = Navigator.findMethodCall(mainMethod, "parseInt").get();
+
+        assertEquals(true, javaParserFacade.solve(methodCallWithNestedStaticFieldParam).isSolved());
+    }
+
+    @Test
+    public void packageStaticMethodCalls() {
+        ClassOrInterfaceDeclaration clazz = ((JavaParserClassDeclaration) typeSolver.solveType("PackageDotExpressions")).getWrappedNode();
+        MethodDeclaration mainMethod = Navigator.demandMethod(clazz, "main");
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        MethodCallExpr staticMethodCall = Navigator.findMethodCall(mainMethod, "staticMethod").get();
+
+        MethodCallExpr methodCall = Navigator.findMethodCall(mainMethod, "methodCall").get();
+        MethodCallExpr innerMethodCall = Navigator.findMethodCall(mainMethod, "innerMethodCall").get();
+        MethodCallExpr innerInnerMethodCall = Navigator.findMethodCall(mainMethod, "innerInnerMethodCall").get();
+
+        MethodCallExpr firstFieldMethodCall = Navigator.findMethodCall(mainMethod, "firstContainerMethod").get();
+        MethodCallExpr secondFieldMethodCall = Navigator.findMethodCall(mainMethod, "secondContainerMethod").get();
+        MethodCallExpr thirdFieldMethodCall = Navigator.findMethodCall(mainMethod, "thirdContainerMethod").get();
+
+        assertEquals(true, javaParserFacade.solve(staticMethodCall).isSolved());
+
+        assertEquals(true, javaParserFacade.solve(methodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(innerMethodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(innerInnerMethodCall).isSolved());
+
+        assertEquals(true, javaParserFacade.solve(firstFieldMethodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(secondFieldMethodCall).isSolved());
+        assertEquals(true, javaParserFacade.solve(thirdFieldMethodCall).isSolved());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclarationTest.java
new file mode 100644
index 0000000..1029456
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclarationTest.java
@@ -0,0 +1,98 @@
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+public class JavaParserAnonymousClassDeclarationTest extends AbstractResolutionTest {
+
+  @Test
+  public void anonymousClassAsMethodArgument() {
+    CompilationUnit cu = parseSample("AnonymousClassDeclarations");
+    ClassOrInterfaceDeclaration aClass = Navigator.demandClass(cu, "AnonymousClassDeclarations");
+    MethodDeclaration method = Navigator.demandMethod(aClass, "fooBar1");
+    MethodCallExpr methodCall = Navigator.findMethodCall(method, "of").get();
+
+    CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+    combinedTypeSolver.add(new ReflectionTypeSolver());
+    MethodUsage methodUsage =
+        JavaParserFacade.get(combinedTypeSolver).solveMethodAsUsage(methodCall);
+
+    assertThat(methodUsage.getQualifiedSignature(),
+               is("AnonymousClassDeclarations.ParDo.of(AnonymousClassDeclarations.DoFn<I, O>)"));
+  }
+
+  @Test
+  public void callingSuperClassInnerClassMethod() {
+    CompilationUnit cu = parseSample("AnonymousClassDeclarations");
+    ClassOrInterfaceDeclaration aClass = Navigator.demandClass(cu, "AnonymousClassDeclarations");
+    MethodDeclaration method = Navigator.demandMethod(aClass, "fooBar2");
+    MethodCallExpr methodCall = Navigator.findMethodCall(method, "innerClassMethod").get();
+
+    CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+    combinedTypeSolver.add(new ReflectionTypeSolver());
+    MethodUsage methodUsage =
+        JavaParserFacade.get(combinedTypeSolver).solveMethodAsUsage(methodCall);
+
+    assertThat(methodUsage.getQualifiedSignature(),
+               is("AnonymousClassDeclarations.DoFn.ProcessContext.innerClassMethod()"));
+  }
+
+  @Test
+  public void callingAnonymousClassInnerMethod() {
+    CompilationUnit cu = parseSample("AnonymousClassDeclarations");
+    ClassOrInterfaceDeclaration aClass = Navigator.demandClass(cu, "AnonymousClassDeclarations");
+    MethodDeclaration method = Navigator.demandMethod(aClass, "fooBar3");
+    MethodCallExpr methodCall = Navigator.findMethodCall(method, "callAnnonClassInnerMethod").get();
+
+    CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+    combinedTypeSolver.add(new ReflectionTypeSolver());
+    MethodUsage methodUsage =
+        JavaParserFacade.get(combinedTypeSolver).solveMethodAsUsage(methodCall);
+
+    assertTrue(methodUsage.getQualifiedSignature().startsWith("AnonymousClassDeclarations"));
+    assertTrue(methodUsage.getQualifiedSignature().contains("Anonymous-"));
+    assertTrue(methodUsage.getQualifiedSignature().endsWith("callAnnonClassInnerMethod()"));
+  }
+
+  @Test
+  public void usingAnonymousSuperClassInnerType() {
+    CompilationUnit cu = parseSample("AnonymousClassDeclarations");
+    ClassOrInterfaceDeclaration aClass = Navigator.demandClass(cu, "AnonymousClassDeclarations");
+    MethodDeclaration method = Navigator.demandMethod(aClass, "fooBar4");
+    MethodCallExpr methodCall = Navigator.findMethodCall(method, "toString").get();
+
+    CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+    combinedTypeSolver.add(new ReflectionTypeSolver());
+    MethodUsage methodUsage =
+        JavaParserFacade.get(combinedTypeSolver).solveMethodAsUsage(methodCall);
+
+    assertThat(methodUsage.getQualifiedSignature(), is("java.lang.Enum.toString()"));
+  }
+
+  @Test
+  public void usingAnonymousClassInnerType() {
+    CompilationUnit cu = parseSample("AnonymousClassDeclarations");
+    ClassOrInterfaceDeclaration aClass = Navigator.demandClass(cu, "AnonymousClassDeclarations");
+    MethodDeclaration method = Navigator.demandMethod(aClass, "fooBar5");
+    MethodCallExpr methodCall = Navigator.findMethodCall(method, "toString").get();
+
+    CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+    combinedTypeSolver.add(new ReflectionTypeSolver());
+    MethodUsage methodUsage =
+        JavaParserFacade.get(combinedTypeSolver).solveMethodAsUsage(methodCall);
+
+    assertThat(methodUsage.getQualifiedSignature(), is("java.lang.Enum.toString()"));
+  }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java
new file mode 100644
index 0000000..0e70b18
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclarationTest.java
@@ -0,0 +1,894 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedFieldDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavaParserClassDeclarationTest extends AbstractTest {
+
+    private TypeSolver typeSolver;
+    private TypeSolver typeSolverNewCode;
+    private ResolvedReferenceType string;
+    private ResolvedReferenceType listOfBoolean;
+
+    @Before
+    public void setup() {
+        File src = adaptPath(new File("src/test/test_sourcecode/javaparser_src/proper_source"));
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+        combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_src/generated"))));
+        typeSolver = combinedTypeSolver;
+
+        File srcNewCode = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+        CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver();
+        combinedTypeSolverNewCode.add(new ReflectionTypeSolver());
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(srcNewCode));
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        typeSolverNewCode = combinedTypeSolverNewCode;
+
+        TypeSolver ts = new ReflectionTypeSolver();
+        string = new ReferenceTypeImpl(ts.solveType(String.class.getCanonicalName()), ts);
+        ResolvedReferenceType booleanC = new ReferenceTypeImpl(ts.solveType(Boolean.class.getCanonicalName()), ts);
+        listOfBoolean = new ReferenceTypeImpl(ts.solveType(List.class.getCanonicalName()), ImmutableList.of(booleanC), ts);
+    }
+
+    ///
+    /// Test misc
+    ///
+
+    @Test
+    public void testIsClass() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(true, compilationUnit.isClass());
+    }
+
+    @Test
+    public void testIsInterface() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(false, compilationUnit.isInterface());
+    }
+
+    @Test
+    public void testIsEnum() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(false, compilationUnit.isEnum());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(false, compilationUnit.isTypeParameter());
+    }
+
+    @Test
+    public void testIsType() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(true, compilationUnit.isType());
+    }
+
+    @Test
+    public void testAsType() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(compilationUnit, compilationUnit.asType());
+    }
+
+    @Test
+    public void testAsClass() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(compilationUnit, compilationUnit.asClass());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsInterface() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        compilationUnit.asInterface();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsEnum() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        compilationUnit.asEnum();
+    }
+
+    @Test
+    public void testGetPackageName() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast", compilationUnit.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("CompilationUnit", compilationUnit.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast.CompilationUnit", compilationUnit.getQualifiedName());
+    }
+
+    ///
+    /// Test ancestors
+    ///
+
+    @Test
+    public void testGetSuperclassWithoutTypeParameters() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast.Node", compilationUnit.getSuperClass().getQualifiedName());
+    }
+
+    @Test
+    public void testGetSuperclassWithTypeParameters() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", compilationUnit.getSuperClass().getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", compilationUnit.getSuperClass().typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithoutTypeParameters() {
+        JavaParserClassDeclaration cu = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(3, constructorDeclaration.getAllSuperClasses().size());
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("com.github.javaparser.ast.body.BodyDeclaration")));
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("com.github.javaparser.ast.Node")));
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("java.lang.Object")));
+
+        ResolvedReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(2);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+    }
+
+    @Test
+    public void testGetInterfacesWithoutParameters() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of(), compilationUnit.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavaParserClassDeclaration coid = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.DocumentableNode"), coid.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetInterfacesWithParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(7, constructorDeclaration.getInterfaces().size());
+
+        ResolvedReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllInterfacesWithoutParameters() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable"), compilationUnit.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavaParserClassDeclaration coid = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.NamedNode", "com.github.javaparser.ast.body.AnnotableNode", "com.github.javaparser.ast.DocumentableNode"), coid.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllInterfacesWithParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(9, constructorDeclaration.getAllInterfaces().size());
+
+        ResolvedReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(7);
+        assertEquals("java.lang.Cloneable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAncestorsWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(8, constructorDeclaration.getAncestors().size());
+
+        ResolvedReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllAncestorsWithoutTypeParameters() {
+        JavaParserClassDeclaration cu = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllAncestors().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllAncestorsWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(12, constructorDeclaration.getAllAncestors().size());
+
+        ResolvedReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(2);
+        assertEquals("java.lang.Cloneable", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(4);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(9);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(10);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(11);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    ///
+    /// Test fields
+    ///
+
+    @Test
+    public void testGetFieldForExistingField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        ResolvedFieldDeclaration fieldDeclaration = null;
+
+        // declared field
+        fieldDeclaration = constructorDeclaration.getField("modifiers");
+        assertEquals("modifiers", fieldDeclaration.getName());
+        assertEquals("java.util.EnumSet", fieldDeclaration.getType().asReferenceType().getQualifiedName());
+        assertEquals(AccessSpecifier.PRIVATE, fieldDeclaration.accessSpecifier());
+        assertEquals(false, fieldDeclaration.isStatic());
+
+        // inherited field
+        fieldDeclaration = constructorDeclaration.getField("annotations");
+        assertEquals("annotations", fieldDeclaration.getName());
+        assertEquals("java.util.List", fieldDeclaration.getType().asReferenceType().getQualifiedName());
+        assertEquals(AccessSpecifier.PRIVATE, fieldDeclaration.accessSpecifier());
+    }
+
+    @Test(expected = UnsolvedSymbolException.class)
+    public void testGetFieldForUnexistingField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        constructorDeclaration.getField("unexisting");
+    }
+
+    @Test
+    public void testGetAllFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<ResolvedFieldDeclaration> allFields = constructorDeclaration.getAllFields();
+        assertEquals(16, allFields.size());
+
+        ResolvedFieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(6);
+        assertEquals("annotations", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(7);
+        assertEquals("NODE_BY_BEGIN_POSITION", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(8);
+        assertEquals("range", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(9);
+        assertEquals("parentNode", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(10);
+        assertEquals("childrenNodes", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(11);
+        assertEquals("orphanComments", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(12);
+        assertEquals("userData", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(13);
+        assertEquals("comment", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(14);
+        assertEquals("ABSOLUTE_BEGIN_LINE", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(15);
+        assertEquals("ABSOLUTE_END_LINE", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetAllGenericFields() throws IOException, ParseException {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        CompilationUnit cu = JavaParser.parse(adaptPath(new File("src/test/resources/GenericFields.java.txt")));
+        JavaParserClassDeclaration classDeclaration = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CB"), typeSolver);
+
+        assertEquals(3, classDeclaration.getAllFields().size());
+
+        ReferenceTypeImpl rtClassDeclaration = new ReferenceTypeImpl(classDeclaration, typeSolver);
+
+        assertEquals("s", classDeclaration.getAllFields().get(0).getName());
+        assertEquals(string, classDeclaration.getAllFields().get(0).getType());
+        assertEquals(string, rtClassDeclaration.getFieldType("s").get());
+
+        assertEquals("t", classDeclaration.getAllFields().get(1).getName());
+        assertEquals("java.util.List<java.lang.Boolean>", classDeclaration.getAllFields().get(1).getType().describe());
+        assertEquals(listOfBoolean, rtClassDeclaration.getFieldType("t").get());
+
+        assertEquals("i", classDeclaration.getAllFields().get(2).getName());
+        assertEquals(ResolvedPrimitiveType.INT, classDeclaration.getAllFields().get(2).getType());
+        assertEquals(ResolvedPrimitiveType.INT, rtClassDeclaration.getFieldType("i").get());
+    }
+
+    @Test
+    public void testGetAllStaticFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<ResolvedFieldDeclaration> allFields = constructorDeclaration.getAllStaticFields();
+        assertEquals(3, allFields.size());
+
+        ResolvedFieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("NODE_BY_BEGIN_POSITION", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("ABSOLUTE_BEGIN_LINE", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("ABSOLUTE_END_LINE", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetAllNonStaticFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<ResolvedFieldDeclaration> allFields = constructorDeclaration.getAllNonStaticFields();
+        assertEquals(13, allFields.size());
+
+        ResolvedFieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(6);
+        assertEquals("annotations", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(7);
+        assertEquals("range", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(8);
+        assertEquals("parentNode", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(9);
+        assertEquals("childrenNodes", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(10);
+        assertEquals("orphanComments", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(11);
+        assertEquals("userData", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(12);
+        assertEquals("comment", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetDeclaredFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<ResolvedFieldDeclaration> allFields = constructorDeclaration.getDeclaredFields();
+        assertEquals(6, allFields.size());
+
+        ResolvedFieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+    }
+
+    ///
+    /// Test methods
+    ///
+
+    @Test
+    public void testGetDeclaredMethods() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        Set<ResolvedMethodDeclaration> allMethods = constructorDeclaration.getDeclaredMethods();
+        assertEquals(20, allMethods.size());
+
+        List<ResolvedMethodDeclaration> sortedMethods = allMethods.stream()
+                .sorted((o1, o2) -> o1.getQualifiedSignature().compareTo(o2.getQualifiedSignature()))
+                .collect(Collectors.toList());
+
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)", sortedMethods.get(0).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)", sortedMethods.get(1).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getBody()", sortedMethods.get(2).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString()", sortedMethods.get(3).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean)", sortedMethods.get(4).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)", sortedMethods.get(5).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getJavaDoc()", sortedMethods.get(6).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()", sortedMethods.get(7).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getName()", sortedMethods.get(8).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getNameExpr()", sortedMethods.get(9).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()", sortedMethods.get(10).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()", sortedMethods.get(11).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()", sortedMethods.get(12).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)", sortedMethods.get(13).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)", sortedMethods.get(14).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)", sortedMethods.get(15).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)", sortedMethods.get(16).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)", sortedMethods.get(17).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)", sortedMethods.get(18).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)", sortedMethods.get(19).getQualifiedSignature());
+    }
+
+    @Test
+    public void testGetAllMethods() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        Set<MethodUsage> allMethods = constructorDeclaration.getAllMethods();
+
+        List<MethodUsage> sortedMethods = allMethods.stream()
+                .sorted((o1, o2) -> o1.getQualifiedSignature().compareTo(o2.getQualifiedSignature()))
+                .collect(Collectors.toList());
+
+        List<String> signatures = sortedMethods.stream().map(m -> m.getQualifiedSignature()).collect(Collectors.toList());
+
+        assertEquals(ImmutableList.of("com.github.javaparser.ast.Node.addOrphanComment(com.github.javaparser.ast.comments.Comment)",
+                "com.github.javaparser.ast.Node.clone()",
+                "com.github.javaparser.ast.Node.contains(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.equals(java.lang.Object)",
+                "com.github.javaparser.ast.Node.getAllContainedComments()",
+                "com.github.javaparser.ast.Node.getBegin()",
+                "com.github.javaparser.ast.Node.getChildrenNodes()",
+                "com.github.javaparser.ast.Node.getComment()",
+                "com.github.javaparser.ast.Node.getEnd()",
+                "com.github.javaparser.ast.Node.getNodesByType(java.lang.Class<N>)",
+                "com.github.javaparser.ast.Node.getOrphanComments()",
+                "com.github.javaparser.ast.Node.getParentNode()",
+                "com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)",
+                "com.github.javaparser.ast.Node.getRange()",
+                "com.github.javaparser.ast.Node.getUserData(com.github.javaparser.ast.UserDataKey<M>)",
+                "com.github.javaparser.ast.Node.hasComment()",
+                "com.github.javaparser.ast.Node.hashCode()",
+                "com.github.javaparser.ast.Node.isPositionedAfter(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.isPositionedBefore(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)",
+                "com.github.javaparser.ast.Node.setBegin(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setBlockComment(java.lang.String)",
+                "com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)",
+                "com.github.javaparser.ast.Node.setEnd(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setLineComment(java.lang.String)",
+                "com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.setRange(com.github.javaparser.Range)",
+                "com.github.javaparser.ast.Node.setUserData(com.github.javaparser.ast.UserDataKey<M>, M)",
+                "com.github.javaparser.ast.Node.toString()",
+                "com.github.javaparser.ast.Node.toStringWithoutComments()",
+                "com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)",
+                "com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()",
+                "com.github.javaparser.ast.body.BodyDeclaration.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getBody()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getJavaDoc()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getName()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getNameExpr()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addMarkerAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addMarkerAnnotation(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addSingleMemberAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addSingleMemberAnnotation(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotationByClass(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotationByName(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.isAnnotationPresent(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.createBody()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.setJavaDocComment(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.addModifier(com.github.javaparser.ast.Modifier...)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isAbstract()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isFinal()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isNative()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isPrivate()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isProtected()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isPublic()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStatic()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStrictfp()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isSynchronized()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isTransient()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isVolatile()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.body.Parameter)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.type.Type, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(java.lang.Class<?>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.body.Parameter)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.type.Type, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(java.lang.Class<?>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByName(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByType(java.lang.Class<?>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByType(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.addThrows(com.github.javaparser.ast.type.ReferenceType)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.addThrows(java.lang.Class<? extends java.lang.Throwable>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.String)",
+                "java.lang.Object.finalize()",
+                "java.lang.Object.getClass()",
+                "java.lang.Object.notify()",
+                "java.lang.Object.notifyAll()",
+                "java.lang.Object.registerNatives()",
+                "java.lang.Object.wait()",
+                "java.lang.Object.wait(long)",
+                "java.lang.Object.wait(long, int)"), signatures);
+    }
+
+    ///
+    /// Test constructors
+    ///
+
+    @Test
+    public void testGetConstructors() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<ResolvedConstructorDeclaration> constructors = constructorDeclaration.getConstructors();
+        assertEquals(4, constructors.size());
+
+        assertEquals("ConstructorDeclaration()", constructors.get(0).getSignature());
+        assertEquals("ConstructorDeclaration(java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.lang.String)", constructors.get(1).getSignature());
+        assertEquals("ConstructorDeclaration(java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.String, java.util.List<com.github.javaparser.ast.body.Parameter>, java.util.List<com.github.javaparser.ast.type.ReferenceType>, com.github.javaparser.ast.stmt.BlockStmt)", constructors.get(2).getSignature());
+        assertEquals("ConstructorDeclaration(com.github.javaparser.Range, java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.String, java.util.List<com.github.javaparser.ast.body.Parameter>, java.util.List<com.github.javaparser.ast.type.ReferenceType>, com.github.javaparser.ast.stmt.BlockStmt)", constructors.get(3).getSignature());
+    }
+
+    ///
+    /// Resolution
+    ///
+
+    //SymbolReference<MethodDeclaration> solveMethod(String name, List<Type> parameterTypes);
+    @Test
+    public void testSolveMethodExisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<ResolvedMethodDeclaration> res = null;
+
+        res = constructorDeclaration.solveMethod("isStatic", ImmutableList.of());
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStatic()", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(RuntimeException.class.getClass(), typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(String.class, typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.String)", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        // This is solved because it is raw
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(Class.class, typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)", res.getCorrespondingDeclaration().getQualifiedSignature());
+    }
+
+    @Test
+    public void testSolveMethodNotExisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<ResolvedMethodDeclaration> res = null;
+
+        res = constructorDeclaration.solveMethod("unexistingMethod", ImmutableList.of());
+        assertEquals(false, res.isSolved());
+
+        res = constructorDeclaration.solveMethod("isStatic", ImmutableList.of(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveMethodNotExistingBecauseOfTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<ResolvedMethodDeclaration> res = null;
+
+        ResolvedReferenceType stringType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(String.class, typeSolverNewCode);
+        ResolvedReferenceType rawClassType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolverNewCode);
+        ResolvedReferenceType classOfStringType = (ResolvedReferenceType) rawClassType.replaceTypeVariables(rawClassType.getTypeDeclaration().getTypeParameters().get(0), stringType);
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(classOfStringType));
+        assertEquals(false, res.isSolved());
+    }
+
+
+    ///
+    /// Assignability
+    ///
+
+    // boolean isAssignableBy(Type type);
+
+    // boolean canBeAssignedTo(TypeDeclaration other)
+
+    // boolean isAssignableBy(TypeDeclaration other);
+
+    ///
+    /// Annotations
+    ///
+
+    // hasDirectlyAnnotation
+
+    @Test
+    public void testHasDirectlyAnnotation() throws IOException, ParseException {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        CompilationUnit cu = JavaParser.parse(adaptPath(new File("src/test/resources/Annotations.java.txt")));
+
+        JavaParserClassDeclaration ca = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CA"), typeSolver);
+        assertEquals(true, ca.hasDirectlyAnnotation("foo.bar.MyAnnotation"));
+        assertEquals(false, ca.hasDirectlyAnnotation("foo.bar.MyAnnotation2"));
+        assertEquals(false, ca.hasDirectlyAnnotation("MyAnnotation"));
+        assertEquals(false, ca.hasDirectlyAnnotation("foo.bar.MyUnexistingAnnotation"));
+
+        JavaParserClassDeclaration cb = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CB"), typeSolver);
+        assertEquals(false, cb.hasDirectlyAnnotation("foo.bar.MyAnnotation"));
+        assertEquals(true, cb.hasDirectlyAnnotation("foo.bar.MyAnnotation2"));
+        assertEquals(false, cb.hasDirectlyAnnotation("MyAnnotation"));
+        assertEquals(false, cb.hasDirectlyAnnotation("foo.bar.MyUnexistingAnnotation"));
+    }
+
+    // hasAnnotation
+
+    @Test
+    public void testHasAnnotation() throws IOException, ParseException {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        CompilationUnit cu = JavaParser.parse(adaptPath(new File("src/test/resources/Annotations.java.txt")));
+
+        JavaParserClassDeclaration ca = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CA"), typeSolver);
+        assertEquals(true, ca.hasAnnotation("foo.bar.MyAnnotation"));
+        assertEquals(false, ca.hasAnnotation("foo.bar.MyAnnotation2"));
+        assertEquals(false, ca.hasAnnotation("MyAnnotation"));
+        assertEquals(false, ca.hasAnnotation("foo.bar.MyUnexistingAnnotation"));
+
+        JavaParserClassDeclaration cb = new JavaParserClassDeclaration(Navigator.demandClass(cu, "CB"), typeSolver);
+        assertEquals(true, cb.hasAnnotation("foo.bar.MyAnnotation"));
+        assertEquals(true, cb.hasAnnotation("foo.bar.MyAnnotation2"));
+        assertEquals(false, cb.hasAnnotation("MyAnnotation"));
+        assertEquals(false, cb.hasAnnotation("foo.bar.MyUnexistingAnnotation"));
+    }
+
+    ///
+    ///
+    ///
+
+    // List<TypeParameterDeclaration> getTypeParameters();
+
+    // AccessLevel accessLevel();
+
+    ///
+    /// Containment
+    ///
+
+    // Set<TypeDeclaration> internalTypes()
+
+    // Optional<TypeDeclaration> containerType()
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclarationTest.java
new file mode 100644
index 0000000..c171f4b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclarationTest.java
@@ -0,0 +1,826 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavaParserEnumDeclarationTest extends AbstractTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        File srcNewCode = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+        CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver();
+        combinedTypeSolverNewCode.add(new ReflectionTypeSolver());
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(srcNewCode));
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        typeSolver = combinedTypeSolverNewCode;
+    }
+
+    ///
+    /// Test misc
+    ///
+
+    @Test
+    public void testIsClass() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isClass());
+    }
+
+    @Test
+    public void testIsInterface() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isInterface());
+    }
+
+    @Test
+    public void testIsEnum() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(true, modifier.isEnum());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isTypeParameter());
+    }
+
+    @Test
+    public void testIsType() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(true, modifier.isType());
+    }
+
+    @Test
+    public void testAsType() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(modifier, modifier.asType());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsClass() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        modifier.asClass();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsInterface() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        modifier.asInterface();
+    }
+
+    @Test
+    public void testAsEnum() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(modifier, modifier.asEnum());
+    }
+
+    @Test
+    public void testGetPackageName() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("com.github.javaparser.ast", modifier.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("Modifier", modifier.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("com.github.javaparser.ast.Modifier", modifier.getQualifiedName());
+    }
+
+    ///
+    /// Test ancestors
+    ///
+
+    /*@Test
+    public void testGetSuperclassWithoutTypeParameters() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("com.github.javaparser.ast.Node", compilationUnit.getSuperClass().getQualifiedName());
+    }
+
+    @Test
+    public void testGetSuperclassWithTypeParameters() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", compilationUnit.getSuperClass().getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", compilationUnit.getSuperClass().typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithoutTypeParameters() {
+        JavaParserClassDeclaration cu = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(3, constructorDeclaration.getAllSuperClasses().size());
+
+        ReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(2);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+    }
+
+    @Test
+    public void testGetInterfacesWithoutParameters() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(ImmutableSet.of(), compilationUnit.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavaParserClassDeclaration coid = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.DocumentableNode"), coid.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetInterfacesWithParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(7, constructorDeclaration.getInterfaces().size());
+
+        ReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllInterfacesWithoutParameters() {
+        JavaParserEnumDeclaration modifier = (JavaParserEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable"), compilationUnit.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavaParserClassDeclaration coid = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.NamedNode", "com.github.javaparser.ast.body.AnnotableNode", "com.github.javaparser.ast.DocumentableNode"), coid.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllInterfacesWithParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(9, constructorDeclaration.getAllInterfaces().size());
+
+        ReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(7);
+        assertEquals("java.lang.Cloneable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAncestorsWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(8, constructorDeclaration.getAncestors().size());
+
+        ReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllAncestorsWithoutTypeParameters() {
+        JavaParserClassDeclaration cu = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllAncestors().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllAncestorsWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(12, constructorDeclaration.getAllAncestors().size());
+
+        ReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(2);
+        assertEquals("java.lang.Cloneable", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(4);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(9);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(10);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(11);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    ///
+    /// Test fields
+    ///
+
+    @Test
+    public void testGetFieldForExistingField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        FieldDeclaration fieldDeclaration = null;
+
+        // declared field
+        fieldDeclaration = constructorDeclaration.getField("modifiers");
+        assertEquals("modifiers", fieldDeclaration.getName());
+        assertEquals("java.util.EnumSet", fieldDeclaration.getType().asReferenceType().getQualifiedName());
+        assertEquals(AccessLevel.PRIVATE, fieldDeclaration.accessLevel());
+        assertEquals(false, fieldDeclaration.isStatic());
+
+        // inherited field
+        fieldDeclaration = constructorDeclaration.getField("annotations");
+        assertEquals("annotations", fieldDeclaration.getName());
+        assertEquals("java.util.List", fieldDeclaration.getType().asReferenceType().getQualifiedName());
+        assertEquals(AccessLevel.PRIVATE, fieldDeclaration.accessLevel());
+    }
+
+    @Test(expected = UnsolvedSymbolException.class)
+    public void testGetFieldForUnexistingField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        constructorDeclaration.getField("unexisting");
+    }
+
+    @Test
+    public void testGetAllFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getAllFields();
+        assertEquals(16, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(6);
+        assertEquals("annotations", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(7);
+        assertEquals("NODE_BY_BEGIN_POSITION", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(8);
+        assertEquals("range", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(9);
+        assertEquals("parentNode", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(10);
+        assertEquals("childrenNodes", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(11);
+        assertEquals("orphanComments", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(12);
+        assertEquals("userData", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(13);
+        assertEquals("comment", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(14);
+        assertEquals("ABSOLUTE_BEGIN_LINE", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(15);
+        assertEquals("ABSOLUTE_END_LINE", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetAllStaticFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getAllStaticFields();
+        assertEquals(3, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("NODE_BY_BEGIN_POSITION", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("ABSOLUTE_BEGIN_LINE", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("ABSOLUTE_END_LINE", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetAllNonStaticFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getAllNonStaticFields();
+        assertEquals(13, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(6);
+        assertEquals("annotations", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(7);
+        assertEquals("range", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(8);
+        assertEquals("parentNode", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(9);
+        assertEquals("childrenNodes", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(10);
+        assertEquals("orphanComments", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(11);
+        assertEquals("userData", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(12);
+        assertEquals("comment", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetDeclaredFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getDeclaredFields();
+        assertEquals(6, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+    }
+
+    ///
+    /// Test methods
+    ///
+
+    @Test
+    public void testGetDeclaredMethods() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        Set<MethodDeclaration> allMethods = constructorDeclaration.getDeclaredMethods();
+        assertEquals(20, allMethods.size());
+
+        List<MethodDeclaration> sortedMethods = allMethods.stream()
+                .sorted((o1, o2) -> o1.getQualifiedSignature().compareTo(o2.getQualifiedSignature()))
+                .collect(Collectors.toList());
+
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)", sortedMethods.get(0).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)", sortedMethods.get(1).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getBody()", sortedMethods.get(2).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString()", sortedMethods.get(3).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean)", sortedMethods.get(4).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)", sortedMethods.get(5).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getJavaDoc()", sortedMethods.get(6).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()", sortedMethods.get(7).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getName()", sortedMethods.get(8).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getNameExpr()", sortedMethods.get(9).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()", sortedMethods.get(10).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()", sortedMethods.get(11).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()", sortedMethods.get(12).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)", sortedMethods.get(13).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)", sortedMethods.get(14).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)", sortedMethods.get(15).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)", sortedMethods.get(16).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)", sortedMethods.get(17).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)", sortedMethods.get(18).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)", sortedMethods.get(19).getQualifiedSignature());
+    }
+
+    @Test
+    public void testGetAllMethods() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        Set<MethodUsage> allMethods = constructorDeclaration.getAllMethods();
+
+        List<MethodUsage> sortedMethods = allMethods.stream()
+                .sorted((o1, o2) -> o1.getQualifiedSignature().compareTo(o2.getQualifiedSignature()))
+                .collect(Collectors.toList());
+
+        List<String> signatures = sortedMethods.stream().map(m -> m.getQualifiedSignature()).collect(Collectors.toList());
+
+        assertEquals(ImmutableList.of("com.github.javaparser.ast.Node.addOrphanComment(com.github.javaparser.ast.comments.Comment)",
+                "com.github.javaparser.ast.Node.clone()",
+                "com.github.javaparser.ast.Node.contains(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.equals(java.lang.Object)",
+                "com.github.javaparser.ast.Node.getAllContainedComments()",
+                "com.github.javaparser.ast.Node.getBegin()",
+                "com.github.javaparser.ast.Node.getChildrenNodes()",
+                "com.github.javaparser.ast.Node.getComment()",
+                "com.github.javaparser.ast.Node.getEnd()",
+                "com.github.javaparser.ast.Node.getNodesByType(java.lang.Class<N>)",
+                "com.github.javaparser.ast.Node.getOrphanComments()",
+                "com.github.javaparser.ast.Node.getParentNode()",
+                "com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)",
+                "com.github.javaparser.ast.Node.getRange()",
+                "com.github.javaparser.ast.Node.getUserData(com.github.javaparser.ast.UserDataKey<M>)",
+                "com.github.javaparser.ast.Node.hasComment()",
+                "com.github.javaparser.ast.Node.hashCode()",
+                "com.github.javaparser.ast.Node.isPositionedAfter(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.isPositionedBefore(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)",
+                "com.github.javaparser.ast.Node.setBegin(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setBlockComment(java.lang.String)",
+                "com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)",
+                "com.github.javaparser.ast.Node.setEnd(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setLineComment(java.lang.String)",
+                "com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.setRange(com.github.javaparser.Range)",
+                "com.github.javaparser.ast.Node.setUserData(com.github.javaparser.ast.UserDataKey<M>, M)",
+                "com.github.javaparser.ast.Node.toString()",
+                "com.github.javaparser.ast.Node.toStringWithoutComments()",
+                "com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)",
+                "com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()",
+                "com.github.javaparser.ast.body.BodyDeclaration.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getBody()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getJavaDoc()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getName()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getNameExpr()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addMarkerAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addMarkerAnnotation(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addSingleMemberAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addSingleMemberAnnotation(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotationByClass(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotationByName(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.isAnnotationPresent(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.createBody()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.setJavaDocComment(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.addModifier(com.github.javaparser.ast.Modifier...)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isAbstract()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isFinal()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isNative()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isPrivate()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isProtected()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isPublic()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStatic()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStrictfp()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isSynchronized()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isTransient()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isVolatile()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.body.Parameter)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.type.Type, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(java.lang.Class<?>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.body.Parameter)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.type.Type, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(java.lang.Class<?>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByName(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByType(java.lang.Class<?>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByType(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.addThrows(com.github.javaparser.ast.type.ReferenceType)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.addThrows(java.lang.Class<? extends java.lang.Throwable>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.String)",
+                "java.lang.Object.finalize()",
+                "java.lang.Object.getClass()",
+                "java.lang.Object.notify()",
+                "java.lang.Object.notifyAll()",
+                "java.lang.Object.registerNatives()",
+                "java.lang.Object.wait()",
+                "java.lang.Object.wait(long)",
+                "java.lang.Object.wait(long, int)"), signatures);
+    }
+
+    ///
+    /// Test constructors
+    ///
+
+    @Test
+    public void testGetConstructors() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<ConstructorDeclaration> constructors = constructorDeclaration.getConstructors();
+        assertEquals(4, constructors.size());
+
+        assertEquals("ConstructorDeclaration()", constructors.get(0).getSignature());
+        assertEquals("ConstructorDeclaration(java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.lang.String)", constructors.get(1).getSignature());
+        assertEquals("ConstructorDeclaration(java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.String, java.util.List<com.github.javaparser.ast.body.Parameter>, java.util.List<com.github.javaparser.ast.type.ReferenceType>, com.github.javaparser.ast.stmt.BlockStmt)", constructors.get(2).getSignature());
+        assertEquals("ConstructorDeclaration(com.github.javaparser.Range, java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.String, java.util.List<com.github.javaparser.ast.body.Parameter>, java.util.List<com.github.javaparser.ast.type.ReferenceType>, com.github.javaparser.ast.stmt.BlockStmt)", constructors.get(3).getSignature());
+    }
+
+    ///
+    /// Resolution
+    ///
+
+    //SymbolReference<MethodDeclaration> solveMethod(String name, List<Type> parameterTypes);
+    @Test
+    public void testSolveMethodExisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<MethodDeclaration> res = null;
+
+        res = constructorDeclaration.solveMethod("isStatic", ImmutableList.of());
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStatic()", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(RuntimeException.class.getClass(), typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(String.class, typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.String)", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        // This is solved because it is raw
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(Class.class, typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)", res.getCorrespondingDeclaration().getQualifiedSignature());
+    }
+
+    @Test
+    public void testSolveMethodNotExisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<MethodDeclaration> res = null;
+
+        res = constructorDeclaration.solveMethod("unexistingMethod", ImmutableList.of());
+        assertEquals(false, res.isSolved());
+
+        res = constructorDeclaration.solveMethod("isStatic", ImmutableList.of(PrimitiveType.BOOLEAN));
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveMethodNotExistingBecauseOfTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<MethodDeclaration> res = null;
+
+        ReferenceType stringType = (ReferenceType) ReflectionFactory.typeUsageFor(String.class, typeSolverNewCode);
+        ReferenceType rawClassType = (ReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolverNewCode);
+        ReferenceType classOfStringType = (ReferenceType) rawClassType.replaceTypeVariables("T", stringType);
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(classOfStringType));
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveSymbolUnexisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("unexisting", typeSolver);
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveSymbolToDeclaredField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("name", typeSolver);
+        assertEquals(true, res.isSolved());
+        assertEquals(true, res.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void testSolveSymbolToInheritedPublicField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("NODE_BY_BEGIN_POSITION", typeSolver);
+        assertEquals(true, res.isSolved());
+        assertEquals(true, res.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void testSolveSymbolToInheritedPrivateField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("parentNode", typeSolver);
+        assertEquals(false, res.isSolved());
+    }
+
+    ///
+    /// Assignability
+    ///
+
+    // boolean isAssignableBy(Type type);
+
+    // boolean canBeAssignedTo(TypeDeclaration other)
+
+    // boolean isAssignableBy(TypeDeclaration other);
+
+    ///
+    /// Annotations
+    ///
+
+    // hasDirectlyAnnotation
+
+    // hasAnnotation
+
+    ///
+    ///
+    ///
+
+    // List<TypeParameterDeclaration> getTypeParameters();
+
+    // AccessLevel accessLevel();
+
+    ///
+    /// Containment
+    ///
+
+    // Set<TypeDeclaration> internalTypes()
+
+    // Optional<TypeDeclaration> containerType()*/
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclarationTest.java
new file mode 100644
index 0000000..cf5e580
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclarationTest.java
@@ -0,0 +1,826 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javaparsermodel.declarations;
+
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavaParserInterfaceDeclarationTest extends AbstractTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        File srcNewCode = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+        CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver();
+        combinedTypeSolverNewCode.add(new ReflectionTypeSolver());
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(srcNewCode));
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        typeSolver = combinedTypeSolverNewCode;
+    }
+
+    ///
+    /// Test misc
+    ///
+
+    @Test
+    public void testIsClass() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(false, nodeWithAnnotations.isClass());
+    }
+
+    @Test
+    public void testIsInterface() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(true, nodeWithAnnotations.isInterface());
+    }
+
+    @Test
+    public void testIsEnum() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(false, nodeWithAnnotations.isEnum());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(false, nodeWithAnnotations.isTypeParameter());
+    }
+
+    @Test
+    public void testIsType() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(true, nodeWithAnnotations.isType());
+    }
+
+    @Test
+    public void testAsType() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(nodeWithAnnotations, nodeWithAnnotations.asType());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsClass() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(nodeWithAnnotations, nodeWithAnnotations.asClass());
+    }
+
+    @Test
+    public void testAsInterface() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(nodeWithAnnotations, nodeWithAnnotations.asInterface());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsEnum() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        nodeWithAnnotations.asEnum();
+    }
+
+    @Test
+    public void testGetPackageName() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals("com.github.javaparser.ast.nodeTypes", nodeWithAnnotations.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals("NodeWithAnnotations", nodeWithAnnotations.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", nodeWithAnnotations.getQualifiedName());
+    }
+
+    ///
+    /// Test ancestors
+    ///
+
+    /*@Test
+    public void testGetSuperclassWithoutTypeParameters() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals("com.github.javaparser.ast.Node", compilationUnit.getSuperClass().getQualifiedName());
+    }
+
+    @Test
+    public void testGetSuperclassWithTypeParameters() {
+        JavaParserClassDeclaration compilationUnit = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", compilationUnit.getSuperClass().getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", compilationUnit.getSuperClass().typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithoutTypeParameters() {
+        JavaParserClassDeclaration cu = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(3, constructorDeclaration.getAllSuperClasses().size());
+
+        ReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(2);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+    }
+
+    @Test
+    public void testGetInterfacesWithoutParameters() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(ImmutableSet.of(), compilationUnit.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavaParserClassDeclaration coid = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.DocumentableNode"), coid.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetInterfacesWithParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(7, constructorDeclaration.getInterfaces().size());
+
+        ReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllInterfacesWithoutParameters() {
+        JavaParserInterfaceDeclaration nodeWithAnnotations = (JavaParserInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable"), compilationUnit.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavaParserClassDeclaration coid = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.NamedNode", "com.github.javaparser.ast.body.AnnotableNode", "com.github.javaparser.ast.DocumentableNode"), coid.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllInterfacesWithParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(9, constructorDeclaration.getAllInterfaces().size());
+
+        ReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(7);
+        assertEquals("java.lang.Cloneable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAncestorsWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(8, constructorDeclaration.getAncestors().size());
+
+        ReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllAncestorsWithoutTypeParameters() {
+        JavaParserClassDeclaration cu = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllAncestors().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllAncestorsWithTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(12, constructorDeclaration.getAllAncestors().size());
+
+        ReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(2);
+        assertEquals("java.lang.Cloneable", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(4);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(9);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(10);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(11);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    ///
+    /// Test fields
+    ///
+
+    @Test
+    public void testGetFieldForExistingField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        FieldDeclaration fieldDeclaration = null;
+
+        // declared field
+        fieldDeclaration = constructorDeclaration.getField("modifiers");
+        assertEquals("modifiers", fieldDeclaration.getName());
+        assertEquals("java.util.EnumSet", fieldDeclaration.getType().asReferenceType().getQualifiedName());
+        assertEquals(AccessLevel.PRIVATE, fieldDeclaration.accessLevel());
+        assertEquals(false, fieldDeclaration.isStatic());
+
+        // inherited field
+        fieldDeclaration = constructorDeclaration.getField("annotations");
+        assertEquals("annotations", fieldDeclaration.getName());
+        assertEquals("java.util.List", fieldDeclaration.getType().asReferenceType().getQualifiedName());
+        assertEquals(AccessLevel.PRIVATE, fieldDeclaration.accessLevel());
+    }
+
+    @Test(expected = UnsolvedSymbolException.class)
+    public void testGetFieldForUnexistingField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        constructorDeclaration.getField("unexisting");
+    }
+
+    @Test
+    public void testGetAllFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getAllFields();
+        assertEquals(16, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(6);
+        assertEquals("annotations", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(7);
+        assertEquals("NODE_BY_BEGIN_POSITION", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(8);
+        assertEquals("range", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(9);
+        assertEquals("parentNode", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(10);
+        assertEquals("childrenNodes", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(11);
+        assertEquals("orphanComments", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(12);
+        assertEquals("userData", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(13);
+        assertEquals("comment", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(14);
+        assertEquals("ABSOLUTE_BEGIN_LINE", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(15);
+        assertEquals("ABSOLUTE_END_LINE", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetAllStaticFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getAllStaticFields();
+        assertEquals(3, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("NODE_BY_BEGIN_POSITION", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("ABSOLUTE_BEGIN_LINE", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("ABSOLUTE_END_LINE", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetAllNonStaticFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getAllNonStaticFields();
+        assertEquals(13, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(6);
+        assertEquals("annotations", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(7);
+        assertEquals("range", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(8);
+        assertEquals("parentNode", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(9);
+        assertEquals("childrenNodes", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(10);
+        assertEquals("orphanComments", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(11);
+        assertEquals("userData", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(12);
+        assertEquals("comment", fieldDeclaration.getName());
+    }
+
+    @Test
+    public void testGetDeclaredFields() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<FieldDeclaration> allFields = constructorDeclaration.getDeclaredFields();
+        assertEquals(6, allFields.size());
+
+        FieldDeclaration fieldDeclaration = null;
+
+        fieldDeclaration = allFields.get(0);
+        assertEquals("modifiers", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(1);
+        assertEquals("typeParameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(2);
+        assertEquals("name", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(3);
+        assertEquals("parameters", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(4);
+        assertEquals("throws_", fieldDeclaration.getName());
+
+        fieldDeclaration = allFields.get(5);
+        assertEquals("body", fieldDeclaration.getName());
+    }
+
+    ///
+    /// Test methods
+    ///
+
+    @Test
+    public void testGetDeclaredMethods() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        Set<MethodDeclaration> allMethods = constructorDeclaration.getDeclaredMethods();
+        assertEquals(20, allMethods.size());
+
+        List<MethodDeclaration> sortedMethods = allMethods.stream()
+                .sorted((o1, o2) -> o1.getQualifiedSignature().compareTo(o2.getQualifiedSignature()))
+                .collect(Collectors.toList());
+
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)", sortedMethods.get(0).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)", sortedMethods.get(1).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getBody()", sortedMethods.get(2).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString()", sortedMethods.get(3).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean)", sortedMethods.get(4).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)", sortedMethods.get(5).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getJavaDoc()", sortedMethods.get(6).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()", sortedMethods.get(7).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getName()", sortedMethods.get(8).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getNameExpr()", sortedMethods.get(9).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()", sortedMethods.get(10).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()", sortedMethods.get(11).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()", sortedMethods.get(12).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)", sortedMethods.get(13).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)", sortedMethods.get(14).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)", sortedMethods.get(15).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)", sortedMethods.get(16).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)", sortedMethods.get(17).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)", sortedMethods.get(18).getQualifiedSignature());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)", sortedMethods.get(19).getQualifiedSignature());
+    }
+
+    @Test
+    public void testGetAllMethods() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        Set<MethodUsage> allMethods = constructorDeclaration.getAllMethods();
+
+        List<MethodUsage> sortedMethods = allMethods.stream()
+                .sorted((o1, o2) -> o1.getQualifiedSignature().compareTo(o2.getQualifiedSignature()))
+                .collect(Collectors.toList());
+
+        List<String> signatures = sortedMethods.stream().map(m -> m.getQualifiedSignature()).collect(Collectors.toList());
+
+        assertEquals(ImmutableList.of("com.github.javaparser.ast.Node.addOrphanComment(com.github.javaparser.ast.comments.Comment)",
+                "com.github.javaparser.ast.Node.clone()",
+                "com.github.javaparser.ast.Node.contains(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.equals(java.lang.Object)",
+                "com.github.javaparser.ast.Node.getAllContainedComments()",
+                "com.github.javaparser.ast.Node.getBegin()",
+                "com.github.javaparser.ast.Node.getChildrenNodes()",
+                "com.github.javaparser.ast.Node.getComment()",
+                "com.github.javaparser.ast.Node.getEnd()",
+                "com.github.javaparser.ast.Node.getNodesByType(java.lang.Class<N>)",
+                "com.github.javaparser.ast.Node.getOrphanComments()",
+                "com.github.javaparser.ast.Node.getParentNode()",
+                "com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)",
+                "com.github.javaparser.ast.Node.getRange()",
+                "com.github.javaparser.ast.Node.getUserData(com.github.javaparser.ast.UserDataKey<M>)",
+                "com.github.javaparser.ast.Node.hasComment()",
+                "com.github.javaparser.ast.Node.hashCode()",
+                "com.github.javaparser.ast.Node.isPositionedAfter(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.isPositionedBefore(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)",
+                "com.github.javaparser.ast.Node.setBegin(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setBlockComment(java.lang.String)",
+                "com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)",
+                "com.github.javaparser.ast.Node.setEnd(com.github.javaparser.Position)",
+                "com.github.javaparser.ast.Node.setLineComment(java.lang.String)",
+                "com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)",
+                "com.github.javaparser.ast.Node.setRange(com.github.javaparser.Range)",
+                "com.github.javaparser.ast.Node.setUserData(com.github.javaparser.ast.UserDataKey<M>, M)",
+                "com.github.javaparser.ast.Node.toString()",
+                "com.github.javaparser.ast.Node.toStringWithoutComments()",
+                "com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)",
+                "com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()",
+                "com.github.javaparser.ast.body.BodyDeclaration.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getBody()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getJavaDoc()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getName()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getNameExpr()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)",
+                "com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addMarkerAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addMarkerAnnotation(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addSingleMemberAnnotation(java.lang.Class<? extends java.lang.annotation.Annotation>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addSingleMemberAnnotation(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotationByClass(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotationByName(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.isAnnotationPresent(java.lang.Class<? extends java.lang.annotation.Annotation>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.isAnnotationPresent(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.createBody()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.setJavaDocComment(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.addModifier(com.github.javaparser.ast.Modifier...)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isAbstract()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isFinal()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isNative()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isPrivate()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isProtected()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isPublic()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStatic()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStrictfp()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isSynchronized()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isTransient()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isVolatile()",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.body.Parameter)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.type.Type, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(java.lang.Class<?>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.body.Parameter)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.type.Type, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(java.lang.Class<?>, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(java.lang.String, java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByName(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByType(java.lang.Class<?>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParamByType(java.lang.String)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.addThrows(com.github.javaparser.ast.type.ReferenceType)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.addThrows(java.lang.Class<? extends java.lang.Throwable>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)",
+                "com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.String)",
+                "java.lang.Object.finalize()",
+                "java.lang.Object.getClass()",
+                "java.lang.Object.notify()",
+                "java.lang.Object.notifyAll()",
+                "java.lang.Object.registerNatives()",
+                "java.lang.Object.wait()",
+                "java.lang.Object.wait(long)",
+                "java.lang.Object.wait(long, int)"), signatures);
+    }
+
+    ///
+    /// Test constructors
+    ///
+
+    @Test
+    public void testGetConstructors() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        List<ConstructorDeclaration> constructors = constructorDeclaration.getConstructors();
+        assertEquals(4, constructors.size());
+
+        assertEquals("ConstructorDeclaration()", constructors.get(0).getSignature());
+        assertEquals("ConstructorDeclaration(java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.lang.String)", constructors.get(1).getSignature());
+        assertEquals("ConstructorDeclaration(java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.String, java.util.List<com.github.javaparser.ast.body.Parameter>, java.util.List<com.github.javaparser.ast.type.ReferenceType>, com.github.javaparser.ast.stmt.BlockStmt)", constructors.get(2).getSignature());
+        assertEquals("ConstructorDeclaration(com.github.javaparser.Range, java.util.EnumSet<com.github.javaparser.ast.Modifier>, java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.String, java.util.List<com.github.javaparser.ast.body.Parameter>, java.util.List<com.github.javaparser.ast.type.ReferenceType>, com.github.javaparser.ast.stmt.BlockStmt)", constructors.get(3).getSignature());
+    }
+
+    ///
+    /// Resolution
+    ///
+
+    //SymbolReference<MethodDeclaration> solveMethod(String name, List<Type> parameterTypes);
+    @Test
+    public void testSolveMethodExisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<MethodDeclaration> res = null;
+
+        res = constructorDeclaration.solveMethod("isStatic", ImmutableList.of());
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.isStatic()", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(RuntimeException.class.getClass(), typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(String.class, typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.String)", res.getCorrespondingDeclaration().getQualifiedSignature());
+
+        // This is solved because it is raw
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(ReflectionFactory.typeUsageFor(Class.class, typeSolverNewCode)));
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.Class<? extends java.lang.Throwable>)", res.getCorrespondingDeclaration().getQualifiedSignature());
+    }
+
+    @Test
+    public void testSolveMethodNotExisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<MethodDeclaration> res = null;
+
+        res = constructorDeclaration.solveMethod("unexistingMethod", ImmutableList.of());
+        assertEquals(false, res.isSolved());
+
+        res = constructorDeclaration.solveMethod("isStatic", ImmutableList.of(PrimitiveType.BOOLEAN));
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveMethodNotExistingBecauseOfTypeParameters() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<MethodDeclaration> res = null;
+
+        ReferenceType stringType = (ReferenceType) ReflectionFactory.typeUsageFor(String.class, typeSolverNewCode);
+        ReferenceType rawClassType = (ReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolverNewCode);
+        ReferenceType classOfStringType = (ReferenceType) rawClassType.replaceTypeVariables("T", stringType);
+        res = constructorDeclaration.solveMethod("isThrows", ImmutableList.of(classOfStringType));
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveSymbolUnexisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("unexisting", typeSolver);
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveSymbolToDeclaredField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("name", typeSolver);
+        assertEquals(true, res.isSolved());
+        assertEquals(true, res.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void testSolveSymbolToInheritedPublicField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("NODE_BY_BEGIN_POSITION", typeSolver);
+        assertEquals(true, res.isSolved());
+        assertEquals(true, res.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void testSolveSymbolToInheritedPrivateField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ValueDeclaration> res = constructorDeclaration.solveSymbol("parentNode", typeSolver);
+        assertEquals(false, res.isSolved());
+    }
+
+    ///
+    /// Assignability
+    ///
+
+    // boolean isAssignableBy(Type type);
+
+    // boolean canBeAssignedTo(TypeDeclaration other)
+
+    // boolean isAssignableBy(TypeDeclaration other);
+
+    ///
+    /// Annotations
+    ///
+
+    // hasDirectlyAnnotation
+
+    // hasAnnotation
+
+    ///
+    ///
+    ///
+
+    // List<TypeParameterDeclaration> getTypeParameters();
+
+    // AccessLevel accessLevel();
+
+    ///
+    /// Containment
+    ///
+
+    // Set<TypeDeclaration> internalTypes()
+
+    // Optional<TypeDeclaration> containerType()*/
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/Issue257.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/Issue257.java
new file mode 100644
index 0000000..460b516
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/Issue257.java
@@ -0,0 +1,47 @@
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class Issue257 extends AbstractTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() throws IOException {
+        String pathToJar = adaptPath("src/test/resources/issue257/issue257.jar");
+        File jar = new File(pathToJar);
+        typeSolver = new CombinedTypeSolver(new JarTypeSolver(jar.getAbsolutePath()), new ReflectionTypeSolver());
+    }
+
+    @Test
+    public void verifyBCanBeSolved() throws FileNotFoundException {
+        typeSolver.solveType("net.testbug.B");
+    }
+
+    @Test
+    public void issue257() throws FileNotFoundException {
+        String pathToSourceFile = adaptPath("src/test/resources/issue257/A.java.txt");
+        CompilationUnit cu = JavaParser.parse(new File(pathToSourceFile));
+        Statement statement = cu.getClassByName("A").get().getMethodsByName("run").get(0).getBody().get().getStatement(0);
+        ExpressionStmt expressionStmt = (ExpressionStmt)statement;
+        Expression expression = expressionStmt.getExpression();
+        JavaParserFacade.get(typeSolver).getType(expression);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclarationTest.java
new file mode 100644
index 0000000..9f55977
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclarationTest.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavassistClassDeclarationTest extends AbstractTest {
+
+    private TypeSolver typeSolver;
+
+    private TypeSolver newTypeSolver;
+
+    @Before
+    public void setup() throws IOException {
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToJar), new ReflectionTypeSolver());
+
+        String newPathToJar = adaptPath("src/test/resources/javaparser-core-3.0.0-alpha.2.jar");
+        newTypeSolver = new CombinedTypeSolver(new JarTypeSolver(newPathToJar), new ReflectionTypeSolver());
+    }
+
+    ///
+    /// Test misc
+    ///
+
+    @Test
+    public void testIsClass() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(true, compilationUnit.isClass());
+    }
+
+    @Test
+    public void testIsInterface() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(false, compilationUnit.isInterface());
+    }
+
+    @Test
+    public void testIsEnum() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(false, compilationUnit.isEnum());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(false, compilationUnit.isTypeParameter());
+    }
+
+    @Test
+    public void testIsType() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(true, compilationUnit.isType());
+    }
+
+    @Test
+    public void testAsType() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(compilationUnit, compilationUnit.asType());
+    }
+
+    @Test
+    public void testAsClass() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(compilationUnit, compilationUnit.asClass());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsInterface() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        compilationUnit.asInterface();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsEnum() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        compilationUnit.asEnum();
+    }
+
+    @Test
+    public void testGetPackageName() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast", compilationUnit.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("CompilationUnit", compilationUnit.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast.CompilationUnit", compilationUnit.getQualifiedName());
+    }
+
+    ///
+    /// Test ancestors
+    ///
+
+    @Test
+    public void testGetSuperclass() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast.Node", compilationUnit.getSuperClass().getQualifiedName());
+    }
+
+    @Test
+    public void testGetSuperclassWithoutTypeParameters() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast.Node", compilationUnit.getSuperClass().getQualifiedName());
+    }
+
+    @Test
+    public void testGetSuperclassWithTypeParameters() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", compilationUnit.getSuperClass().getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", compilationUnit.getSuperClass().typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllSuperclasses() {
+        JavassistClassDeclaration cu = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllAncestors() {
+        JavassistClassDeclaration cu = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllAncestors().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetInterfaces() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of(), compilationUnit.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavassistClassDeclaration coid = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.DocumentableNode"), coid.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllInterfaces() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of(), compilationUnit.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavassistClassDeclaration coid = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.NamedNode", "com.github.javaparser.ast.body.AnnotableNode", "com.github.javaparser.ast.DocumentableNode"), coid.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithoutTypeParameters() {
+        JavassistClassDeclaration cu = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithTypeParameters() {
+        JavassistClassDeclaration constructorDeclaration = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(3, constructorDeclaration.getAllSuperClasses().size());
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("com.github.javaparser.ast.body.BodyDeclaration")));
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("com.github.javaparser.ast.Node")));
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("java.lang.Object")));
+
+        ResolvedReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(2);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+    }
+
+    @Test
+    public void testGetInterfacesWithoutParameters() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of(), compilationUnit.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavassistClassDeclaration coid = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.nodeTypes.NodeWithExtends", "com.github.javaparser.ast.nodeTypes.NodeWithImplements"), coid.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetInterfacesWithParameters() {
+        JavassistClassDeclaration constructorDeclaration = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(7, constructorDeclaration.getInterfaces().size());
+
+        ResolvedReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllInterfacesWithoutParameters() {
+        JavassistClassDeclaration compilationUnit = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable"), compilationUnit.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        JavassistClassDeclaration coid = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.nodeTypes.NodeWithExtends",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations",
+                "java.lang.Cloneable",
+                "com.github.javaparser.ast.nodeTypes.NodeWithImplements",
+                "com.github.javaparser.ast.nodeTypes.NodeWithName",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers",
+                "com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc",
+                "com.github.javaparser.ast.nodeTypes.NodeWithMembers"), coid.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllInterfacesWithParameters() {
+        JavassistClassDeclaration constructorDeclaration = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(9, constructorDeclaration.getAllInterfaces().size());
+
+        ResolvedReferenceType interfaze = null;
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(7);
+        assertEquals("java.lang.Cloneable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAncestorsWithTypeParameters() {
+        JavassistClassDeclaration constructorDeclaration = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(8, constructorDeclaration.getAncestors().size());
+
+        ResolvedReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllAncestorsWithoutTypeParameters() {
+        JavassistClassDeclaration cu = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllAncestors().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllAncestorsWithTypeParameters() {
+        JavassistClassDeclaration constructorDeclaration = (JavassistClassDeclaration) newTypeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(12, constructorDeclaration.getAllAncestors().size());
+
+        ResolvedReferenceType ancestor = null;
+
+        ancestor = constructorDeclaration.getAllAncestors().get(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(1);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(2);
+        assertEquals("java.lang.Cloneable", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(4);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithName.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(8);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(9);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(10);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrowable", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrowable.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllAncestors().get(11);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.T").get().asReferenceType().getQualifiedName());
+    }
+    
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclarationTest.java
new file mode 100644
index 0000000..8e6d66f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclarationTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedEnumDeclaration;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavassistEnumDeclarationTest extends AbstractTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() throws IOException {
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-3.0.0-alpha.2.jar");
+        typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToJar), new ReflectionTypeSolver());
+    }
+
+    ///
+    /// Test misc
+    ///
+
+    @Test
+    public void testIsClass() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isClass());
+    }
+
+    @Test
+    public void testIsInterface() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isInterface());
+    }
+
+    @Test
+    public void testIsEnum() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(true, modifier.isEnum());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isTypeParameter());
+    }
+
+    @Test
+    public void testIsType() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(true, modifier.isType());
+    }
+
+    @Test
+    public void testAsType() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(modifier, modifier.asType());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsClass() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        modifier.asClass();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsInterface() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        modifier.asInterface();
+    }
+
+    @Test
+    public void testAsEnum() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(modifier, modifier.asEnum());
+    }
+
+    @Test
+    public void testGetPackageName() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("com.github.javaparser.ast", modifier.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("Modifier", modifier.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        ResolvedEnumDeclaration modifier = (ResolvedEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("com.github.javaparser.ast.Modifier", modifier.getQualifiedName());
+    }
+
+    ///
+    /// Test ancestors
+    ///
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclarationTest.java
new file mode 100644
index 0000000..a593ec4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclarationTest.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.javassistmodel;
+
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavassistInterfaceDeclarationTest extends AbstractTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() throws IOException {
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-3.0.0-alpha.2.jar");
+        typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToJar), new ReflectionTypeSolver());
+    }
+
+    ///
+    /// Test misc
+    ///
+
+    @Test
+    public void testIsClass() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(false, nodeWithAnnotations.isClass());
+    }
+
+    @Test
+    public void testIsInterface() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(true, nodeWithAnnotations.isInterface());
+    }
+
+    @Test
+    public void testIsEnum() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(false, nodeWithAnnotations.isEnum());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(false, nodeWithAnnotations.isTypeParameter());
+    }
+
+    @Test
+    public void testIsType() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(true, nodeWithAnnotations.isType());
+    }
+
+    @Test
+    public void testAsType() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(nodeWithAnnotations, nodeWithAnnotations.asType());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsClass() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        nodeWithAnnotations.asClass();
+    }
+
+    @Test
+    public void testAsInterface() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals(nodeWithAnnotations, nodeWithAnnotations.asInterface());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsEnum() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        nodeWithAnnotations.asEnum();
+    }
+
+    @Test
+    public void testGetPackageName() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals("com.github.javaparser.ast.nodeTypes", nodeWithAnnotations.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals("NodeWithAnnotations", nodeWithAnnotations.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        JavassistInterfaceDeclaration nodeWithAnnotations = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations");
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", nodeWithAnnotations.getQualifiedName());
+    }
+
+    ///
+    /// Test ancestors
+    ///
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/logic/FunctionInterfaceLogicTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/logic/FunctionInterfaceLogicTest.java
new file mode 100644
index 0000000..bda2cc9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/logic/FunctionInterfaceLogicTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import static org.junit.Assert.assertEquals;
+
+public class FunctionInterfaceLogicTest {
+
+    @Test
+    public void testGetFunctionalMethodNegativeCaseOnClass() {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        assertEquals(false, FunctionalInterfaceLogic.getFunctionalMethod(string).isPresent());
+    }
+
+    @Test
+    public void testGetFunctionalMethodPositiveCasesOnInterfaces() {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType function = new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Function.class, typeSolver), typeSolver);
+        assertEquals(true, FunctionalInterfaceLogic.getFunctionalMethod(function).isPresent());
+        assertEquals("apply", FunctionalInterfaceLogic.getFunctionalMethod(function).get().getName());
+        ResolvedType consumer = new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Consumer.class, typeSolver), typeSolver);
+        assertEquals(true, FunctionalInterfaceLogic.getFunctionalMethod(consumer).isPresent());
+        assertEquals("accept", FunctionalInterfaceLogic.getFunctionalMethod(consumer).get().getName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/logic/InferenceContextTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/logic/InferenceContextTest.java
new file mode 100644
index 0000000..3af207f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/logic/InferenceContextTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.logic;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.MyObjectProvider;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class InferenceContextTest {
+
+    private TypeSolver typeSolver;
+    private ResolvedReferenceType string;
+    private ResolvedReferenceType object;
+    private ResolvedReferenceType listOfString;
+    private ResolvedReferenceType listOfE;
+    private ResolvedTypeParameterDeclaration tpE;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        listOfString = listOf(string);
+        tpE = mock(ResolvedTypeParameterDeclaration.class);
+        when(tpE.getName()).thenReturn("T");
+
+        listOfE = listOf(new ResolvedTypeVariable(tpE));
+    }
+
+    private ResolvedReferenceType listOf(ResolvedType elementType) {
+        return new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(List.class, typeSolver), ImmutableList.of(elementType), typeSolver);
+    }
+
+    @Test
+    public void noVariablesArePlacedWhenNotNeeded() {
+        ResolvedType result = new InferenceContext(MyObjectProvider.INSTANCE).addPair(object, string);
+        assertEquals(object, result);
+    }
+
+    @Test
+    public void placingASingleVariableTopLevel() {
+        ResolvedType result = new InferenceContext(MyObjectProvider.INSTANCE).addPair(new ResolvedTypeVariable(tpE), listOfString);
+        assertEquals(new InferenceVariableType(0, MyObjectProvider.INSTANCE), result);
+    }
+
+    @Test
+    public void placingASingleVariableInside() {
+        ResolvedType result = new InferenceContext(MyObjectProvider.INSTANCE).addPair(listOfE, listOfString);
+        assertEquals(listOf(new InferenceVariableType(0, MyObjectProvider.INSTANCE)), result);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ArrayTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ArrayTypeTest.java
new file mode 100644
index 0000000..1d8e4dd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ArrayTypeTest.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ArrayTypeTest {
+
+    private ResolvedArrayType arrayOfBooleans;
+    private ResolvedArrayType arrayOfStrings;
+    private ResolvedArrayType arrayOfListOfA;
+    private ResolvedArrayType arrayOfListOfStrings;
+    private ReferenceTypeImpl OBJECT;
+    private ReferenceTypeImpl STRING;
+    private TypeSolver typeSolver;
+    private ResolvedTypeParameterDeclaration tpA;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        OBJECT = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        STRING = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        arrayOfBooleans = new ResolvedArrayType(ResolvedPrimitiveType.BOOLEAN);
+        arrayOfStrings = new ResolvedArrayType(STRING);
+        tpA = ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList());
+        arrayOfListOfA = new ResolvedArrayType(new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(new ResolvedTypeVariable(tpA)), typeSolver));
+        arrayOfListOfStrings = new ResolvedArrayType(new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)), typeSolver));
+    }
+
+    @Test
+    public void testIsArray() {
+        assertEquals(true, arrayOfBooleans.isArray());
+        assertEquals(true, arrayOfStrings.isArray());
+    }
+
+    @Test
+    public void testIsPrimitive() {
+        assertEquals(false, arrayOfBooleans.isPrimitive());
+        assertEquals(false, arrayOfStrings.isPrimitive());
+    }
+
+    @Test
+    public void testIsNull() {
+        assertEquals(false, arrayOfBooleans.isNull());
+        assertEquals(false, arrayOfStrings.isNull());
+    }
+
+    @Test
+    public void testIsReference() {
+        assertEquals(true, arrayOfBooleans.isReference());
+        assertEquals(true, arrayOfStrings.isReference());
+    }
+
+    @Test
+    public void testIsReferenceType() {
+        assertEquals(false, arrayOfBooleans.isReferenceType());
+        assertEquals(false, arrayOfStrings.isReferenceType());
+    }
+
+    @Test
+    public void testIsVoid() {
+        assertEquals(false, arrayOfBooleans.isVoid());
+        assertEquals(false, arrayOfStrings.isVoid());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        assertEquals(false, arrayOfBooleans.isTypeVariable());
+        assertEquals(false, arrayOfStrings.isTypeVariable());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsReferenceTypeUsage() {
+        arrayOfBooleans.asReferenceType();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsTypeParameter() {
+        arrayOfBooleans.asTypeParameter();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsPrimitive() {
+        arrayOfBooleans.asPrimitive();
+    }
+
+    @Test
+    public void testAsArrayTypeUsage() {
+        assertTrue(arrayOfBooleans == arrayOfBooleans.asArrayType());
+        assertTrue(arrayOfStrings == arrayOfStrings.asArrayType());
+        assertTrue(arrayOfListOfA == arrayOfListOfA.asArrayType());
+    }
+
+    @Test
+    public void testAsDescribe() {
+        assertEquals("boolean[]", arrayOfBooleans.describe());
+        assertEquals("java.lang.String[]", arrayOfStrings.describe());
+    }
+
+    @Test
+    public void testReplaceParam() {
+        assertTrue(arrayOfBooleans == arrayOfBooleans.replaceTypeVariables(tpA, OBJECT));
+        assertTrue(arrayOfStrings == arrayOfStrings.replaceTypeVariables(tpA, OBJECT));
+        assertEquals(arrayOfListOfStrings, arrayOfListOfStrings.replaceTypeVariables(tpA, OBJECT));
+        ResolvedArrayType arrayOfListOfObjects = new ResolvedArrayType(new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(OBJECT), typeSolver));
+        assertEquals(true, arrayOfListOfA.replaceTypeVariables(tpA, OBJECT).isArray());
+        assertEquals(ImmutableList.of(OBJECT),
+                arrayOfListOfA.replaceTypeVariables(tpA, OBJECT).asArrayType().getComponentType()
+                        .asReferenceType().typeParametersValues());
+        assertEquals(new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                arrayOfListOfA.replaceTypeVariables(tpA, OBJECT).asArrayType().getComponentType()
+                        .asReferenceType().getTypeDeclaration());
+        assertEquals(new ReferenceTypeImpl(
+                        new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                        ImmutableList.of(OBJECT), typeSolver),
+                arrayOfListOfA.replaceTypeVariables(tpA, OBJECT).asArrayType().getComponentType());
+        assertEquals(arrayOfListOfObjects, arrayOfListOfA.replaceTypeVariables(tpA, OBJECT));
+        assertEquals(arrayOfListOfStrings, arrayOfListOfA.replaceTypeVariables(tpA, STRING));
+        assertTrue(arrayOfListOfA != arrayOfListOfA.replaceTypeVariables(tpA, OBJECT));
+    }
+
+    @Test
+    public void testIsAssignableBy() {
+        assertEquals(false, arrayOfBooleans.isAssignableBy(OBJECT));
+        assertEquals(false, arrayOfBooleans.isAssignableBy(STRING));
+        assertEquals(false, arrayOfBooleans.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(false, arrayOfBooleans.isAssignableBy(ResolvedVoidType.INSTANCE));
+
+        assertEquals(true, arrayOfBooleans.isAssignableBy(arrayOfBooleans));
+        assertEquals(false, arrayOfBooleans.isAssignableBy(arrayOfStrings));
+        assertEquals(false, arrayOfBooleans.isAssignableBy(arrayOfListOfA));
+        assertEquals(false, arrayOfBooleans.isAssignableBy(arrayOfListOfStrings));
+        assertEquals(false, arrayOfStrings.isAssignableBy(arrayOfBooleans));
+        assertEquals(true, arrayOfStrings.isAssignableBy(arrayOfStrings));
+        assertEquals(false, arrayOfStrings.isAssignableBy(arrayOfListOfA));
+        assertEquals(false, arrayOfStrings.isAssignableBy(arrayOfListOfStrings));
+        assertEquals(false, arrayOfListOfA.isAssignableBy(arrayOfBooleans));
+        assertEquals(false, arrayOfListOfA.isAssignableBy(arrayOfStrings));
+        assertEquals(true, arrayOfListOfA.isAssignableBy(arrayOfListOfA));
+        assertEquals(false, arrayOfListOfA.isAssignableBy(arrayOfListOfStrings));
+        assertEquals(false, arrayOfListOfStrings.isAssignableBy(arrayOfBooleans));
+        assertEquals(false, arrayOfListOfStrings.isAssignableBy(arrayOfStrings));
+        assertEquals(false, arrayOfListOfStrings.isAssignableBy(arrayOfListOfA));
+        assertEquals(true, arrayOfListOfStrings.isAssignableBy(arrayOfListOfStrings));
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/NullTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/NullTypeTest.java
new file mode 100644
index 0000000..4df2460
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/NullTypeTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class NullTypeTest {
+
+    private ResolvedArrayType arrayOfBooleans;
+    private ResolvedArrayType arrayOfListOfA;
+    private ReferenceTypeImpl OBJECT;
+    private ReferenceTypeImpl STRING;
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        OBJECT = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        STRING = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        arrayOfBooleans = new ResolvedArrayType(ResolvedPrimitiveType.BOOLEAN);
+        arrayOfListOfA = new ResolvedArrayType(new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(new ResolvedTypeVariable(ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList()))), typeSolver));
+    }
+
+    @Test
+    public void testIsArray() {
+        assertEquals(false, NullType.INSTANCE.isArray());
+    }
+
+    @Test
+    public void testIsPrimitive() {
+        assertEquals(false, NullType.INSTANCE.isPrimitive());
+    }
+
+    @Test
+    public void testIsNull() {
+        assertEquals(true, NullType.INSTANCE.isNull());
+    }
+
+    @Test
+    public void testIsReference() {
+        assertEquals(true, NullType.INSTANCE.isReference());
+    }
+
+    @Test
+    public void testIsReferenceType() {
+        assertEquals(false, NullType.INSTANCE.isReferenceType());
+    }
+
+    @Test
+    public void testIsVoid() {
+        assertEquals(false, NullType.INSTANCE.isVoid());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        assertEquals(false, NullType.INSTANCE.isTypeVariable());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsReferenceTypeUsage() {
+        NullType.INSTANCE.asReferenceType();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsTypeParameter() {
+        NullType.INSTANCE.asTypeParameter();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsArrayTypeUsage() {
+        NullType.INSTANCE.asArrayType();
+    }
+
+    @Test
+    public void testAsDescribe() {
+        assertEquals("null", NullType.INSTANCE.describe());
+    }
+
+    @Test
+    public void testIsAssignableBy() {
+        try {
+            assertEquals(false, NullType.INSTANCE.isAssignableBy(NullType.INSTANCE));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, NullType.INSTANCE.isAssignableBy(OBJECT));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, NullType.INSTANCE.isAssignableBy(STRING));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, NullType.INSTANCE.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, NullType.INSTANCE.isAssignableBy(ResolvedVoidType.INSTANCE));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/PrimitiveTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/PrimitiveTypeTest.java
new file mode 100644
index 0000000..3679dbd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/PrimitiveTypeTest.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class PrimitiveTypeTest {
+
+    private ResolvedArrayType arrayOfBooleans;
+    private ResolvedArrayType arrayOfListOfA;
+    private ReferenceTypeImpl OBJECT;
+    private ReferenceTypeImpl STRING;
+    private TypeSolver typeSolver;
+
+    private ReferenceTypeImpl booleanBox;
+    private ReferenceTypeImpl characterBox;
+    private ReferenceTypeImpl byteBox;
+    private ReferenceTypeImpl shortBox;
+    private ReferenceTypeImpl integerBox;
+    private ReferenceTypeImpl longBox;
+    private ReferenceTypeImpl floatBox;
+    private ReferenceTypeImpl doubleBox;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        OBJECT = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        STRING = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        arrayOfBooleans = new ResolvedArrayType(ResolvedPrimitiveType.BOOLEAN);
+        arrayOfListOfA = new ResolvedArrayType(new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(new ResolvedTypeVariable(ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList()))), typeSolver));
+
+        booleanBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Boolean.class, typeSolver), typeSolver);
+        characterBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Character.class, typeSolver), typeSolver);
+        byteBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Byte.class, typeSolver), typeSolver);
+        shortBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Short.class, typeSolver), typeSolver);
+        integerBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Integer.class, typeSolver), typeSolver);
+        longBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Long.class, typeSolver), typeSolver);
+        floatBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Float.class, typeSolver), typeSolver);
+        doubleBox = new ReferenceTypeImpl(new ReflectionClassDeclaration(Double.class, typeSolver), typeSolver);
+
+    }
+
+    @Test
+    public void testIsArray() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(false, ptu.isArray());
+        }
+    }
+
+    @Test
+    public void testIsPrimitive() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(true, ptu.isPrimitive());
+        }
+    }
+
+    @Test
+    public void testIsNull() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(false, ptu.isNull());
+        }
+    }
+
+    @Test
+    public void testIsReference() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(false, ptu.isReference());
+        }
+    }
+
+    @Test
+    public void testIsReferenceType() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(false, ptu.isReferenceType());
+        }
+    }
+
+    @Test
+    public void testIsVoid() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(false, ptu.isVoid());
+        }
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(false, ptu.isTypeVariable());
+        }
+    }
+
+    @Test
+    public void testAsReferenceTypeUsage() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            try {
+                ptu.asReferenceType();
+                fail();
+            } catch (UnsupportedOperationException e) {
+            }
+        }
+    }
+
+    @Test
+    public void testAsTypeParameter() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            try {
+                ptu.asTypeParameter();
+                fail();
+            } catch (UnsupportedOperationException e) {
+            }
+        }
+    }
+
+    @Test
+    public void testAsArrayTypeUsage() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            try {
+                ptu.asArrayType();
+                fail();
+            } catch (UnsupportedOperationException e) {
+            }
+        }
+    }
+
+    @Test
+    public void testAsDescribe() {
+        assertEquals("boolean", ResolvedPrimitiveType.BOOLEAN.describe());
+        assertEquals("char", ResolvedPrimitiveType.CHAR.describe());
+        assertEquals("byte", ResolvedPrimitiveType.BYTE.describe());
+        assertEquals("short", ResolvedPrimitiveType.SHORT.describe());
+        assertEquals("int", ResolvedPrimitiveType.INT.describe());
+        assertEquals("long", ResolvedPrimitiveType.LONG.describe());
+        assertEquals("float", ResolvedPrimitiveType.FLOAT.describe());
+        assertEquals("double", ResolvedPrimitiveType.DOUBLE.describe());
+    }
+
+    @Test
+    public void testIsAssignableByOtherPrimitiveTypes() {
+        assertEquals(true, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(true, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(true, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(true, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(true, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+
+        assertEquals(false, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(false, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, ResolvedPrimitiveType.LONG.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+
+        assertEquals(false, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, ResolvedPrimitiveType.FLOAT.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+
+        assertEquals(false, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.CHAR));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.BYTE));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+    }
+
+    @Test
+    public void testIsAssignableByBoxedTypes() {
+        assertEquals(true, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(booleanBox));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(characterBox));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(byteBox));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(shortBox));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(integerBox));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(longBox));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(floatBox));
+        assertEquals(false, ResolvedPrimitiveType.BOOLEAN.isAssignableBy(doubleBox));
+
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(booleanBox));
+        assertEquals(true, ResolvedPrimitiveType.CHAR.isAssignableBy(characterBox));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(byteBox));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(shortBox));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(integerBox));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(longBox));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(floatBox));
+        assertEquals(false, ResolvedPrimitiveType.CHAR.isAssignableBy(doubleBox));
+
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(booleanBox));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(characterBox));
+        assertEquals(true, ResolvedPrimitiveType.BYTE.isAssignableBy(byteBox));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(shortBox));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(integerBox));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(longBox));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(floatBox));
+        assertEquals(false, ResolvedPrimitiveType.BYTE.isAssignableBy(doubleBox));
+
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(booleanBox));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(characterBox));
+        assertEquals(true, ResolvedPrimitiveType.SHORT.isAssignableBy(byteBox));
+        assertEquals(true, ResolvedPrimitiveType.SHORT.isAssignableBy(shortBox));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(integerBox));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(longBox));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(floatBox));
+        assertEquals(false, ResolvedPrimitiveType.SHORT.isAssignableBy(doubleBox));
+
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(booleanBox));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(characterBox));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(byteBox));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(shortBox));
+        assertEquals(true, ResolvedPrimitiveType.INT.isAssignableBy(integerBox));
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(longBox));
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(floatBox));
+        assertEquals(false, ResolvedPrimitiveType.INT.isAssignableBy(doubleBox));
+
+        assertEquals(false, ResolvedPrimitiveType.LONG.isAssignableBy(booleanBox));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(characterBox));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(byteBox));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(shortBox));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(integerBox));
+        assertEquals(true, ResolvedPrimitiveType.LONG.isAssignableBy(longBox));
+        assertEquals(false, ResolvedPrimitiveType.LONG.isAssignableBy(floatBox));
+        assertEquals(false, ResolvedPrimitiveType.LONG.isAssignableBy(doubleBox));
+
+        assertEquals(false, ResolvedPrimitiveType.FLOAT.isAssignableBy(booleanBox));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(characterBox));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(byteBox));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(shortBox));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(integerBox));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(longBox));
+        assertEquals(true, ResolvedPrimitiveType.FLOAT.isAssignableBy(floatBox));
+        assertEquals(false, ResolvedPrimitiveType.FLOAT.isAssignableBy(doubleBox));
+
+        assertEquals(false, ResolvedPrimitiveType.DOUBLE.isAssignableBy(booleanBox));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(characterBox));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(byteBox));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(shortBox));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(integerBox));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(longBox));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(floatBox));
+        assertEquals(true, ResolvedPrimitiveType.DOUBLE.isAssignableBy(doubleBox));
+    }
+
+    @Test
+    public void testIsAssignableByAnythingElse() {
+        for (ResolvedPrimitiveType ptu : ResolvedPrimitiveType.values()) {
+            assertEquals(false, ptu.isAssignableBy(OBJECT));
+            assertEquals(false, ptu.isAssignableBy(STRING));
+            assertEquals(false, ptu.isAssignableBy(NullType.INSTANCE));
+            assertEquals(false, ptu.isAssignableBy(ResolvedVoidType.INSTANCE));
+            assertEquals(false, ptu.isAssignableBy(arrayOfBooleans));
+            assertEquals(false, ptu.isAssignableBy(arrayOfListOfA));
+        }
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeTest.java
new file mode 100644
index 0000000..3f4b318
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeTest.java
@@ -0,0 +1,600 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.*;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.stream.Stream;
+
+import static org.junit.Assert.*;
+
+public class ReferenceTypeTest {
+
+    private ReferenceTypeImpl listOfA;
+    private ReferenceTypeImpl listOfStrings;
+    private ReferenceTypeImpl linkedListOfString;
+    private ReferenceTypeImpl collectionOfString;
+    private ReferenceTypeImpl listOfWildcardExtendsString;
+    private ReferenceTypeImpl listOfWildcardSuperString;
+    private ReferenceTypeImpl object;
+    private ReferenceTypeImpl string;
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        listOfA = new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(new ResolvedTypeVariable(ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList()))), typeSolver);
+        listOfStrings = new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)), typeSolver);
+        linkedListOfString = new ReferenceTypeImpl(
+                new ReflectionClassDeclaration(LinkedList.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)), typeSolver);
+        collectionOfString = new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(Collection.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)), typeSolver);
+        listOfWildcardExtendsString = new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(ResolvedWildcard.extendsBound(string)), typeSolver);
+        listOfWildcardSuperString = new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(ResolvedWildcard.superBound(string)), typeSolver);
+    }
+
+    @Test
+    public void testDerivationOfTypeParameters() {
+        ReflectionTypeSolver typeSolver = new ReflectionTypeSolver();
+        ReferenceTypeImpl ref1 = new ReferenceTypeImpl(typeSolver.solveType(LinkedList.class.getCanonicalName()), typeSolver);
+        assertEquals(1, ref1.typeParametersValues().size());
+        assertEquals(true, ref1.typeParametersValues().get(0).isTypeVariable());
+        assertEquals("E", ref1.typeParametersValues().get(0).asTypeParameter().getName());
+    }
+
+    @Test
+    public void testIsArray() {
+        assertEquals(false, object.isArray());
+        assertEquals(false, string.isArray());
+        assertEquals(false, listOfA.isArray());
+        assertEquals(false, listOfStrings.isArray());
+    }
+
+    @Test
+    public void testIsPrimitive() {
+        assertEquals(false, object.isPrimitive());
+        assertEquals(false, string.isPrimitive());
+        assertEquals(false, listOfA.isPrimitive());
+        assertEquals(false, listOfStrings.isPrimitive());
+    }
+
+    @Test
+    public void testIsNull() {
+        assertEquals(false, object.isNull());
+        assertEquals(false, string.isNull());
+        assertEquals(false, listOfA.isNull());
+        assertEquals(false, listOfStrings.isNull());
+    }
+
+    @Test
+    public void testIsReference() {
+        assertEquals(true, object.isReference());
+        assertEquals(true, string.isReference());
+        assertEquals(true, listOfA.isReference());
+        assertEquals(true, listOfStrings.isReference());
+    }
+
+    @Test
+    public void testIsReferenceType() {
+        assertEquals(true, object.isReferenceType());
+        assertEquals(true, string.isReferenceType());
+        assertEquals(true, listOfA.isReferenceType());
+        assertEquals(true, listOfStrings.isReferenceType());
+    }
+
+    @Test
+    public void testIsVoid() {
+        assertEquals(false, object.isVoid());
+        assertEquals(false, string.isVoid());
+        assertEquals(false, listOfA.isVoid());
+        assertEquals(false, listOfStrings.isVoid());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        assertEquals(false, object.isTypeVariable());
+        assertEquals(false, string.isTypeVariable());
+        assertEquals(false, listOfA.isTypeVariable());
+        assertEquals(false, listOfStrings.isTypeVariable());
+    }
+
+    @Test
+    public void testAsReferenceTypeUsage() {
+        assertTrue(object == object.asReferenceType());
+        assertTrue(string == string.asReferenceType());
+        assertTrue(listOfA == listOfA.asReferenceType());
+        assertTrue(listOfStrings == listOfStrings.asReferenceType());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsTypeParameter() {
+        object.asTypeParameter();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsArrayTypeUsage() {
+        object.asArrayType();
+    }
+
+    @Test
+    public void testAsDescribe() {
+        assertEquals("java.lang.Object", object.describe());
+        assertEquals("java.lang.String", string.describe());
+        assertEquals("java.util.List<A>", listOfA.describe());
+        assertEquals("java.util.List<java.lang.String>", listOfStrings.describe());
+    }
+
+    @Test
+    public void testReplaceParam() {
+        ResolvedTypeParameterDeclaration tpA = ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList());
+        assertTrue(object == object.replaceTypeVariables(tpA, object));
+        assertTrue(string == string.replaceTypeVariables(tpA, object));
+        assertEquals(listOfStrings, listOfStrings.replaceTypeVariables(tpA, object));
+        assertEquals(listOfStrings, listOfA.replaceTypeVariables(tpA, string));
+    }
+
+    @Test
+    public void testIsAssignableBySimple() {
+        assertEquals(true, object.isAssignableBy(string));
+        assertEquals(false, string.isAssignableBy(object));
+        assertEquals(false, listOfStrings.isAssignableBy(listOfA));
+        assertEquals(false, listOfA.isAssignableBy(listOfStrings));
+
+        assertEquals(false, object.isAssignableBy(ResolvedVoidType.INSTANCE));
+        assertEquals(false, string.isAssignableBy(ResolvedVoidType.INSTANCE));
+        assertEquals(false, listOfStrings.isAssignableBy(ResolvedVoidType.INSTANCE));
+        assertEquals(false, listOfA.isAssignableBy(ResolvedVoidType.INSTANCE));
+
+        assertEquals(true, object.isAssignableBy(NullType.INSTANCE));
+        assertEquals(true, string.isAssignableBy(NullType.INSTANCE));
+        assertEquals(true, listOfStrings.isAssignableBy(NullType.INSTANCE));
+        assertEquals(true, listOfA.isAssignableBy(NullType.INSTANCE));
+    }
+
+    @Test
+    public void testIsAssignableByBoxedPrimitive(){
+        ResolvedReferenceType numberType = new ReferenceTypeImpl(new ReflectionClassDeclaration(Number.class, typeSolver),typeSolver);
+        ResolvedReferenceType intType = new ReferenceTypeImpl(new ReflectionClassDeclaration(Integer.class, typeSolver),typeSolver);
+        ResolvedReferenceType doubleType = new ReferenceTypeImpl(new ReflectionClassDeclaration(Double.class, typeSolver),typeSolver);
+
+        assertEquals(true,  numberType.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(true,  numberType.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+        assertEquals(true,  numberType.isAssignableBy(ResolvedPrimitiveType.SHORT));
+        assertEquals(true,  numberType.isAssignableBy(ResolvedPrimitiveType.LONG));
+        assertEquals(true,  numberType.isAssignableBy(ResolvedPrimitiveType.FLOAT));
+        assertEquals(false, numberType.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+        assertEquals(true,  intType.isAssignableBy(ResolvedPrimitiveType.INT));
+        assertEquals(true,  doubleType.isAssignableBy(ResolvedPrimitiveType.DOUBLE));
+    }
+
+    @Test
+    public void testIsAssignableByGenerics() {
+        assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString));
+        assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString));
+        assertEquals(true, listOfWildcardExtendsString.isAssignableBy(listOfStrings));
+        assertEquals(false, listOfWildcardExtendsString.isAssignableBy(listOfWildcardSuperString));
+        assertEquals(true, listOfWildcardSuperString.isAssignableBy(listOfStrings));
+        assertEquals(false, listOfWildcardSuperString.isAssignableBy(listOfWildcardExtendsString));
+    }
+
+    @Test
+    public void testIsAssignableByGenericsInheritance() {
+        assertEquals(true, collectionOfString.isAssignableBy(collectionOfString));
+        assertEquals(true, collectionOfString.isAssignableBy(listOfStrings));
+        assertEquals(true, collectionOfString.isAssignableBy(linkedListOfString));
+
+        assertEquals(false, listOfStrings.isAssignableBy(collectionOfString));
+        assertEquals(true, listOfStrings.isAssignableBy(listOfStrings));
+        assertEquals(true, listOfStrings.isAssignableBy(linkedListOfString));
+
+        assertEquals(false, linkedListOfString.isAssignableBy(collectionOfString));
+        assertEquals(false, linkedListOfString.isAssignableBy(listOfStrings));
+        assertEquals(true, linkedListOfString.isAssignableBy(linkedListOfString));
+    }
+
+    @Test
+    public void testGetAllAncestorsConsideringTypeParameters() {
+        assertTrue(linkedListOfString.getAllAncestors().contains(object));
+        assertTrue(linkedListOfString.getAllAncestors().contains(listOfStrings));
+        assertTrue(linkedListOfString.getAllAncestors().contains(collectionOfString));
+        assertFalse(linkedListOfString.getAllAncestors().contains(listOfA));
+    }
+
+    class Foo {
+
+    }
+
+    class Bar extends Foo {
+
+    }
+
+    class Bazzer<A, B, C> {
+
+    }
+
+    class MoreBazzing<A, B> extends Bazzer<B, String, A> {
+
+    }
+
+    @Test
+    public void testGetAllAncestorsConsideringGenericsCases() {
+        ReferenceTypeImpl foo = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver);
+        ReferenceTypeImpl bar = new ReferenceTypeImpl(new ReflectionClassDeclaration(Bar.class, typeSolver), typeSolver);
+        ReferenceTypeImpl left, right;
+
+        //YES MoreBazzing<Foo, Bar> e1 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                        ImmutableList.of(foo, bar), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<? extends Foo, Bar> e2 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                        ImmutableList.of(ResolvedWildcard.extendsBound(foo), bar), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<Foo, ? extends Bar> e3 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                        ImmutableList.of(foo, ResolvedWildcard.extendsBound(bar)), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<? extends Foo, ? extends Foo> e4 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                        ImmutableList.of(ResolvedWildcard.extendsBound(foo), ResolvedWildcard.extendsBound(foo)), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<? extends Foo, ? extends Foo> e5 = new MoreBazzing<Bar, Bar>();
+        left = new ReferenceTypeImpl(
+                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                ImmutableList.of(ResolvedWildcard.extendsBound(foo), ResolvedWildcard.extendsBound(foo)), typeSolver);
+        right = new ReferenceTypeImpl(
+                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                ImmutableList.of(bar, bar), typeSolver);
+        assertEquals(true, left.isAssignableBy(right));
+
+        //YES Bazzer<Object, String, String> e6 = new MoreBazzing<String, Object>();
+        left = new ReferenceTypeImpl(
+                new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                ImmutableList.of(object, string, string), typeSolver);
+        right = new ReferenceTypeImpl(
+                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                ImmutableList.of(string, object), typeSolver);
+
+        // To debug the following
+        List<ResolvedReferenceType> ancestors = right.getAllAncestors();
+        ResolvedReferenceType moreBazzingAncestor = ancestors.stream().filter(a -> a.getQualifiedName().endsWith("Bazzer")).findFirst().get();
+
+        assertEquals(true, left.isAssignableBy(right));
+
+        //YES Bazzer<String,String,String> e7 = new MoreBazzing<String, String>();
+        assertEquals(true,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(string, string, string), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(string, string), typeSolver))
+        );
+
+        //YES Bazzer<Bar,String,Foo> e8 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(bar, string, foo), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES Bazzer<Foo,String,Bar> e9 = new MoreBazzing<Bar, Foo>();
+        assertEquals(true,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(foo, string, bar), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+
+        //NO Bazzer<Bar,String,Foo> n1 = new MoreBazzing<Bar, Foo>();
+        assertEquals(false,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(bar, string, foo), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+
+        //NO Bazzer<Bar,String,Bar> n2 = new MoreBazzing<Bar, Foo>();
+        assertEquals(false,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(bar, string, foo), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+
+        //NO Bazzer<Foo,Object,Bar> n3 = new MoreBazzing<Bar, Foo>();
+        assertEquals(false,
+                new ReferenceTypeImpl(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(foo, object, bar), typeSolver)
+                        .isAssignableBy(new ReferenceTypeImpl(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+    }
+
+    @Test
+    public void charSequenceIsAssignableToObject() {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ReferenceTypeImpl charSequence = new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(CharSequence.class, typeSolver), typeSolver);
+        ReferenceTypeImpl object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        assertEquals(false, charSequence.isAssignableBy(object));
+        assertEquals(true, object.isAssignableBy(charSequence));
+    }
+
+    @Test
+    public void testGetFieldTypeExisting() {
+        class Foo<A> {
+            List<A> elements;
+        }
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ReferenceTypeImpl ref = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver);
+
+        assertEquals(true, ref.getFieldType("elements").isPresent());
+        assertEquals(true, ref.getFieldType("elements").get().isReferenceType());
+        assertEquals(List.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().getQualifiedName());
+        assertEquals(1, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().size());
+        assertEquals(true, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).isTypeVariable());
+        assertEquals("A", ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).asTypeParameter().getName());
+
+        ref = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)),
+                typeSolver);
+
+        assertEquals(true, ref.getFieldType("elements").isPresent());
+        assertEquals(true, ref.getFieldType("elements").get().isReferenceType());
+        assertEquals(List.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().getQualifiedName());
+        assertEquals(1, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().size());
+        assertEquals(true, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).isReferenceType());
+        assertEquals(String.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetFieldTypeUnexisting() {
+        class Foo<A> {
+            List<A> elements;
+        }
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ReferenceTypeImpl ref = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver);
+
+        assertEquals(false, ref.getFieldType("bar").isPresent());
+
+        ref = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)),
+                typeSolver);
+
+        assertEquals(false, ref.getFieldType("bar").isPresent());
+    }
+
+    @Test
+    public void testTypeParamValue() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        ResolvedClassDeclaration abstractList = new ReflectionClassDeclaration(AbstractList.class, typeResolver);
+        ResolvedClassDeclaration abstractCollection = new ReflectionClassDeclaration(AbstractCollection.class, typeResolver);
+        ResolvedInterfaceDeclaration list = new ReflectionInterfaceDeclaration(List.class, typeResolver);
+        ResolvedInterfaceDeclaration collection = new ReflectionInterfaceDeclaration(Collection.class, typeResolver);
+        ResolvedInterfaceDeclaration iterable = new ReflectionInterfaceDeclaration(Iterable.class, typeResolver);
+        ResolvedType string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeResolver), typeResolver);
+        ResolvedReferenceType arrayListOfString = new ReferenceTypeImpl(arraylist, ImmutableList.of(string), typeResolver);
+        assertEquals(Optional.of(string), arrayListOfString.typeParamValue(arraylist.getTypeParameters().get(0)));
+        assertEquals(Optional.of(string), arrayListOfString.typeParamValue(abstractList.getTypeParameters().get(0)));
+        assertEquals(Optional.of(string), arrayListOfString.typeParamValue(abstractCollection.getTypeParameters().get(0)));
+        assertEquals(Optional.of(string), arrayListOfString.typeParamValue(list.getTypeParameters().get(0)));
+        assertEquals(Optional.of(string), arrayListOfString.typeParamValue(collection.getTypeParameters().get(0)));
+        assertEquals(Optional.of(string), arrayListOfString.typeParamValue(iterable.getTypeParameters().get(0)));
+    }
+
+    @Test
+    public void testGetAllAncestorsOnRawType() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        ResolvedReferenceType rawArrayList = new ReferenceTypeImpl(arraylist, typeResolver);
+
+        Map<String, ResolvedReferenceType> ancestors = new HashMap<>();
+        rawArrayList.getAllAncestors().forEach(a -> ancestors.put(a.getQualifiedName(), a));
+        assertEquals(9, ancestors.size());
+
+        ResolvedTypeVariable tv = new ResolvedTypeVariable(arraylist.getTypeParameters().get(0));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(RandomAccess.class, typeResolver), typeResolver), ancestors.get("java.util.RandomAccess"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(AbstractCollection.class, typeResolver), ImmutableList.of(tv), typeResolver), ancestors.get("java.util.AbstractCollection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(List.class, typeResolver), ImmutableList.of(tv), typeResolver), ancestors.get("java.util.List"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Cloneable.class, typeResolver), typeResolver), ancestors.get("java.lang.Cloneable"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Collection.class, typeResolver), ImmutableList.of(tv), typeResolver), ancestors.get("java.util.Collection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(AbstractList.class, typeResolver), ImmutableList.of(tv), typeResolver), ancestors.get("java.util.AbstractList"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeResolver), typeResolver), ancestors.get("java.lang.Object"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Iterable.class, typeResolver), ImmutableList.of(tv), typeResolver), ancestors.get("java.lang.Iterable"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Serializable.class, typeResolver), typeResolver), ancestors.get("java.io.Serializable"));
+    }
+
+    @Test
+    public void testGetAllAncestorsOnTypeWithSpecifiedTypeParametersForInterface() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedInterfaceDeclaration list = new ReflectionInterfaceDeclaration(List.class, typeResolver);
+        ResolvedType string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeResolver), typeResolver);
+        ResolvedReferenceType listOfString = new ReferenceTypeImpl(list, ImmutableList.of(string), typeResolver);
+
+        Map<String, ResolvedReferenceType> ancestors = new HashMap<>();
+        listOfString.getAllAncestors().forEach(a -> ancestors.put(a.getQualifiedName(), a));
+        assertEquals(3, ancestors.size());
+
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Collection.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.Collection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeResolver), typeResolver), ancestors.get("java.lang.Object"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Iterable.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.lang.Iterable"));
+    }
+
+    @Test
+    public void testGetAllAncestorsOnTypeWithSpecifiedTypeParametersForClassAbstractCollection() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration abstractCollection = new ReflectionClassDeclaration(AbstractCollection.class, typeResolver);
+        ResolvedType string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeResolver), typeResolver);
+        ResolvedReferenceType abstractCollectionOfString = new ReferenceTypeImpl(abstractCollection, ImmutableList.of(string), typeResolver);
+
+        Map<String, ResolvedReferenceType> ancestors = new HashMap<>();
+        abstractCollectionOfString.getAllAncestors().forEach(a -> ancestors.put(a.getQualifiedName(), a));
+        assertEquals(3, ancestors.size());
+
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Collection.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.Collection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeResolver), typeResolver), ancestors.get("java.lang.Object"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Iterable.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.lang.Iterable"));
+    }
+
+    @Test
+    public void testGetAllAncestorsOnTypeWithSpecifiedTypeParametersForClassAbstractList() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration abstractList = new ReflectionClassDeclaration(AbstractList.class, typeResolver);
+        ResolvedType string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeResolver), typeResolver);
+        ResolvedReferenceType abstractListOfString = new ReferenceTypeImpl(abstractList, ImmutableList.of(string), typeResolver);
+
+        Map<String, ResolvedReferenceType> ancestors = new HashMap<>();
+        abstractListOfString.getAllAncestors().forEach(a -> ancestors.put(a.getQualifiedName(), a));
+        assertEquals(5, ancestors.size());
+
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(AbstractCollection.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.AbstractCollection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(List.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.List"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Collection.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.Collection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeResolver), typeResolver), ancestors.get("java.lang.Object"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Iterable.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.lang.Iterable"));
+    }
+
+    @Test
+    public void testGetAllAncestorsOnTypeWithSpecifiedTypeParametersForClassArrayList() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        ResolvedType string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeResolver), typeResolver);
+        ResolvedReferenceType arrayListOfString = new ReferenceTypeImpl(arraylist, ImmutableList.of(string), typeResolver);
+
+        Map<String, ResolvedReferenceType> ancestors = new HashMap<>();
+        arrayListOfString.getAllAncestors().forEach(a -> ancestors.put(a.getQualifiedName(), a));
+        assertEquals(9, ancestors.size());
+
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(RandomAccess.class, typeResolver), typeResolver), ancestors.get("java.util.RandomAccess"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(AbstractCollection.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.AbstractCollection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(List.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.List"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Cloneable.class, typeResolver), typeResolver), ancestors.get("java.lang.Cloneable"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Collection.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.Collection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(AbstractList.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.util.AbstractList"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeResolver), typeResolver), ancestors.get("java.lang.Object"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Iterable.class, typeResolver), ImmutableList.of(string), typeResolver), ancestors.get("java.lang.Iterable"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Serializable.class, typeResolver), typeResolver), ancestors.get("java.io.Serializable"));
+    }
+
+    @Test
+    public void testTypeParametersValues() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedReferenceType stream = new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Stream.class, typeResolver), typeResolver);
+        assertEquals(1, stream.typeParametersValues().size());
+        assertEquals(new ResolvedTypeVariable(new ReflectionInterfaceDeclaration(Stream.class, typeResolver).getTypeParameters().get(0)), stream.typeParametersValues().get(0));
+    }
+
+    @Test
+    public void testReplaceTypeVariables() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedInterfaceDeclaration streamInterface = new ReflectionInterfaceDeclaration(Stream.class, typeResolver);
+        ResolvedReferenceType stream = new ReferenceTypeImpl(streamInterface, typeResolver);
+
+        ResolvedMethodDeclaration streamMap = streamInterface.getDeclaredMethods().stream().filter(m -> m.getName().equals("map")).findFirst().get();
+        ResolvedTypeParameterDeclaration streamMapR = streamMap.findTypeParameter("T").get();
+        ResolvedTypeVariable typeVariable = new ResolvedTypeVariable(streamMapR);
+        stream = stream.deriveTypeParameters(stream.typeParametersMap().toBuilder().setValue(stream.getTypeDeclaration().getTypeParameters().get(0), typeVariable).build());
+
+        ResolvedTypeParameterDeclaration tpToReplace = streamInterface.getTypeParameters().get(0);
+        ResolvedType replaced = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeResolver), typeResolver);
+
+        ResolvedType streamReplaced = stream.replaceTypeVariables(tpToReplace, replaced);
+        assertEquals("java.util.stream.Stream<java.lang.String>", streamReplaced.describe());
+    }
+
+    @Test
+    public void testReplaceTypeVariablesWithLambdaInBetween() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedInterfaceDeclaration streamInterface = new ReflectionInterfaceDeclaration(Stream.class, typeResolver);
+        ResolvedReferenceType stream = new ReferenceTypeImpl(streamInterface, typeResolver);
+
+        ResolvedMethodDeclaration streamMap = streamInterface.getDeclaredMethods().stream().filter(m -> m.getName().equals("map")).findFirst().get();
+        ResolvedTypeParameterDeclaration streamMapR = streamMap.findTypeParameter("T").get();
+        ResolvedTypeVariable typeVariable = new ResolvedTypeVariable(streamMapR);
+        stream = stream.deriveTypeParameters(stream.typeParametersMap().toBuilder().setValue(stream.getTypeDeclaration().getTypeParameters().get(0), typeVariable).build());
+
+        ResolvedTypeParameterDeclaration tpToReplace = streamInterface.getTypeParameters().get(0);
+        ResolvedType replaced = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeResolver), typeResolver);
+
+        ResolvedType streamReplaced = stream.replaceTypeVariables(tpToReplace, replaced);
+        assertEquals("java.util.stream.Stream<java.lang.String>", streamReplaced.describe());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/TypeVariableUsageTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/TypeVariableUsageTest.java
new file mode 100644
index 0000000..1808b9c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/TypeVariableUsageTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+
+import static org.junit.Assert.*;
+
+public class TypeVariableUsageTest {
+
+    private ResolvedTypeVariable tpA;
+    private ReferenceTypeImpl tpString;
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        tpA = new ResolvedTypeVariable(ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList()));
+        
+        typeSolver = new ReflectionTypeSolver();
+        tpString = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+    }
+
+    @Test
+    public void testIsAssignableBySimple() {
+        assertEquals(false, tpString.isAssignableBy(tpA));
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/VoidTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/VoidTypeTest.java
new file mode 100644
index 0000000..2c88ebb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/VoidTypeTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedArrayType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.resolution.types.ResolvedVoidType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class VoidTypeTest {
+
+    private ResolvedArrayType arrayOfBooleans;
+    private ResolvedArrayType arrayOfListOfA;
+    private ReferenceTypeImpl OBJECT;
+    private ReferenceTypeImpl STRING;
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        OBJECT = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        STRING = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        arrayOfBooleans = new ResolvedArrayType(ResolvedPrimitiveType.BOOLEAN);
+        arrayOfListOfA = new ResolvedArrayType(new ReferenceTypeImpl(
+                new ReflectionInterfaceDeclaration(List.class, typeSolver),
+                ImmutableList.of(new ResolvedTypeVariable(ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList()))), typeSolver));
+    }
+
+    @Test
+    public void testIsArray() {
+        assertEquals(false, ResolvedVoidType.INSTANCE.isArray());
+    }
+
+    @Test
+    public void testIsPrimitive() {
+        assertEquals(false, ResolvedVoidType.INSTANCE.isPrimitive());
+    }
+
+    @Test
+    public void testIsNull() {
+        assertEquals(false, ResolvedVoidType.INSTANCE.isNull());
+    }
+
+    @Test
+    public void testIsReference() {
+        assertEquals(false, ResolvedVoidType.INSTANCE.isReference());
+    }
+
+    @Test
+    public void testIsReferenceType() {
+        assertEquals(false, ResolvedVoidType.INSTANCE.isReferenceType());
+    }
+
+    @Test
+    public void testIsVoid() {
+        assertEquals(true, ResolvedVoidType.INSTANCE.isVoid());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        assertEquals(false, ResolvedVoidType.INSTANCE.isTypeVariable());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsReferenceTypeUsage() {
+        ResolvedVoidType.INSTANCE.asReferenceType();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsTypeParameter() {
+        ResolvedVoidType.INSTANCE.asTypeParameter();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsArrayTypeUsage() {
+        ResolvedVoidType.INSTANCE.asArrayType();
+    }
+
+    @Test
+    public void testAsDescribe() {
+        assertEquals("void", ResolvedVoidType.INSTANCE.describe());
+    }
+
+    @Test
+    public void testIsAssignableBy() {
+        try {
+            assertEquals(false, ResolvedVoidType.INSTANCE.isAssignableBy(NullType.INSTANCE));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, ResolvedVoidType.INSTANCE.isAssignableBy(OBJECT));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, ResolvedVoidType.INSTANCE.isAssignableBy(STRING));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, ResolvedVoidType.INSTANCE.isAssignableBy(ResolvedPrimitiveType.BOOLEAN));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+        try {
+            assertEquals(false, ResolvedVoidType.INSTANCE.isAssignableBy(ResolvedVoidType.INSTANCE));
+            fail();
+        } catch (UnsupportedOperationException e) {
+
+        }
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/WildcardUsageTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/WildcardUsageTest.java
new file mode 100644
index 0000000..705805d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/model/typesystem/WildcardUsageTest.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.model.typesystem;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.resolution.types.ResolvedWildcard;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class WildcardUsageTest {
+
+    class Foo {
+    }
+
+    class Bar extends Foo {
+    }
+
+    private TypeSolver typeSolver;
+    private ReferenceTypeImpl foo;
+    private ReferenceTypeImpl bar;
+    private ReferenceTypeImpl object;
+    private ReferenceTypeImpl string;
+    private ResolvedWildcard unbounded = ResolvedWildcard.UNBOUNDED;
+    private ResolvedWildcard superFoo;
+    private ResolvedWildcard superBar;
+    private ResolvedWildcard extendsFoo;
+    private ResolvedWildcard extendsBar;
+    private ResolvedWildcard superA;
+    private ResolvedWildcard extendsA;
+    private ResolvedWildcard superString;
+    private ResolvedWildcard extendsString;
+    private ResolvedTypeVariable a;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+        foo = new ReferenceTypeImpl(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver);
+        bar = new ReferenceTypeImpl(new ReflectionClassDeclaration(Bar.class, typeSolver), typeSolver);
+        object = new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        string = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+        superFoo = ResolvedWildcard.superBound(foo);
+        superBar = ResolvedWildcard.superBound(bar);
+        extendsFoo = ResolvedWildcard.extendsBound(foo);
+        extendsBar = ResolvedWildcard.extendsBound(bar);
+        a = new ResolvedTypeVariable(ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList()));
+        superA = ResolvedWildcard.superBound(a);
+        extendsA = ResolvedWildcard.extendsBound(a);
+        superString = ResolvedWildcard.superBound(string);
+        extendsString = ResolvedWildcard.extendsBound(string);
+    }
+
+    @Test
+    public void testIsArray() {
+        assertEquals(false, unbounded.isArray());
+        assertEquals(false, superFoo.isArray());
+        assertEquals(false, superBar.isArray());
+        assertEquals(false, extendsFoo.isArray());
+        assertEquals(false, extendsBar.isArray());
+    }
+
+    @Test
+    public void testIsPrimitive() {
+        assertEquals(false, unbounded.isPrimitive());
+        assertEquals(false, superFoo.isPrimitive());
+        assertEquals(false, superBar.isPrimitive());
+        assertEquals(false, extendsFoo.isPrimitive());
+        assertEquals(false, extendsBar.isPrimitive());
+    }
+
+    @Test
+    public void testIsNull() {
+        assertEquals(false, unbounded.isNull());
+        assertEquals(false, superFoo.isNull());
+        assertEquals(false, superBar.isNull());
+        assertEquals(false, extendsFoo.isNull());
+        assertEquals(false, extendsBar.isNull());
+    }
+
+    @Test
+    public void testIsReference() {
+        assertEquals(true, unbounded.isReference());
+        assertEquals(true, superFoo.isReference());
+        assertEquals(true, superBar.isReference());
+        assertEquals(true, extendsFoo.isReference());
+        assertEquals(true, extendsBar.isReference());
+    }
+
+    @Test
+    public void testIsReferenceType() {
+        assertEquals(false, unbounded.isReferenceType());
+        assertEquals(false, superFoo.isReferenceType());
+        assertEquals(false, superBar.isReferenceType());
+        assertEquals(false, extendsFoo.isReferenceType());
+        assertEquals(false, extendsBar.isReferenceType());
+    }
+
+    @Test
+    public void testIsVoid() {
+        assertEquals(false, unbounded.isVoid());
+        assertEquals(false, superFoo.isVoid());
+        assertEquals(false, superBar.isVoid());
+        assertEquals(false, extendsFoo.isVoid());
+        assertEquals(false, extendsBar.isVoid());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        assertEquals(false, unbounded.isTypeVariable());
+        assertEquals(false, superFoo.isTypeVariable());
+        assertEquals(false, superBar.isTypeVariable());
+        assertEquals(false, extendsFoo.isTypeVariable());
+        assertEquals(false, extendsBar.isTypeVariable());
+    }
+
+    @Test
+    public void testIsWildcard() {
+        assertEquals(true, unbounded.isWildcard());
+        assertEquals(true, superFoo.isWildcard());
+        assertEquals(true, superBar.isWildcard());
+        assertEquals(true, extendsFoo.isWildcard());
+        assertEquals(true, extendsBar.isWildcard());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsArrayTypeUsage() {
+        unbounded.asArrayType();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsReferenceTypeUsage() {
+        unbounded.asReferenceType();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsTypeParameter() {
+        unbounded.asTypeParameter();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsPrimitive() {
+        unbounded.asPrimitive();
+    }
+
+    @Test
+    public void testAsWildcard() {
+        assertTrue(unbounded == unbounded.asWildcard());
+        assertTrue(superFoo == superFoo.asWildcard());
+        assertTrue(superBar == superBar.asWildcard());
+        assertTrue(extendsFoo == extendsFoo.asWildcard());
+        assertTrue(extendsBar == extendsBar.asWildcard());
+    }
+
+    @Test
+    public void testAsDescribe() {
+        assertEquals("?", unbounded.describe());
+        assertEquals("? super com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Foo", superFoo.describe());
+        assertEquals("? super com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Bar", superBar.describe());
+        assertEquals("? extends com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Foo", extendsFoo.describe());
+        assertEquals("? extends com.github.javaparser.symbolsolver.model.typesystem.WildcardUsageTest.Bar", extendsBar.describe());
+    }
+
+    @Test
+    public void testReplaceParam() {
+        ResolvedTypeParameterDeclaration tpA = ResolvedTypeParameterDeclaration.onType("A", "foo.Bar", Collections.emptyList());
+        ResolvedTypeParameterDeclaration tpB = ResolvedTypeParameterDeclaration.onType("B", "foo.Bar", Collections.emptyList());
+        assertTrue(unbounded == unbounded.replaceTypeVariables(tpA, string));
+        assertTrue(superFoo == superFoo.replaceTypeVariables(tpA, string));
+        assertTrue(extendsFoo == extendsFoo.replaceTypeVariables(tpA, string));
+        assertEquals(superString, superA.replaceTypeVariables(tpA, string));
+        assertEquals(extendsString, extendsA.replaceTypeVariables(tpA, string));
+        assertTrue(superA == superA.replaceTypeVariables(tpB, string));
+        assertTrue(extendsA == extendsA.replaceTypeVariables(tpB, string));
+    }
+
+    @Test
+    public void testIsAssignableBySimple() {
+        assertEquals(false, unbounded.isAssignableBy(object));
+        assertEquals(true, object.isAssignableBy(unbounded));
+        assertEquals(false, string.isAssignableBy(unbounded));
+        assertEquals(true, superFoo.isAssignableBy(foo));
+        assertEquals(false, foo.isAssignableBy(superFoo));
+        assertEquals(false, extendsFoo.isAssignableBy(foo));
+        assertEquals(true, foo.isAssignableBy(extendsFoo));
+    }
+
+    /*@Test
+    public void testIsAssignableByGenerics() {
+        assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString));
+        assertEquals(false, listOfStrings.isAssignableBy(listOfWildcardExtendsString));
+        assertEquals(true,  listOfWildcardExtendsString.isAssignableBy(listOfStrings));
+        assertEquals(false, listOfWildcardExtendsString.isAssignableBy(listOfWildcardSuperString));
+        assertEquals(true,  listOfWildcardSuperString.isAssignableBy(listOfStrings));
+        assertEquals(false, listOfWildcardSuperString.isAssignableBy(listOfWildcardExtendsString));
+    }
+
+    @Test
+    public void testIsAssignableByGenericsInheritance() {
+        assertEquals(true, collectionOfString.isAssignableBy(collectionOfString));
+        assertEquals(true, collectionOfString.isAssignableBy(listOfStrings));
+        assertEquals(true, collectionOfString.isAssignableBy(linkedListOfString));
+
+        assertEquals(false, listOfStrings.isAssignableBy(collectionOfString));
+        assertEquals(true, listOfStrings.isAssignableBy(listOfStrings));
+        assertEquals(true, listOfStrings.isAssignableBy(linkedListOfString));
+
+        assertEquals(false, linkedListOfString.isAssignableBy(collectionOfString));
+        assertEquals(false, linkedListOfString.isAssignableBy(listOfStrings));
+        assertEquals(true, linkedListOfString.isAssignableBy(linkedListOfString));
+    }
+
+    @Test
+    public void testGetAllAncestorsConsideringTypeParameters() {
+        assertTrue(linkedListOfString.getAllAncestors().contains(object));
+        assertTrue(linkedListOfString.getAllAncestors().contains(listOfStrings));
+        assertTrue(linkedListOfString.getAllAncestors().contains(collectionOfString));
+        assertFalse(linkedListOfString.getAllAncestors().contains(listOfA));
+    }
+
+    @Test
+    public void testGetAllAncestorsConsideringGenericsCases() {
+        ReferenceTypeUsage foo = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver);
+        ReferenceTypeUsage bar = new ReferenceTypeUsage(new ReflectionClassDeclaration(Bar.class, typeSolver), typeSolver);
+        ReferenceTypeUsage left, right;
+
+        //YES MoreBazzing<Foo, Bar> e1 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeUsage(
+                    new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                    ImmutableList.of(foo, bar), typeSolver)
+                .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<? extends Foo, Bar> e2 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                        ImmutableList.of(WildcardUsage.extendsBound(foo), bar), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<Foo, ? extends Bar> e3 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                        ImmutableList.of(foo, WildcardUsage.extendsBound(bar)), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<? extends Foo, ? extends Foo> e4 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                        ImmutableList.of(WildcardUsage.extendsBound(foo), WildcardUsage.extendsBound(foo)), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES MoreBazzing<? extends Foo, ? extends Foo> e5 = new MoreBazzing<Bar, Bar>();
+        left = new ReferenceTypeUsage(
+                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                ImmutableList.of(WildcardUsage.extendsBound(foo), WildcardUsage.extendsBound(foo)), typeSolver);
+        right = new ReferenceTypeUsage(
+                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                ImmutableList.of(bar, bar), typeSolver);
+        assertEquals(true, left.isAssignableBy(right));
+
+        //YES Bazzer<Object, String, String> e6 = new MoreBazzing<String, Object>();
+        left = new ReferenceTypeUsage(
+                new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                ImmutableList.of(object, string, string), typeSolver);
+        right = new ReferenceTypeUsage(
+                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                ImmutableList.of(string, object), typeSolver);
+        assertEquals(true, left.isAssignableBy(right));
+
+        //YES Bazzer<String,String,String> e7 = new MoreBazzing<String, String>();
+        assertEquals(true,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(string, string, string), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(string, string), typeSolver))
+        );
+
+        //YES Bazzer<Bar,String,Foo> e8 = new MoreBazzing<Foo, Bar>();
+        assertEquals(true,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(bar, string, foo), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(foo, bar), typeSolver))
+        );
+
+        //YES Bazzer<Foo,String,Bar> e9 = new MoreBazzing<Bar, Foo>();
+        assertEquals(true,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(foo, string, bar), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+
+        //NO Bazzer<Bar,String,Foo> n1 = new MoreBazzing<Bar, Foo>();
+        assertEquals(false,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(bar,string,foo), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+
+        //NO Bazzer<Bar,String,Bar> n2 = new MoreBazzing<Bar, Foo>();
+        assertEquals(false,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(bar, string, foo), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+
+        //NO Bazzer<Foo,Object,Bar> n3 = new MoreBazzing<Bar, Foo>();
+        assertEquals(false,
+                new ReferenceTypeUsage(
+                        new ReflectionClassDeclaration(Bazzer.class, typeSolver),
+                        ImmutableList.of(foo, object, bar), typeSolver)
+                        .isAssignableBy(new ReferenceTypeUsage(
+                                new ReflectionClassDeclaration(MoreBazzing.class, typeSolver),
+                                ImmutableList.of(bar, foo), typeSolver))
+        );
+    }
+
+    @Test
+    public void charSequenceIsAssignableToObject() {
+        TypeSolver typeSolver = new JreTypeSolver();
+        ReferenceTypeUsage charSequence = new ReferenceTypeUsage(new ReflectionInterfaceDeclaration(CharSequence.class, typeSolver), typeSolver);
+        ReferenceTypeUsage object = new ReferenceTypeUsage(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver);
+        assertEquals(false, charSequence.isAssignableBy(object));
+        assertEquals(true, object.isAssignableBy(charSequence));
+    }
+
+    @Test
+    public void testGetFieldTypeExisting() {
+        class Foo<A> {
+            List<A> elements;
+        }
+
+        TypeSolver typeSolver = new JreTypeSolver();
+        ReferenceTypeUsage ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver);
+
+        assertEquals(true, ref.getFieldType("elements").isPresent());
+        assertEquals(true, ref.getFieldType("elements").get().isReferenceType());
+        assertEquals(List.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().getQualifiedName());
+        assertEquals(1, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().size());
+        assertEquals(true, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).isTypeParameter());
+        assertEquals("A", ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).asTypeParameter().getName());
+
+        ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeUsage(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)),
+                typeSolver);
+
+        assertEquals(true, ref.getFieldType("elements").isPresent());
+        assertEquals(true, ref.getFieldType("elements").get().isReferenceType());
+        assertEquals(List.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().getQualifiedName());
+        assertEquals(1, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().size());
+        assertEquals(true, ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).isReferenceType());
+        assertEquals(String.class.getCanonicalName(), ref.getFieldType("elements").get().asReferenceType().typeParametersValues().get(0).asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetFieldTypeUnexisting() {
+        class Foo<A> {
+            List<A> elements;
+        }
+
+        TypeSolver typeSolver = new JreTypeSolver();
+        ReferenceTypeUsage ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver), typeSolver);
+
+        assertEquals(false, ref.getFieldType("bar").isPresent());
+
+        ref = new ReferenceTypeUsage(new ReflectionClassDeclaration(Foo.class, typeSolver),
+                ImmutableList.of(new ReferenceTypeUsage(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver)),
+                typeSolver);
+
+        assertEquals(false, ref.getFieldType("bar").isPresent());
+    }*/
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclarationTest.java
new file mode 100644
index 0000000..8de0e23
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclarationTest.java
@@ -0,0 +1,776 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Test;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class ReflectionClassDeclarationTest extends AbstractTest {
+    
+    private TypeSolver typeResolver = new ReflectionTypeSolver(false);
+
+    @Test
+    public void testIsClass() {
+        class Foo<E> {
+            E field;
+        }
+        class Bar extends Foo<String> {
+        }
+
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedClassDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver);
+        ResolvedClassDeclaration bar = new ReflectionClassDeclaration(Bar.class, typeResolver);
+
+        assertEquals(true, foo.isClass());
+        assertEquals(true, bar.isClass());
+    }
+
+    @Test
+    public void testGetSuperclassSimpleImplicit() {
+        class Foo<E> {
+            E field;
+        }
+
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedClassDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver);
+
+        assertEquals(Object.class.getCanonicalName(), foo.getSuperClass().getQualifiedName());
+        assertEquals(Collections.emptyList(), foo.getSuperClass().typeParametersValues());
+    }
+
+    @Test
+    public void testGetSuperclassSimple() {
+        class Bar {
+        }
+        class Foo<E> extends Bar {
+            E field;
+        }
+
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedClassDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver);
+
+        assertEquals("Bar", foo.getSuperClass().getTypeDeclaration().getName());
+        assertEquals(Collections.emptyList(), foo.getSuperClass().typeParametersValues());
+    }
+
+    @Test
+    public void testGetSuperclassWithGenericSimple() {
+        class Foo<E> {
+            E field;
+        }
+        class Bar extends Foo<String> {
+        }
+
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedClassDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver);
+        ResolvedClassDeclaration bar = new ReflectionClassDeclaration(Bar.class, typeResolver);
+
+        assertEquals("Foo", bar.getSuperClass().getTypeDeclaration().getName());
+        assertEquals(1, bar.getSuperClass().typeParametersValues().size());
+        assertEquals(String.class.getCanonicalName(), bar.getSuperClass().typeParametersValues().get(0).asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetSuperclassWithGenericInheritanceSameName() {
+        class Foo<E> {
+            E field;
+        }
+        class Bar<E> extends Foo<E> {
+        }
+
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedClassDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver);
+        ResolvedClassDeclaration bar = new ReflectionClassDeclaration(Bar.class, typeResolver);
+
+        assertEquals("Foo", bar.getSuperClass().getTypeDeclaration().getName());
+        assertEquals(1, bar.getSuperClass().typeParametersValues().size());
+        assertEquals(true, bar.getSuperClass().typeParametersValues().get(0).isTypeVariable());
+        assertEquals("E", bar.getSuperClass().typeParametersValues().get(0).asTypeParameter().getName());
+        assertEquals(true, bar.getSuperClass().typeParametersValues().get(0).asTypeParameter().declaredOnType());
+        assertEquals(false, bar.getSuperClass().typeParametersValues().get(0).asTypeParameter().declaredOnMethod());
+        assertTrue(bar.getSuperClass().typeParametersValues().get(0).asTypeParameter().getQualifiedName().endsWith("Bar.E"));
+    }
+
+    @Test
+    public void testGetSuperclassWithGenericInheritanceDifferentName() {
+        class Foo<E> {
+            E field;
+        }
+        class Bar extends Foo<String> {
+        }
+
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedClassDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver);
+        ResolvedClassDeclaration bar = new ReflectionClassDeclaration(Bar.class, typeResolver);
+
+        assertEquals(true, foo.isClass());
+        assertEquals(true, bar.isClass());
+    }
+
+    @Test
+    public void testGetFieldDeclarationTypeVariableInheritance() {
+        class Foo<E> {
+            E field;
+        }
+        class Bar extends Foo<String> {
+        }
+
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedReferenceTypeDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver);
+        ResolvedReferenceTypeDeclaration bar = new ReflectionClassDeclaration(Bar.class, typeResolver);
+
+        ResolvedFieldDeclaration fooField = foo.getField("field");
+        assertEquals(true, fooField.getType().isTypeVariable());
+        assertEquals("E", fooField.getType().asTypeParameter().getName());
+
+        ResolvedFieldDeclaration barField = bar.getField("field");
+        assertEquals(true, barField.getType().isReferenceType());
+        assertEquals(String.class.getCanonicalName(), barField.getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetDeclaredMethods() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedReferenceTypeDeclaration string = new ReflectionClassDeclaration(String.class, typeResolver);
+        List<ResolvedMethodDeclaration> methods = string.getDeclaredMethods().stream()
+                .filter(m -> m.accessSpecifier() != AccessSpecifier.PRIVATE && m.accessSpecifier() != AccessSpecifier.DEFAULT)
+                .sorted((a, b) -> a.getName().compareTo(b.getName()))
+                .collect(Collectors.toList());
+        if (isJava9()) {
+            assertEquals(69, methods.size());
+        } else {
+            assertEquals(67, methods.size());
+        }
+        assertEquals("charAt", methods.get(0).getName());
+        assertEquals(false, methods.get(0).isAbstract());
+        assertEquals(1, methods.get(0).getNumberOfParams());
+        assertEquals("int", methods.get(0).getParam(0).getType().describe());
+        if (isJava9()) {
+            assertEquals("compareTo", methods.get(6).getName());
+            assertEquals(false, methods.get(6).isAbstract());
+            assertEquals(1, methods.get(6).getNumberOfParams());
+            assertEquals("java.lang.String", methods.get(6).getParam(0).getType().describe());
+        } else {
+            assertEquals("concat", methods.get(6).getName());
+            assertEquals(false, methods.get(6).isAbstract());
+            assertEquals(1, methods.get(6).getNumberOfParams());
+            assertEquals("java.lang.String", methods.get(6).getParam(0).getType().describe());
+        }
+    }
+
+    @Test
+    public void testGetInterfaces() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        // Serializable, Cloneable, List<E>, RandomAccess
+        assertEquals(ImmutableSet.of(Serializable.class.getCanonicalName(),
+                Cloneable.class.getCanonicalName(),
+                List.class.getCanonicalName(),
+                RandomAccess.class.getCanonicalName()),
+                arraylist.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllInterfaces() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        // Serializable, Cloneable, Iterable<E>, Collection<E>, List<E>, RandomAccess
+        assertEquals(ImmutableSet.of(Serializable.class.getCanonicalName(),
+                Cloneable.class.getCanonicalName(),
+                List.class.getCanonicalName(),
+                RandomAccess.class.getCanonicalName(),
+                Collection.class.getCanonicalName(),
+                Iterable.class.getCanonicalName()),
+                arraylist.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllSuperclasses() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        assertEquals(ImmutableSet.of(Object.class.getCanonicalName(),
+                AbstractCollection.class.getCanonicalName(),
+                AbstractList.class.getCanonicalName()),
+                arraylist.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+        ResolvedClassDeclaration string = new ReflectionClassDeclaration(String.class, typeResolver);
+        assertEquals(ImmutableSet.of(Object.class.getCanonicalName()),
+                string.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetPackageName() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        assertEquals("java.util", arraylist.getPackageName());
+        ResolvedClassDeclaration string = new ReflectionClassDeclaration(String.class, typeResolver);
+        assertEquals("java.lang", string.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        assertEquals("ArrayList", arraylist.getClassName());
+        ResolvedClassDeclaration string = new ReflectionClassDeclaration(String.class, typeResolver);
+        assertEquals("String", string.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        assertEquals("java.util.ArrayList", arraylist.getQualifiedName());
+        ResolvedClassDeclaration string = new ReflectionClassDeclaration(String.class, typeResolver);
+        assertEquals("java.lang.String", string.getQualifiedName());
+    }
+
+    // solveMethod
+    // isAssignableBy
+    // canBeAssignedTo
+    // hasField
+    // solveSymbol
+    // solveType
+    // getDeclaredMethods
+    // getAllMethods
+
+    @Test
+    public void testGetAllFields() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        assertEquals(ImmutableSet.of("modCount", "serialVersionUID", "MAX_ARRAY_SIZE", "size", "elementData", "EMPTY_ELEMENTDATA", "DEFAULTCAPACITY_EMPTY_ELEMENTDATA", "DEFAULT_CAPACITY"),
+                arraylist.getAllFields().stream().map(ResolvedDeclaration::getName).collect(Collectors.toSet()));
+    }
+
+    ///
+    /// Test ancestors
+    ///    
+
+    @Test
+    public void testAllAncestors() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedClassDeclaration arraylist = new ReflectionClassDeclaration(ArrayList.class, typeResolver);
+        Map<String, ResolvedReferenceType> ancestors = new HashMap<>();
+        arraylist.getAllAncestors().forEach(a -> ancestors.put(a.getQualifiedName(), a));
+        assertEquals(9, ancestors.size());
+
+        ResolvedTypeVariable typeVariable = new ResolvedTypeVariable(arraylist.getTypeParameters().get(0));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(RandomAccess.class, typeResolver), typeResolver), ancestors.get("java.util.RandomAccess"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(AbstractCollection.class, typeResolver), ImmutableList.of(typeVariable), typeResolver), ancestors.get("java.util.AbstractCollection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(List.class, typeResolver), ImmutableList.of(typeVariable), typeResolver), ancestors.get("java.util.List"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Cloneable.class, typeResolver), typeResolver), ancestors.get("java.lang.Cloneable"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Collection.class, typeResolver), ImmutableList.of(typeVariable), typeResolver), ancestors.get("java.util.Collection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(AbstractList.class, typeResolver), ImmutableList.of(typeVariable), typeResolver), ancestors.get("java.util.AbstractList"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeResolver), typeResolver), ancestors.get("java.lang.Object"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Iterable.class, typeResolver), ImmutableList.of(typeVariable), typeResolver), ancestors.get("java.lang.Iterable"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Serializable.class, typeResolver), typeResolver), ancestors.get("java.io.Serializable"));
+    }
+
+    @Test
+    public void testGetSuperclassWithoutTypeParameters() {
+        ReflectionClassDeclaration compilationUnit = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals("com.github.javaparser.ast.Node", compilationUnit.getSuperClass().getQualifiedName());
+    }
+
+    @Test
+    public void testGetSuperclassWithTypeParameters() {
+        ReflectionClassDeclaration compilationUnit = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals("com.github.javaparser.ast.body.CallableDeclaration", compilationUnit.getSuperClass().getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", compilationUnit.getSuperClass().typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.CallableDeclaration.T").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithoutTypeParameters() {
+        ReflectionClassDeclaration cu = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.Node", "java.lang.Object"), cu.getAllSuperClasses().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllSuperclassesWithTypeParameters() {
+        ReflectionClassDeclaration constructorDeclaration = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(4, constructorDeclaration.getAllSuperClasses().size());
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("com.github.javaparser.ast.body.CallableDeclaration")));
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("com.github.javaparser.ast.body.BodyDeclaration")));
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("com.github.javaparser.ast.Node")));
+        assertEquals(true, constructorDeclaration.getAllSuperClasses().stream().anyMatch(s -> s.getQualifiedName().equals("java.lang.Object")));
+
+        ResolvedReferenceType ancestor;
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(0);
+        assertEquals("com.github.javaparser.ast.body.CallableDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.CallableDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(1);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(2);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = constructorDeclaration.getAllSuperClasses().get(3);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+    }
+
+    @Test
+    public void testGetInterfacesWithoutParameters() {
+        ReflectionClassDeclaration compilationUnit = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of(), compilationUnit.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+
+        ReflectionClassDeclaration coid = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.nodeTypes.NodeWithExtends",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier",
+                "com.github.javaparser.ast.nodeTypes.NodeWithConstructors",
+                "com.github.javaparser.ast.nodeTypes.NodeWithImplements",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier",
+                "com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters",
+                "com.github.javaparser.resolution.Resolvable"),
+                coid.getInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetInterfacesWithParameters() {
+        ReflectionClassDeclaration constructorDeclaration = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        System.out.println(constructorDeclaration.getInterfaces().stream().map(t -> t.getQualifiedName()).collect(Collectors.toList()));
+        assertEquals(8, constructorDeclaration.getInterfaces().size());
+
+        ResolvedReferenceType interfaze;
+
+        interfaze = constructorDeclaration.getInterfaces().get(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getInterfaces().get(7);
+        assertEquals("com.github.javaparser.resolution.Resolvable", interfaze.getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllInterfacesWithoutParameters() {
+        ReflectionClassDeclaration compilationUnit = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.visitor.Visitable", "com.github.javaparser.ast.observer.Observable",
+                "com.github.javaparser.HasParentNode", "com.github.javaparser.ast.nodeTypes.NodeWithRange",
+                "com.github.javaparser.ast.nodeTypes.NodeWithTokenRange").stream().sorted().collect(Collectors.toList()),
+                compilationUnit.getAllInterfaces().stream().map(i -> i.getQualifiedName()).sorted().collect(Collectors.toList()));
+
+        ReflectionClassDeclaration coid = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ClassOrInterfaceDeclaration");
+        assertEquals(ImmutableSet.of("com.github.javaparser.ast.nodeTypes.NodeWithExtends",
+                "com.github.javaparser.ast.nodeTypes.NodeWithAnnotations",
+                "java.lang.Cloneable",
+                "com.github.javaparser.HasParentNode",
+                "com.github.javaparser.ast.visitor.Visitable",
+                "com.github.javaparser.ast.nodeTypes.NodeWithImplements",
+                "com.github.javaparser.ast.nodeTypes.NodeWithSimpleName",
+                "com.github.javaparser.ast.nodeTypes.NodeWithModifiers",
+                "com.github.javaparser.ast.nodeTypes.NodeWithJavadoc",
+                "com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters",
+                "com.github.javaparser.ast.nodeTypes.NodeWithMembers",
+                "com.github.javaparser.ast.observer.Observable",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithProtectedModifier",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers",
+                "com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStrictfpModifier",
+                "com.github.javaparser.ast.nodeTypes.NodeWithRange",
+                "com.github.javaparser.ast.nodeTypes.NodeWithTokenRange",
+                "com.github.javaparser.ast.nodeTypes.NodeWithConstructors",
+                "com.github.javaparser.resolution.Resolvable"), coid.getAllInterfaces().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllInterfacesWithParameters() {
+        ReflectionClassDeclaration constructorDeclaration = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        List<ResolvedReferenceType> interfaces = constructorDeclaration.getAllInterfaces();
+        assertEquals(34, interfaces.size());
+
+        ResolvedReferenceType interfaze;
+        int i = 0;
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithProtectedModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithProtectedModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.resolution.Resolvable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("java.lang.Cloneable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.HasParentNode", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.Node", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.HasParentNode.T").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.observer.Observable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.visitor.Visitable", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithRange", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.Node", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithRange.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTokenRange", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.Node", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTokenRange.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithProtectedModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithProtectedModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", interfaze.getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier.N").get().asReferenceType().getQualifiedName());
+
+        interfaze = constructorDeclaration.getAllInterfaces().get(i++);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStrictfpModifier", interfaze.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", interfaze.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStrictfpModifier.N").get().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void testGetAncestorsWithTypeParameters() {
+        ReflectionClassDeclaration constructorDeclaration = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+        assertEquals(9, constructorDeclaration.getAncestors().size());
+
+        ResolvedReferenceType ancestor;
+        List<ResolvedReferenceType> ancestors = constructorDeclaration.getAncestors();
+        ancestors.sort(Comparator.comparing(ResolvedReferenceType::getQualifiedName));
+
+        ancestor = ancestors.get(0);
+        assertEquals("com.github.javaparser.ast.body.CallableDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.CallableDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(1);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(2);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(3);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(4);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(5);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(6);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(7);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.get(8);
+        assertEquals("com.github.javaparser.resolution.Resolvable", ancestor.getQualifiedName());
+    }
+
+    @Test
+    public void testGetAllAncestorsWithoutTypeParameters() {
+        ReflectionClassDeclaration cu = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.CompilationUnit");
+        assertEquals(ImmutableSet.of("java.lang.Cloneable", "com.github.javaparser.ast.visitor.Visitable",
+                "com.github.javaparser.ast.observer.Observable", "com.github.javaparser.ast.Node",
+                "com.github.javaparser.ast.nodeTypes.NodeWithTokenRange", "java.lang.Object", "com.github.javaparser.HasParentNode",
+                "com.github.javaparser.ast.nodeTypes.NodeWithRange"), cu.getAllAncestors().stream().map(i -> i.getQualifiedName()).collect(Collectors.toSet()));
+    }
+
+    @Test
+    public void testGetAllAncestorsWithTypeParameters() {
+        ReflectionClassDeclaration constructorDeclaration = (ReflectionClassDeclaration) typeResolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        ResolvedReferenceType ancestor;
+        List<ResolvedReferenceType> ancestors = constructorDeclaration.getAllAncestors();
+        ancestors.sort(Comparator.comparing(ResolvedReferenceType::getQualifiedName));
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.HasParentNode", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.Node", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.HasParentNode.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.Node", ancestor.getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.body.BodyDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.BodyDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.body.CallableDeclaration", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.body.CallableDeclaration.T").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithDeclaration", ancestor.getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithJavadoc.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithModifiers.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithParameters.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithRange", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.Node", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithRange.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithThrownExceptions.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTokenRange", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.Node", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTokenRange.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAbstractModifier.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithAccessModifiers.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithFinalModifier.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPrivateModifier.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithProtectedModifier", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithProtectedModifier.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithPublicModifier.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStrictfpModifier", ancestor.getQualifiedName());
+        assertEquals("com.github.javaparser.ast.body.ConstructorDeclaration", ancestor.typeParametersMap().getValueBySignature("com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStrictfpModifier.N").get().asReferenceType().getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.observer.Observable", ancestor.getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.ast.visitor.Visitable", ancestor.getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("com.github.javaparser.resolution.Resolvable", ancestor.getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("java.lang.Cloneable", ancestor.getQualifiedName());
+
+        ancestor = ancestors.remove(0);
+        assertEquals("java.lang.Object", ancestor.getQualifiedName());
+
+        assertTrue(ancestors.isEmpty());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclarationTest.java
new file mode 100644
index 0000000..00379b0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclarationTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ReflectionEnumDeclarationTest extends AbstractTest {
+
+    private TypeSolver typeSolver = new ReflectionTypeSolver(false);
+
+    ///
+    /// Test misc
+    ///
+
+    @Test
+    public void testIsClass() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isClass());
+    }
+
+    @Test
+    public void testIsInterface() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isInterface());
+    }
+
+    @Test
+    public void testIsEnum() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(true, modifier.isEnum());
+    }
+
+    @Test
+    public void testIsTypeVariable() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(false, modifier.isTypeParameter());
+    }
+
+    @Test
+    public void testIsType() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(true, modifier.isType());
+    }
+
+    @Test
+    public void testAsType() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(modifier, modifier.asType());
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsClass() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        modifier.asClass();
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testAsInterface() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        modifier.asInterface();
+    }
+
+    @Test
+    public void testAsEnum() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals(modifier, modifier.asEnum());
+    }
+
+    @Test
+    public void testGetPackageName() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("com.github.javaparser.ast", modifier.getPackageName());
+    }
+
+    @Test
+    public void testGetClassName() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("Modifier", modifier.getClassName());
+    }
+
+    @Test
+    public void testGetQualifiedName() {
+        ReflectionEnumDeclaration modifier = (ReflectionEnumDeclaration) typeSolver.solveType("com.github.javaparser.ast.Modifier");
+        assertEquals("com.github.javaparser.ast.Modifier", modifier.getQualifiedName());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclarationTest.java
new file mode 100644
index 0000000..a526610
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclarationTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedTypeVariable;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class ReflectionInterfaceDeclarationTest extends AbstractTest {
+
+    @Test
+    public void testGetDeclaredMethods() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedReferenceTypeDeclaration list = new ReflectionInterfaceDeclaration(List.class, typeResolver);
+        List<ResolvedMethodDeclaration> methods = list.getDeclaredMethods().stream()
+                .sorted((a, b) -> a.getName().compareTo(b.getName()))
+                .collect(Collectors.toList());
+        if (isJava9()) {
+            assertEquals(40, methods.size());
+            assertEquals("clear", methods.get(4).getName());
+            assertEquals(true, methods.get(4).isAbstract());
+            assertEquals(0, methods.get(4).getNumberOfParams());
+            assertEquals("contains", methods.get(5).getName());
+            assertEquals(true, methods.get(5).isAbstract());
+            assertEquals(1, methods.get(5).getNumberOfParams());
+            assertEquals(true, methods.get(5).getParam(0).getType().isReferenceType());
+            assertEquals(Object.class.getCanonicalName(), methods.get(5).getParam(0).getType().asReferenceType().getQualifiedName());
+        } else {
+            assertEquals(28, methods.size());
+            assertEquals("clear", methods.get(4).getName());
+            assertEquals(true, methods.get(4).isAbstract());
+            assertEquals(0, methods.get(4).getNumberOfParams());
+            assertEquals("contains", methods.get(5).getName());
+            assertEquals(true, methods.get(5).isAbstract());
+            assertEquals(1, methods.get(5).getNumberOfParams());
+            assertEquals(true, methods.get(5).getParam(0).getType().isReferenceType());
+            assertEquals(Object.class.getCanonicalName(), methods.get(5).getParam(0).getType().asReferenceType().getQualifiedName());
+        }
+    }
+
+    @Test
+    public void testAllAncestors() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+        ResolvedInterfaceDeclaration list = new ReflectionInterfaceDeclaration(List.class, typeResolver);
+        Map<String, ResolvedReferenceType> ancestors = new HashMap<>();
+        list.getAllAncestors().forEach(a -> ancestors.put(a.getQualifiedName(), a));
+        assertEquals(3, ancestors.size());
+
+        ResolvedTypeVariable typeVariable = new ResolvedTypeVariable(list.getTypeParameters().get(0));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Collection.class, typeResolver), ImmutableList.of(typeVariable), typeResolver), ancestors.get("java.util.Collection"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeResolver), typeResolver), ancestors.get("java.lang.Object"));
+        assertEquals(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(Iterable.class, typeResolver), ImmutableList.of(typeVariable), typeResolver), ancestors.get("java.lang.Iterable"));
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclarationTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclarationTest.java
new file mode 100644
index 0000000..8a5be17
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclarationTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.reflectionmodel;
+
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedInterfaceDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class ReflectionMethodDeclarationTest {
+
+    @Test
+    public void testGetSignature() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedClassDeclaration object = new ReflectionClassDeclaration(Object.class, typeResolver);
+        ResolvedInterfaceDeclaration list = new ReflectionInterfaceDeclaration(List.class, typeResolver);
+
+        ResolvedMethodDeclaration hashCode = object.getAllMethods().stream().filter(m -> m.getName().equals("hashCode")).findFirst().get().getDeclaration();
+        ResolvedMethodDeclaration equals = object.getAllMethods().stream().filter(m -> m.getName().equals("equals")).findFirst().get().getDeclaration();
+        ResolvedMethodDeclaration containsAll = list.getAllMethods().stream().filter(m -> m.getName().equals("containsAll")).findFirst().get().getDeclaration();
+        ResolvedMethodDeclaration subList = list.getAllMethods().stream().filter(m -> m.getName().equals("subList")).findFirst().get().getDeclaration();
+
+        assertEquals("hashCode()", hashCode.getSignature());
+        assertEquals("equals(java.lang.Object)", equals.getSignature());
+        assertEquals("containsAll(java.util.Collection<? extends java.lang.Object>)", containsAll.getSignature());
+        assertEquals("subList(int, int)", subList.getSignature());
+    }
+
+    @Test
+    public void testGetGenericReturnType() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedInterfaceDeclaration map = new ReflectionInterfaceDeclaration(Map.class, typeResolver);
+
+        ResolvedMethodDeclaration put = map.getAllMethods().stream().filter(m -> m.getName().equals("put")).findFirst().get().getDeclaration();
+        assertEquals(true, put.getReturnType().isTypeVariable());
+        assertEquals(true, put.getReturnType().asTypeParameter().declaredOnType());
+        assertEquals("java.util.Map.V", put.getReturnType().asTypeParameter().getQualifiedName());
+    }
+
+    @Test
+    public void testGetGenericParameters() {
+        TypeSolver typeResolver = new ReflectionTypeSolver();
+
+        ResolvedInterfaceDeclaration map = new ReflectionInterfaceDeclaration(Map.class, typeResolver);
+
+        ResolvedMethodDeclaration put = map.getAllMethods().stream().filter(m -> m.getName().equals("put")).findFirst().get().getDeclaration();
+        assertEquals(true, put.getParam(0).getType().isTypeVariable());
+        assertEquals(true, put.getParam(0).getType().asTypeParameter().declaredOnType());
+        assertEquals("java.util.Map.K", put.getParam(0).getType().asTypeParameter().getQualifiedName());
+
+        assertEquals(true, put.getParam(1).getType().isTypeVariable());
+        assertEquals(true, put.getParam(1).getType().asTypeParameter().declaredOnType());
+        assertEquals("java.util.Map.V", put.getParam(1).getType().asTypeParameter().getQualifiedName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AbstractResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AbstractResolutionTest.java
new file mode 100644
index 0000000..ded9267
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AbstractResolutionTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.symbolsolver.AbstractTest;
+
+import java.io.InputStream;
+
+/**
+ * @author Federico Tomassetti
+ */
+public abstract class AbstractResolutionTest extends AbstractTest {
+
+    protected CompilationUnit parseSampleWithStandardExtension(String sampleName) {
+        return parseSample(sampleName, "java");
+    }
+
+    protected CompilationUnit parseSample(String sampleName) {
+        return parseSample(sampleName, "java.txt");
+    }
+
+    private CompilationUnit parseSample(String sampleName, String extension) {
+        InputStream is = this.getClass().getClassLoader().getResourceAsStream(sampleName + "." + extension);
+        if (is == null) {
+            throw new RuntimeException("Unable to find sample " + sampleName);
+        }
+        return JavaParser.parse(is);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaParserTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaParserTest.java
new file mode 100644
index 0000000..7b9f61b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaParserTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.SlowTest;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.SourceFileInfoExtractor;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@Category(SlowTest.class)
+public class AnalyseJavaParserTest extends AbstractTest {
+
+    private static final File src = adaptPath(new File("src/test/test_sourcecode/javaparser_src/proper_source"));
+
+    private SourceFileInfoExtractor getSourceFileInfoExtractor() {
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+        combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_src/generated"))));
+        SourceFileInfoExtractor sourceFileInfoExtractor = new SourceFileInfoExtractor();
+        sourceFileInfoExtractor.setTypeSolver(combinedTypeSolver);
+        sourceFileInfoExtractor.setPrintFileName(false);
+        return sourceFileInfoExtractor;
+    }
+
+    static String readFile(File file)
+            throws IOException {
+        byte[] encoded = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
+        return new String(encoded, StandardCharsets.UTF_8);
+    }
+
+    private static final boolean DEBUG = true;
+
+    private void parse(String fileName) throws IOException, ParseException {
+        File sourceFile = new File(src.getAbsolutePath() + "/" + fileName + ".java");
+        SourceFileInfoExtractor sourceFileInfoExtractor = getSourceFileInfoExtractor();
+        OutputStream outErrStream = new ByteArrayOutputStream();
+        PrintStream outErr = new PrintStream(outErrStream);
+
+        sourceFileInfoExtractor.setOut(outErr);
+        sourceFileInfoExtractor.setErr(outErr);
+        sourceFileInfoExtractor.solve(sourceFile);
+        String output = outErrStream.toString();
+
+        String path = "src/test/resources/javaparser_expected_output/" + fileName.replaceAll("/", "_") + ".txt";
+        File dstFile = adaptPath(new File(path));
+
+        if (DEBUG && (sourceFileInfoExtractor.getKo() != 0 || sourceFileInfoExtractor.getUnsupported() != 0)) {
+            System.err.println(output);
+        }
+
+        assertTrue("No failures expected when analyzing " + path, 0 == sourceFileInfoExtractor.getKo());
+        assertTrue("No UnsupportedOperationException expected when analyzing " + path, 0 == sourceFileInfoExtractor.getUnsupported());
+
+        String expected = readFile(dstFile);
+
+        String[] outputLines = output.split("\n");
+        String[] expectedLines = expected.split("\n");
+
+        for (int i = 0; i < Math.min(outputLines.length, expectedLines.length); i++) {
+            assertEquals("Line " + (i + 1) + " of " + path + " is different from what is expected", expectedLines[i].trim(), outputLines[i].trim());
+        }
+
+        assertEquals(expectedLines.length, outputLines.length);
+
+        JavaParserFacade.clearInstances();
+
+        // If we need to update the file uncomment these lines
+        //PrintWriter writer = new PrintWriter(dstFile.getAbsoluteFile(), "UTF-8");
+        //writer.print(output);
+        //writer.close();
+    }
+
+    @Test
+    public void parsePositionUtils() throws IOException, ParseException {
+        parse("com/github/javaparser/PositionUtils");
+    }
+
+    @Test
+    public void parseJavaParser() throws IOException, ParseException {
+        parse("com/github/javaparser/JavaParser");
+    }
+
+    @Test
+    public void parseStatement() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/stmt/Statement");
+    }
+
+    @Test
+    public void parseCatchClause() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/stmt/CatchClause");
+    }
+
+    @Test
+    public void parseStatements() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/stmt/LabeledStmt");
+        parse("com/github/javaparser/ast/stmt/BreakStmt");
+        parse("com/github/javaparser/ast/stmt/ReturnStmt");
+        parse("com/github/javaparser/ast/stmt/DoStmt");
+        parse("com/github/javaparser/ast/stmt/AssertStmt");
+        parse("com/github/javaparser/ast/stmt/ContinueStmt");
+        parse("com/github/javaparser/ast/stmt/BlockStmt");
+        parse("com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt");
+        parse("com/github/javaparser/ast/stmt/ExpressionStmt");
+        parse("com/github/javaparser/ast/stmt/EmptyStmt");
+        parse("com/github/javaparser/ast/stmt/SwitchStmt");
+        parse("com/github/javaparser/ast/stmt/IfStmt");
+        parse("com/github/javaparser/ast/stmt/SwitchEntryStmt");
+        parse("com/github/javaparser/ast/stmt/SynchronizedStmt");
+        parse("com/github/javaparser/ast/stmt/ForeachStmt");
+        parse("com/github/javaparser/ast/stmt/ForStmt");
+        parse("com/github/javaparser/ast/stmt/WhileStmt");
+        parse("com/github/javaparser/ast/stmt/ThrowStmt");
+        parse("com/github/javaparser/ast/stmt/TryStmt");
+        parse("com/github/javaparser/ast/stmt/TypeDeclarationStmt");
+    }
+
+    @Test
+    public void parseExpressions() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/expr/NameExpr");
+        parse("com/github/javaparser/ast/expr/FieldAccessExpr");
+        parse("com/github/javaparser/ast/expr/CharLiteralExpr");
+        parse("com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr");
+        parse("com/github/javaparser/ast/expr/IntegerLiteralExpr");
+        parse("com/github/javaparser/ast/expr/ArrayCreationExpr");
+        parse("com/github/javaparser/ast/expr/VariableDeclarationExpr");
+        parse("com/github/javaparser/ast/expr/SuperExpr");
+        parse("com/github/javaparser/ast/expr/ArrayInitializerExpr");
+        parse("com/github/javaparser/ast/expr/EnclosedExpr");
+        parse("com/github/javaparser/ast/expr/Expression");
+        parse("com/github/javaparser/ast/expr/SingleMemberAnnotationExpr");
+        parse("com/github/javaparser/ast/expr/MethodReferenceExpr");
+        parse("com/github/javaparser/ast/expr/ThisExpr");
+        parse("com/github/javaparser/ast/expr/LiteralExpr");
+        parse("com/github/javaparser/ast/expr/AnnotationExpr");
+        parse("com/github/javaparser/ast/expr/InstanceOfExpr");
+        parse("com/github/javaparser/ast/expr/LongLiteralExpr");
+        parse("com/github/javaparser/ast/expr/StringLiteralExpr");
+        parse("com/github/javaparser/ast/expr/NullLiteralExpr");
+        parse("com/github/javaparser/ast/expr/ObjectCreationExpr");
+        parse("com/github/javaparser/ast/expr/TypeExpr");
+        parse("com/github/javaparser/ast/expr/DoubleLiteralExpr");
+        parse("com/github/javaparser/ast/expr/LongLiteralMinValueExpr");
+        parse("com/github/javaparser/ast/expr/MarkerAnnotationExpr");
+        parse("com/github/javaparser/ast/expr/LambdaExpr");
+        parse("com/github/javaparser/ast/expr/AssignExpr");
+        parse("com/github/javaparser/ast/expr/NormalAnnotationExpr");
+        parse("com/github/javaparser/ast/expr/QualifiedNameExpr");
+        parse("com/github/javaparser/ast/expr/MemberValuePair");
+        parse("com/github/javaparser/ast/expr/ArrayAccessExpr");
+        parse("com/github/javaparser/ast/expr/ClassExpr");
+        parse("com/github/javaparser/ast/expr/MethodCallExpr");
+        parse("com/github/javaparser/ast/expr/ConditionalExpr");
+        parse("com/github/javaparser/ast/expr/CastExpr");
+        parse("com/github/javaparser/ast/expr/BooleanLiteralExpr");
+        parse("com/github/javaparser/ast/expr/BinaryExpr");
+        parse("com/github/javaparser/ast/expr/UnaryExpr");
+    }
+
+    @Test
+    public void parseTypes() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/type/ClassOrInterfaceType");
+        parse("com/github/javaparser/ast/type/PrimitiveType");
+        parse("com/github/javaparser/ast/type/WildcardType");
+        parse("com/github/javaparser/ast/type/UnknownType");
+        parse("com/github/javaparser/ast/type/ReferenceType");
+        parse("com/github/javaparser/ast/type/VoidType");
+        parse("com/github/javaparser/ast/type/Type");
+    }
+
+    @Test
+    public void parseVisitors() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/visitor/EqualsVisitor");
+        parse("com/github/javaparser/ast/visitor/ModifierVisitorAdapter");
+        parse("com/github/javaparser/ast/visitor/DumpVisitor");
+        parse("com/github/javaparser/ast/visitor/VoidVisitor");
+        parse("com/github/javaparser/ast/visitor/GenericVisitor");
+        parse("com/github/javaparser/ast/visitor/VoidVisitorAdapter");
+        parse("com/github/javaparser/ast/visitor/GenericVisitorAdapter");
+    }
+
+    @Test
+    public void parseCloneVisitor() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/visitor/CloneVisitor");
+    }
+
+    @Test
+    public void parseSourcesHelper() throws IOException, ParseException {
+        parse("com/github/javaparser/SourcesHelper");
+    }
+
+    @Test
+    public void parseComments() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/comments/LineComment");
+        parse("com/github/javaparser/ast/comments/Comment");
+        parse("com/github/javaparser/ast/comments/CommentsParser");
+        parse("com/github/javaparser/ast/comments/JavadocComment");
+        parse("com/github/javaparser/ast/comments/BlockComment");
+        parse("com/github/javaparser/ast/comments/CommentsCollection");
+    }
+
+    @Test
+    public void parseTheRest() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/internal/Utils");
+        parse("com/github/javaparser/ast/body/AnnotationMemberDeclaration");
+        parse("com/github/javaparser/ast/body/EnumDeclaration");
+        parse("com/github/javaparser/ast/body/Parameter");
+        parse("com/github/javaparser/ast/body/EnumConstantDeclaration");
+        parse("com/github/javaparser/ast/body/VariableDeclarator");
+        parse("com/github/javaparser/ast/body/TypeDeclaration");
+        parse("com/github/javaparser/ast/body/EmptyMemberDeclaration");
+        parse("com/github/javaparser/ast/body/ModifierSet");
+        parse("com/github/javaparser/ast/body/VariableDeclaratorId");
+        parse("com/github/javaparser/ast/body/BaseParameter");
+        parse("com/github/javaparser/ast/body/AnnotableNode");
+        parse("com/github/javaparser/ast/body/AnnotationDeclaration");
+        parse("com/github/javaparser/ast/body/MethodDeclaration");
+        parse("com/github/javaparser/ast/body/EmptyTypeDeclaration");
+        parse("com/github/javaparser/ast/body/InitializerDeclaration");
+        parse("com/github/javaparser/ast/body/BodyDeclaration");
+        parse("com/github/javaparser/ast/body/FieldDeclaration");
+        parse("com/github/javaparser/ast/body/ConstructorDeclaration");
+        parse("com/github/javaparser/ast/body/WithDeclaration");
+        parse("com/github/javaparser/ast/body/MultiTypeParameter");
+        parse("com/github/javaparser/ast/body/ClassOrInterfaceDeclaration");
+        parse("com/github/javaparser/ast/TreeVisitor");
+        parse("com/github/javaparser/ast/PackageDeclaration");
+        parse("com/github/javaparser/ast/DocumentableNode");
+        parse("com/github/javaparser/ast/NamedNode");
+        parse("com/github/javaparser/ast/Node");
+        parse("com/github/javaparser/ast/AccessSpecifier");
+        parse("com/github/javaparser/ast/CompilationUnit");
+        parse("com/github/javaparser/ast/TypeParameter");
+        parse("com/github/javaparser/ast/ImportDeclaration");
+        parse("com/github/javaparser/Position");
+        parse("com/github/javaparser/ASTHelper");
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaSymbolSolver060Test.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaSymbolSolver060Test.java
new file mode 100644
index 0000000..1cce12a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseJavaSymbolSolver060Test.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.SlowTest;
+import com.github.javaparser.symbolsolver.SourceFileInfoExtractor;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * We analyze JavaParser version 0.6.0.
+ */
+@Category(SlowTest.class)
+public class AnalyseJavaSymbolSolver060Test extends AbstractResolutionTest {
+
+    private static final File root = adaptPath(new File("src/test/resources/javasymbolsolver_0_6_0"));
+    private static final File src = adaptPath(new File(root + "/src"));
+    private static final File lib = adaptPath(new File(root + "/lib"));
+    private static final File expectedOutput = adaptPath(new File(root + "/expected_output"));
+
+    private static SourceFileInfoExtractor getSourceFileInfoExtractor() {
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(new File(src + "/java-symbol-solver-core")));
+        combinedTypeSolver.add(new JavaParserTypeSolver(new File(src + "/java-symbol-solver-logic")));
+        combinedTypeSolver.add(new JavaParserTypeSolver(new File(src + "/java-symbol-solver-model")));
+        try {
+			combinedTypeSolver.add(new JarTypeSolver(lib + "/guava-21.0.jar"));
+			combinedTypeSolver.add(new JarTypeSolver(lib + "/javaparser-core-3.3.0.jar"));
+			combinedTypeSolver.add(new JarTypeSolver(lib + "/javaslang-2.0.3.jar"));
+			combinedTypeSolver.add(new JarTypeSolver(lib + "/javassist-3.19.0-GA.jar"));
+		} catch (IOException e) {
+			Assert.fail("one or more jar dependencies could not be found.");
+			e.printStackTrace();
+		}
+        SourceFileInfoExtractor sourceFileInfoExtractor = new SourceFileInfoExtractor();
+        sourceFileInfoExtractor.setTypeSolver(combinedTypeSolver);
+        sourceFileInfoExtractor.setPrintFileName(false);
+        sourceFileInfoExtractor.setVerbose(true);
+        return sourceFileInfoExtractor;
+    }
+
+    private static SourceFileInfoExtractor sourceFileInfoExtractor = getSourceFileInfoExtractor();
+
+    static String readFile(File file)
+            throws IOException {
+        byte[] encoded = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
+        return new String(encoded, StandardCharsets.UTF_8);
+    }
+
+    private static final boolean DEBUG = true;
+
+    /**
+     * @param projectName is one of "java-symbol-solver-core", "java-symbol-solver-logic", "java-symbol-solver-model"
+     * @param fileName describes the file being analyzed
+     * @throws IOException
+     * @throws ParseException
+     */
+    private void parse(String projectName, String fileName) throws IOException, ParseException {
+        File sourceFile = new File(src.getAbsolutePath() + "/" + projectName + "/" + fileName + ".java");
+        OutputStream outErrStream = new ByteArrayOutputStream();
+        PrintStream outErr = new PrintStream(outErrStream);
+
+        sourceFileInfoExtractor.setOut(outErr);
+        sourceFileInfoExtractor.setErr(outErr);
+        sourceFileInfoExtractor.solveMethodCalls(sourceFile);
+        String output = outErrStream.toString();
+
+        String path = adaptPath(expectedOutput).getPath() + "/" + projectName + "/" + fileName.replaceAll("/", "_") + ".txt";
+        File dstFile = new File(path);
+
+        if (isJava9()) {
+            String path9 = adaptPath(expectedOutput).getPath() + "/" + projectName + "/" + fileName.replaceAll("/", "_") + "_J9.txt";
+            File dstFile9 = new File(path9);
+            if (dstFile9.exists()) {
+                path = path9;
+                dstFile = dstFile9;
+            }
+        }
+
+        if (DEBUG && (sourceFileInfoExtractor.getKo() != 0 || sourceFileInfoExtractor.getUnsupported() != 0)) {
+            System.err.println(output);
+        }
+
+        assertTrue("No failures expected when analyzing " + path, 0 == sourceFileInfoExtractor.getKo());
+        assertTrue("No UnsupportedOperationException expected when analyzing " + path, 0 == sourceFileInfoExtractor.getUnsupported());
+
+        if (!dstFile.exists()) {
+            // If we need to update the file uncomment these lines
+//            PrintWriter writer = new PrintWriter(dstFile.getAbsoluteFile(), "UTF-8");
+//            writer.print(output);
+//            writer.close();
+        }
+
+        String expected = readFile(dstFile);
+
+        String[] outputLines = output.split("\n");
+        String[] expectedLines = expected.split("\n");
+
+        for (int i = 0; i < Math.min(outputLines.length, expectedLines.length); i++) {
+            assertEquals("Line " + (i + 1) + " of " + path + " is different from what is expected", expectedLines[i].trim(), outputLines[i].trim());
+        }
+
+        assertEquals(expectedLines.length, outputLines.length);
+
+        JavaParserFacade.clearInstances();
+    }
+
+    @Test
+    public void parseCoreSourceFileInfoExtractor() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/SourceFileInfoExtractor");
+    }
+
+    @Test
+    public void parseCoreCoreResolution() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/core/resolution/Context");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/core/resolution/ContextHelper");
+    }
+
+    @Test
+    public void parseCoreDeclarationsCommon() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/declarations/common/MethodDeclarationCommonLogic");
+    }
+
+    @Test
+    public void parseCoreJavaparserNavigator() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparser/Navigator");
+    }
+
+    @Test
+    public void parseCoreJavaparsermodel() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/DefaultVisitorAdapter");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFacade");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/JavaParserFactory");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/LambdaArgumentTypePlaceholder");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/TypeExtractor");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/UnsolvedSymbolException");
+    }
+
+    @Test
+    public void parseCoreJavaparsermodelContexts() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractJavaParserContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/AbstractMethodLikeDeclarationContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/AnonymousClassDeclarationContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/CatchClauseContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ClassOrInterfaceDeclarationContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/CompilationUnitContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ConstructorContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ContextHelper");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/EnumDeclarationContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/FieldAccessContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForechStatementContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/ForStatementContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/JavaParserTypeDeclarationAdapter");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/LambdaExprContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodCallExprContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/MethodContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/StatementContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/SwitchEntryContext");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/contexts/TryWithResourceContext");
+    }
+
+    @Test
+    public void parseCoreJavaparsermodelDeclarations() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/DefaultConstructorDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/Helper");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnnotationDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserAnonymousClassDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserClassDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserConstructorDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumConstantDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserEnumDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserFieldDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserInterfaceDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserMethodDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserParameterDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserSymbolDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeAdapter");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeParameter");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarations/JavaParserTypeVariableDeclaration");
+    }
+
+    @Test
+    public void parseCoreJavaparsermodelDeclarators() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/AbstractSymbolDeclarator");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/FieldSymbolDeclarator");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/NoSymbolDeclarator");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/ParameterSymbolDeclarator");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javaparsermodel/declarators/VariableSymbolDeclarator");
+    }
+
+    @Test
+    public void parseCoreJavassistmodel() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistClassDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistConstructorDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistEnumDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistFactory");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistFieldDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistInterfaceDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistMethodDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistParameterDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeDeclarationAdapter");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistTypeParameter");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/javassistmodel/JavassistUtils");
+    }
+
+    @Test
+    public void parseCoreModelTypesystem() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/model/typesystem/LazyType");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/model/typesystem/ReferenceTypeImpl");
+    }
+
+    @Test
+    public void parseCoreReflectionmodel() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/MyObjectProvider");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassAdapter");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionClassDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionConstructorDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionEnumDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFactory");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionFieldDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionInterfaceDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionMethodResolutionLogic");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionParameterDeclaration");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/ReflectionTypeParameter");
+    }
+
+    @Test
+    public void parseCoreReflectionmodelComparators() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/comparators/ClassComparator");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/comparators/MethodComparator");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/reflectionmodel/comparators/ParameterComparator");
+    }
+
+    @Test
+    public void parseCoreResolution() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/ConstructorResolutionLogic");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/MethodResolutionLogic");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/SymbolDeclarator");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/SymbolSolver");
+    }
+
+    @Test
+    public void parseCoreResolutionTypesolvers() throws IOException, ParseException {
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/CombinedTypeSolver");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolver");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/JavaParserTypeSolver");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/MemoryTypeSolver");
+        parse("java-symbol-solver-core", "com/github/javaparser/symbolsolver/resolution/typesolvers/ReflectionTypeSolver");
+    }
+
+    @Test
+    public void parseLogic() throws IOException, ParseException {
+		parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/AbstractClassDeclaration");
+		parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/AbstractTypeDeclaration");
+		parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/ConfilictingGenericTypesException");
+		parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/FunctionalInterfaceLogic");
+		parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/InferenceContext");
+		parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/InferenceVariableType");
+		parse("java-symbol-solver-logic", "com/github/javaparser/symbolsolver/logic/ObjectProvider");
+    }
+
+    @Test
+    public void parseModelDeclarations() throws IOException, ParseException {
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/AccessLevel");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/AnnotationDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ClassDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ConstructorDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/Declaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/EnumDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/FieldDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/HasAccessLevel");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/InterfaceDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/MethodAmbiguityException");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/MethodDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/MethodLikeDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ParameterDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ReferenceTypeDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/TypeDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/TypeParameterDeclaration");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/TypeParametrizable");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/declarations/ValueDeclaration");
+    }
+
+    @Test
+    public void parseModelMethodsMethodUsage() throws IOException, ParseException {
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/methods/MethodUsage");
+    }
+
+    @Test
+    public void parseModelResolution() throws IOException, ParseException {
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/SymbolReference");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/TypeSolver");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/UnsolvedSymbolException");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/resolution/Value");
+    }
+
+    @Test
+    public void parseModelTypesystem() throws IOException, ParseException {
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/ArrayType");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/LambdaConstraintType");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/NullType");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/PrimitiveType");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/ReferenceType");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/Type");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/TypeTransformer");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/TypeVariable");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/VoidType");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/Wildcard");
+    }
+
+    @Test
+    public void parseModelTypesystemParametrization() throws IOException, ParseException {
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametersMap");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParameterValueProvider");
+        parse("java-symbol-solver-model", "com/github/javaparser/symbolsolver/model/typesystem/parametrization/TypeParametrized");
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserHelpersTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserHelpersTest.java
new file mode 100644
index 0000000..254609e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserHelpersTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * We analize a more recent version of JavaParser, after the project moved to Java 8.
+ */
+public class AnalyseNewJavaParserHelpersTest extends AbstractResolutionTest {
+
+    private static final File src = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+
+    private static TypeSolver TYPESOLVER = typeSolver();
+
+    private static TypeSolver typeSolver() {
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+        combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        return combinedTypeSolver;
+    }
+
+    private CompilationUnit parse(String fileName) throws IOException {
+        File sourceFile = new File(src.getAbsolutePath() + "/" + fileName + ".java");
+        return JavaParser.parse(sourceFile);
+    }
+
+//    @Test
+//    public void o1TypeIsCorrect() throws IOException, ParseException {
+//        CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils");
+//        NameExpr o1 = Navigator.findAllNodesOfGivenClass(cu, NameExpr.class).stream().filter(it -> it.getName()!=null && it.getName().equals("o1")).findFirst().get();
+//        System.out.println(JavaParserFacade.get(TYPESOLVER).solve(o1).getCorrespondingDeclaration().getType());
+//    }
+//
+//    @Test
+//    public void o2TypeIsCorrect() throws IOException, ParseException {
+//        CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils");
+//        NameExpr o2 = Navigator.findAllNodesOfGivenClass(cu, NameExpr.class).stream().filter(it -> it.getName()!=null && it.getName().equals("o2")).findFirst().get();
+//        System.out.println(JavaParserFacade.get(TYPESOLVER).solve(o2).getCorrespondingDeclaration().getType());
+//    }
+//
+//    // To calculate the type of o1 and o2 I need to first calculate the type of the lambda
+//    @Test
+//    public void lambdaTypeIsCorrect() throws IOException, ParseException {
+//        CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils");
+//        LambdaExpr lambda = Navigator.findAllNodesOfGivenClass(cu, LambdaExpr.class).stream().filter(it -> it.getRange().begin.line == 50).findFirst().get();
+//        System.out.println(JavaParserFacade.get(TYPESOLVER).getType(lambda));
+//    }
+
+    @Test
+    public void nodesTypeIsCorrect() throws IOException {
+        CompilationUnit cu = parse("com/github/javaparser/utils/PositionUtils");
+        NameExpr nodes = cu.findAll(NameExpr.class).stream().filter(it -> it.getName() != null && it.getName().getId().equals("nodes")).findFirst().get();
+        ResolvedType type = JavaParserFacade.get(TYPESOLVER).solve(nodes).getCorrespondingDeclaration().getType();
+        assertEquals("java.util.List<T>", type.describe());
+        assertEquals(1, type.asReferenceType().typeParametersValues().size());
+        assertEquals(true, type.asReferenceType().typeParametersValues().get(0).isTypeVariable());
+        assertEquals("T", type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getName());
+        assertEquals("com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>).T", type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getQualifiedName());
+        assertEquals(1, type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getBounds().size());
+        ResolvedTypeParameterDeclaration.Bound bound = type.asReferenceType().typeParametersValues().get(0).asTypeParameter().getBounds().get(0);
+        assertEquals(true, bound.isExtends());
+        assertEquals("com.github.javaparser.ast.Node", bound.getType().describe());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserTest.java
new file mode 100644
index 0000000..53c0e04
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/AnalyseNewJavaParserTest.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.SlowTest;
+import com.github.javaparser.symbolsolver.SourceFileInfoExtractor;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * We analyze a more recent version of JavaParser, after the project moved to Java 8.
+ */
+@Category(SlowTest.class)
+public class AnalyseNewJavaParserTest extends AbstractResolutionTest {
+
+    private static final File src = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+
+    private static SourceFileInfoExtractor getSourceFileInfoExtractor() {
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+        combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        SourceFileInfoExtractor sourceFileInfoExtractor = new SourceFileInfoExtractor();
+        sourceFileInfoExtractor.setTypeSolver(combinedTypeSolver);
+        sourceFileInfoExtractor.setPrintFileName(false);
+        sourceFileInfoExtractor.setVerbose(true);
+        return sourceFileInfoExtractor;
+    }
+
+    private static SourceFileInfoExtractor sourceFileInfoExtractor = getSourceFileInfoExtractor();
+
+    static String readFile(File file)
+            throws IOException {
+        byte[] encoded = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
+        return new String(encoded, StandardCharsets.UTF_8);
+    }
+
+    private static final boolean DEBUG = true;
+
+    private void parse(String fileName) throws IOException, ParseException {
+        File sourceFile = new File(src.getAbsolutePath() + "/" + fileName + ".java");
+        OutputStream outErrStream = new ByteArrayOutputStream();
+        PrintStream outErr = new PrintStream(outErrStream);
+
+        sourceFileInfoExtractor.setOut(outErr);
+        sourceFileInfoExtractor.setErr(outErr);
+        sourceFileInfoExtractor.solveMethodCalls(sourceFile);
+        String output = outErrStream.toString();
+
+        File expectedOutput = new File("src/test/resources/javaparser_methodcalls_expected_output");
+        String path = adaptPath(expectedOutput).getPath() + "/" + fileName.replaceAll("/", "_") + ".txt";
+        File dstFile = new File(path);
+
+        if (isJava9()) {
+            String path9 = adaptPath(expectedOutput).getPath() + "/" + fileName.replaceAll("/", "_") + "_J9.txt";
+            File dstFile9 = new File(path9);
+            if (dstFile9.exists()) {
+                path = path9;
+                dstFile = dstFile9;
+            }
+        }
+
+        if (DEBUG && (sourceFileInfoExtractor.getKo() != 0 || sourceFileInfoExtractor.getUnsupported() != 0)) {
+            System.err.println(output);
+        }
+
+        assertTrue("No failures expected when analyzing " + path, 0 == sourceFileInfoExtractor.getKo());
+        assertTrue("No UnsupportedOperationException expected when analyzing " + path, 0 == sourceFileInfoExtractor.getUnsupported());
+
+        if (!dstFile.exists()) {
+            // If we need to update the file uncomment these lines
+            PrintWriter writer = new PrintWriter(dstFile.getAbsoluteFile(), "UTF-8");
+            writer.print(output);
+            writer.close();
+        }
+
+        String expected = readFile(dstFile);
+
+        String[] outputLines = output.split("\n");
+        String[] expectedLines = expected.split("\n");
+
+        for (int i = 0; i < Math.min(outputLines.length, expectedLines.length); i++) {
+            assertEquals("Line " + (i + 1) + " of " + path + " is different from what is expected", expectedLines[i].trim(), outputLines[i].trim());
+        }
+
+        assertEquals(expectedLines.length, outputLines.length);
+
+        JavaParserFacade.clearInstances();
+    }
+
+    @Test
+    public void parseUtilsUtils() throws IOException, ParseException {
+        parse("com/github/javaparser/utils/Utils");
+    }
+
+    @Test
+    public void parseCommentsInserter() throws IOException, ParseException {
+        parse("com/github/javaparser/CommentsInserter");
+    }
+
+    @Test
+    public void parsePositionUtils() throws IOException, ParseException {
+        parse("com/github/javaparser/utils/PositionUtils");
+    }
+
+    @Test
+    public void parseModifier() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/Modifier");
+    }
+
+    @Test
+    public void parseNodeWithMembers() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithMembers");
+    }
+
+    @Test
+    public void parseAstStmts() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/stmt/AssertStmt");
+        parse("com/github/javaparser/ast/stmt/BlockStmt");
+        parse("com/github/javaparser/ast/stmt/BreakStmt");
+        parse("com/github/javaparser/ast/stmt/CatchClause");
+        parse("com/github/javaparser/ast/stmt/ContinueStmt");
+        parse("com/github/javaparser/ast/stmt/DoStmt");
+        parse("com/github/javaparser/ast/stmt/EmptyStmt");
+        parse("com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt");
+        parse("com/github/javaparser/ast/stmt/ExpressionStmt");
+        parse("com/github/javaparser/ast/stmt/ForStmt");
+        parse("com/github/javaparser/ast/stmt/ForeachStmt");
+        parse("com/github/javaparser/ast/stmt/IfStmt");
+        parse("com/github/javaparser/ast/stmt/LabeledStmt");
+        parse("com/github/javaparser/ast/stmt/ReturnStmt");
+        parse("com/github/javaparser/ast/stmt/Statement");
+        parse("com/github/javaparser/ast/stmt/SwitchEntryStmt");
+        parse("com/github/javaparser/ast/stmt/SwitchStmt");
+        parse("com/github/javaparser/ast/stmt/SynchronizedStmt");
+        parse("com/github/javaparser/ast/stmt/ThrowStmt");
+        parse("com/github/javaparser/ast/stmt/TryStmt");
+        parse("com/github/javaparser/ast/stmt/TypeDeclarationStmt");
+        parse("com/github/javaparser/ast/stmt/WhileStmt");
+    }
+
+    @Test
+    public void parseAstExprs() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/expr/AnnotationExpr");
+        parse("com/github/javaparser/ast/expr/ArrayAccessExpr");
+        parse("com/github/javaparser/ast/expr/ArrayCreationExpr");
+        parse("com/github/javaparser/ast/expr/ArrayInitializerExpr");
+        parse("com/github/javaparser/ast/expr/AssignExpr");
+        parse("com/github/javaparser/ast/expr/BinaryExpr");
+        parse("com/github/javaparser/ast/expr/BooleanLiteralExpr");
+        parse("com/github/javaparser/ast/expr/CastExpr");
+        parse("com/github/javaparser/ast/expr/CharLiteralExpr");
+        parse("com/github/javaparser/ast/expr/ClassExpr");
+        parse("com/github/javaparser/ast/expr/ConditionalExpr");
+        parse("com/github/javaparser/ast/expr/DoubleLiteralExpr");
+        parse("com/github/javaparser/ast/expr/EnclosedExpr");
+        parse("com/github/javaparser/ast/expr/Expression");
+        parse("com/github/javaparser/ast/expr/FieldAccessExpr");
+        parse("com/github/javaparser/ast/expr/InstanceOfExpr");
+        parse("com/github/javaparser/ast/expr/IntegerLiteralExpr");
+        parse("com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr");
+        parse("com/github/javaparser/ast/expr/LambdaExpr");
+        parse("com/github/javaparser/ast/expr/LiteralExpr");
+        parse("com/github/javaparser/ast/expr/LongLiteralExpr");
+        parse("com/github/javaparser/ast/expr/LongLiteralMinValueExpr");
+        parse("com/github/javaparser/ast/expr/MarkerAnnotationExpr");
+        parse("com/github/javaparser/ast/expr/MemberValuePair");
+        parse("com/github/javaparser/ast/expr/MethodCallExpr");
+        parse("com/github/javaparser/ast/expr/MethodReferenceExpr");
+        parse("com/github/javaparser/ast/expr/NameExpr");
+        parse("com/github/javaparser/ast/expr/NormalAnnotationExpr");
+        parse("com/github/javaparser/ast/expr/NullLiteralExpr");
+        parse("com/github/javaparser/ast/expr/ObjectCreationExpr");
+        parse("com/github/javaparser/ast/expr/QualifiedNameExpr");
+        parse("com/github/javaparser/ast/expr/SingleMemberAnnotationExpr");
+        parse("com/github/javaparser/ast/expr/StringLiteralExpr");
+        parse("com/github/javaparser/ast/expr/SuperExpr");
+        parse("com/github/javaparser/ast/expr/ThisExpr");
+        parse("com/github/javaparser/ast/expr/TypeExpr");
+        parse("com/github/javaparser/ast/expr/UnaryExpr");
+    }
+
+    @Test
+    public void parseVariableDeclarationExpr() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/expr/VariableDeclarationExpr");
+    }
+
+    @Test
+    public void parseAstBody() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/body/AnnotationDeclaration");
+        parse("com/github/javaparser/ast/body/AnnotationMemberDeclaration");
+        parse("com/github/javaparser/ast/body/BodyDeclaration");
+        parse("com/github/javaparser/ast/body/ClassOrInterfaceDeclaration");
+        parse("com/github/javaparser/ast/body/ConstructorDeclaration");
+        parse("com/github/javaparser/ast/body/EmptyMemberDeclaration");
+        parse("com/github/javaparser/ast/body/EmptyTypeDeclaration");
+        parse("com/github/javaparser/ast/body/EnumConstantDeclaration");
+        parse("com/github/javaparser/ast/body/EnumDeclaration");
+        parse("com/github/javaparser/ast/body/FieldDeclaration");
+        parse("com/github/javaparser/ast/body/InitializerDeclaration");
+        parse("com/github/javaparser/ast/body/MethodDeclaration");
+        parse("com/github/javaparser/ast/body/Parameter");
+        parse("com/github/javaparser/ast/body/TypeDeclaration");
+        parse("com/github/javaparser/ast/body/VariableDeclarator");
+        parse("com/github/javaparser/ast/body/VariableDeclaratorId");
+    }
+
+    @Test
+    public void parseAstComments() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/comments/BlockComment");
+        parse("com/github/javaparser/ast/comments/Comment");
+        parse("com/github/javaparser/ast/comments/CommentsCollection");
+        parse("com/github/javaparser/ast/comments/JavadocComment");
+        parse("com/github/javaparser/ast/comments/LineComment");
+    }
+
+    @Test
+    public void parseAstRest() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/AccessSpecifier");
+        parse("com/github/javaparser/ast/ArrayBracketPair");
+        parse("com/github/javaparser/ast/ArrayCreationLevel");
+        parse("com/github/javaparser/ast/CompilationUnit");
+        parse("com/github/javaparser/ast/Example");
+        parse("com/github/javaparser/ast/ImportDeclaration");
+        parse("com/github/javaparser/ast/Node");
+        parse("com/github/javaparser/ast/PackageDeclaration");
+        parse("com/github/javaparser/ast/UserDataKey");
+    }
+
+    @Test
+    public void parseAstNodeTypes() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithAnnotations");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithBody");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithDeclaration");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithElementType");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithExtends");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithImplements");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithJavaDoc");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithModifiers");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithName");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithParameters");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithStatements");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithThrowable");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithType");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments");
+        parse("com/github/javaparser/ast/nodeTypes/NodeWithVariables");
+    }
+
+    @Test
+    public void parseAstTypes() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/type/ArrayType");
+        parse("com/github/javaparser/ast/type/ClassOrInterfaceType");
+        parse("com/github/javaparser/ast/type/IntersectionType");
+        parse("com/github/javaparser/ast/type/PrimitiveType");
+        parse("com/github/javaparser/ast/type/ReferenceType");
+        parse("com/github/javaparser/ast/type/Type");
+        parse("com/github/javaparser/ast/type/TypeParameter");
+        parse("com/github/javaparser/ast/type/UnionType");
+        parse("com/github/javaparser/ast/type/UnknownType");
+        parse("com/github/javaparser/ast/type/VoidType");
+        parse("com/github/javaparser/ast/type/WildcardType");
+    }
+
+    @Test
+    public void parseAstVisitor() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/visitor/CloneVisitor");
+        parse("com/github/javaparser/ast/visitor/EqualsVisitor");
+        parse("com/github/javaparser/ast/visitor/GenericVisitor");
+        parse("com/github/javaparser/ast/visitor/GenericVisitorAdapter");
+        parse("com/github/javaparser/ast/visitor/ModifierVisitorAdapter");
+        parse("com/github/javaparser/ast/visitor/TreeVisitor");
+        parse("com/github/javaparser/ast/visitor/VoidVisitor");
+        parse("com/github/javaparser/ast/visitor/VoidVisitorAdapter");
+    }
+
+    @Test
+    public void parseDumpVisitor() throws IOException, ParseException {
+        parse("com/github/javaparser/ast/visitor/DumpVisitor");
+    }
+
+    @Test
+    public void parseUtils() throws IOException, ParseException {
+        parse("com/github/javaparser/utils/ClassUtils");
+        parse("com/github/javaparser/utils/Pair");
+    }
+
+    @Test
+    public void parseAllOtherNodes() throws IOException, ParseException {
+        parse("com/github/javaparser/JavaParser");
+        parse("com/github/javaparser/ParseProblemException");
+        parse("com/github/javaparser/ParseResult");
+        parse("com/github/javaparser/ParseStart");
+        parse("com/github/javaparser/ParserConfiguration");
+        parse("com/github/javaparser/Position");
+        parse("com/github/javaparser/Problem");
+        parse("com/github/javaparser/Providers");
+        parse("com/github/javaparser/Range");
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ArrayExprTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ArrayExprTest.java
new file mode 100644
index 0000000..92b9733
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ArrayExprTest.java
@@ -0,0 +1,26 @@
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * See issue #17
+ */
+public class ArrayExprTest {
+
+    @Test
+    public void verifyAnArrayAccessExprTypeIsCalculatedProperly() {
+        String code = "class A { String[] arrSQL; String toExamine = arrSQL[1]; }";
+        FieldDeclaration field = JavaParser.parse(code).getClassByName("A").get().getFieldByName("toExamine").get();
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(field.getVariables().get(0).getInitializer().get());
+        assertEquals(true, type.isReferenceType());
+        assertEquals("java.lang.String", type.asReferenceType().getQualifiedName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ContextTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ContextTest.java
new file mode 100644
index 0000000..45cc56e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/ContextTest.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedClassDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.*;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ContextTest extends AbstractTest {
+
+    private TypeSolver typeSolver = new CombinedTypeSolver(new MemoryTypeSolver(), new ReflectionTypeSolver());
+
+    private CompilationUnit parseSample(String sampleName) {
+        InputStream is = ContextTest.class.getClassLoader().getResourceAsStream(sampleName + ".java.txt");
+        return JavaParser.parse(is);
+    }
+
+    @Test
+    public void resolveDeclaredFieldReference() {
+        CompilationUnit cu = parseSample("ReferencesToField");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "ReferencesToField");
+        MethodDeclaration method1 = Navigator.demandMethod(referencesToField, "method1");
+        ExpressionStmt stmt = (ExpressionStmt) method1.getBody().get().getStatements().get(0);
+        AssignExpr assignExpr = (AssignExpr) stmt.getExpression();
+
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        SymbolReference symbolReference = symbolSolver.solveSymbol("i", assignExpr.getTarget());
+
+        assertEquals(true, symbolReference.isSolved());
+        assertEquals("i", symbolReference.getCorrespondingDeclaration().getName());
+        assertEquals(true, symbolReference.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void resolveInheritedFieldReference() {
+        CompilationUnit cu = parseSample("ReferencesToField");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "ReferencesToFieldExtendingClass");
+        MethodDeclaration method1 = Navigator.demandMethod(referencesToField, "method2");
+        ExpressionStmt stmt = (ExpressionStmt) method1.getBody().get().getStatements().get(0);
+        AssignExpr assignExpr = (AssignExpr) stmt.getExpression();
+
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        SymbolReference symbolReference = symbolSolver.solveSymbol("i", assignExpr.getTarget());
+
+        assertEquals(true, symbolReference.isSolved());
+        assertEquals("i", symbolReference.getCorrespondingDeclaration().getName());
+        assertEquals(true, symbolReference.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void resolveParameterReference() {
+        CompilationUnit cu = parseSample("ReferencesToParameter");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "ReferenceToParameter");
+        MethodDeclaration method1 = Navigator.demandMethod(referencesToField, "aMethod");
+        NameExpr foo = Navigator.findNameExpression(method1, "foo").get();
+
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        SymbolReference symbolReference = symbolSolver.solveSymbol("foo", foo);
+
+        assertEquals(true, symbolReference.isSolved());
+        assertEquals("foo", symbolReference.getCorrespondingDeclaration().getName());
+        assertEquals(true, symbolReference.getCorrespondingDeclaration().isParameter());
+    }
+
+    @Test
+    public void resolveReferenceToImportedType() {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType");
+        Parameter param = method.getParameters().get(0);
+
+        ResolvedClassDeclaration compilationUnitDecl = mock(ResolvedClassDeclaration.class);
+        when(compilationUnitDecl.getName()).thenReturn("CompilationUnit");
+        when(compilationUnitDecl.getQualifiedName()).thenReturn("com.github.javaparser.ast.CompilationUnit");
+        TypeSolver typeSolver = mock(TypeSolver.class);
+        when(typeSolver.getRoot()).thenReturn(typeSolver);
+        when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver));
+        when(typeSolver.tryToSolveType("com.github.javaparser.ast.CompilationUnit")).thenReturn(SymbolReference.solved(compilationUnitDecl));
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+
+        SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("CompilationUnit", param);
+
+        assertEquals(true, ref.isSolved());
+        assertEquals("CompilationUnit", ref.getCorrespondingDeclaration().getName());
+        assertEquals("com.github.javaparser.ast.CompilationUnit", ref.getCorrespondingDeclaration().getQualifiedName());
+    }
+
+    @Test
+    public void resolveReferenceUsingQualifiedName() {
+        CompilationUnit cu = parseSample("Navigator2");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType");
+        Parameter param = method.getParameters().get(0);
+
+        ResolvedClassDeclaration compilationUnitDecl = mock(ResolvedClassDeclaration.class);
+        when(compilationUnitDecl.getName()).thenReturn("CompilationUnit");
+        when(compilationUnitDecl.getQualifiedName()).thenReturn("com.github.javaparser.ast.CompilationUnit");
+        TypeSolver typeSolver = mock(TypeSolver.class);
+        //when(typeSolver.tryToSolveType("java.lang.com.github.javaparser.ast.CompilationUnit")).thenReturn(SymbolReference.unsolved(ClassDeclaration.class));
+        when(typeSolver.getRoot()).thenReturn(typeSolver);
+        when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver));
+        when(typeSolver.tryToSolveType("com.github.javaparser.ast.CompilationUnit")).thenReturn(SymbolReference.solved(compilationUnitDecl));
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        
+        SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("com.github.javaparser.ast.CompilationUnit", param);
+
+        assertEquals(true, ref.isSolved());
+        assertEquals("CompilationUnit", ref.getCorrespondingDeclaration().getName());
+        assertEquals("com.github.javaparser.ast.CompilationUnit", ref.getCorrespondingDeclaration().getQualifiedName());
+    }
+
+    @Test
+    public void resolveReferenceToClassesInTheSamePackage() {
+        CompilationUnit cu = parseSample("Navigator3");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType");
+        Parameter param = method.getParameters().get(0);
+
+        ResolvedClassDeclaration compilationUnitDecl = mock(ResolvedClassDeclaration.class);
+        when(compilationUnitDecl.getName()).thenReturn("CompilationUnit");
+        when(compilationUnitDecl.getQualifiedName()).thenReturn("my.packagez.CompilationUnit");
+        TypeSolver typeSolver = mock(TypeSolver.class);
+        when(typeSolver.getRoot()).thenReturn(typeSolver);
+        when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver));
+        when(typeSolver.tryToSolveType("my.packagez.CompilationUnit")).thenReturn(SymbolReference.solved(compilationUnitDecl));
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+
+        SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("CompilationUnit", param);
+
+        assertEquals(true, ref.isSolved());
+        assertEquals("CompilationUnit", ref.getCorrespondingDeclaration().getName());
+        assertEquals("my.packagez.CompilationUnit", ref.getCorrespondingDeclaration().getQualifiedName());
+    }
+
+    @Test
+    public void resolveReferenceToClassInJavaLang() {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType");
+        Parameter param = method.getParameters().get(1);
+
+        ResolvedClassDeclaration stringDecl = mock(ResolvedClassDeclaration.class);
+        when(stringDecl.getName()).thenReturn("String");
+        when(stringDecl.getQualifiedName()).thenReturn("java.lang.String");
+        TypeSolver typeSolver = mock(TypeSolver.class);
+        when(typeSolver.tryToSolveType("me.tomassetti.symbolsolver.javaparser.String")).thenReturn(SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class));
+        when(typeSolver.getRoot()).thenReturn(typeSolver);
+        when(typeSolver.solveType("java.lang.Object")).thenReturn(new ReflectionClassDeclaration(Object.class, typeSolver));
+        when(typeSolver.tryToSolveType("java.lang.String")).thenReturn(SymbolReference.solved(stringDecl));
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+
+        SymbolReference<? extends ResolvedTypeDeclaration> ref = symbolSolver.solveType("String", param);
+
+        assertEquals(true, ref.isSolved());
+        assertEquals("String", ref.getCorrespondingDeclaration().getName());
+        assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getQualifiedName());
+    }
+
+    @Test
+    public void resolveReferenceToMethod() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType");
+        MethodCallExpr callToGetTypes = Navigator.findMethodCall(method, "getTypes").get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToJar), new ReflectionTypeSolver(true));
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+
+        MethodUsage ref = symbolSolver.solveMethod("getTypes", Collections.emptyList(), callToGetTypes);
+
+        assertEquals("getTypes", ref.getName());
+        assertEquals("com.github.javaparser.ast.CompilationUnit", ref.declaringType().getQualifiedName());
+
+        //verify(typeSolver);
+    }
+
+    @Test
+    public void resolveCascadeOfReferencesToMethod() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "findType");
+        MethodCallExpr callToStream = Navigator.findMethodCall(method, "stream").get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToJar), new ReflectionTypeSolver(true));
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        MethodUsage ref = symbolSolver.solveMethod("stream", Collections.emptyList(), callToStream);
+
+        assertEquals("stream", ref.getName());
+        assertEquals("java.util.Collection", ref.declaringType().getQualifiedName());
+    }
+
+    @Test
+    public void resolveReferenceToMethodCalledOnArrayAccess() {
+        CompilationUnit cu = parseSample("ArrayAccess");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ArrayAccess");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "access");
+        MethodCallExpr callToTrim = Navigator.findMethodCall(method, "trim").get();
+
+        File src = adaptPath(new File("src/test/resources"));
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(src));
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        MethodUsage ref = symbolSolver.solveMethod("trim", Collections.emptyList(), callToTrim);
+
+        assertEquals("trim", ref.getName());
+        assertEquals("java.lang.String", ref.declaringType().getQualifiedName());
+    }
+
+    @Test
+    public void resolveReferenceToJreType() {
+        CompilationUnit cu = parseSample("NavigatorSimplified");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo");
+        com.github.javaparser.ast.type.Type streamJavaParserType = method.getParameters().get(0).getType();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType streamType = JavaParserFacade.get(typeSolver).convert(streamJavaParserType, method);
+
+        assertEquals("java.util.stream.Stream<java.lang.String>", streamType.describe());
+    }
+
+    @Test
+    public void resolveReferenceToMethodWithLambda() {
+        CompilationUnit cu = parseSample("NavigatorSimplified");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr methodCallExpr = Navigator.findMethodCall(method, "filter").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType ref = JavaParserFacade.get(typeSolver).getType(methodCallExpr);
+
+        assertEquals("java.util.stream.Stream<java.lang.String>", ref.describe());
+        assertEquals(1, ref.asReferenceType().typeParametersValues().size());
+        assertEquals("java.lang.String", ref.asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveReferenceToLambdaParamBase() {
+        CompilationUnit cu = parseSample("NavigatorSimplified");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        NameExpr refToT = Navigator.findNameExpression(method, "t").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        ResolvedType ref = javaParserFacade.getType(refToT);
+
+        assertEquals("? super java.lang.String", ref.describe());
+    }
+
+    @Test
+    public void resolveReferenceToLambdaParamSimplified() {
+        CompilationUnit cu = parseSample("NavigatorSimplified");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr call = Navigator.findMethodCall(method, "isEmpty").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        MethodUsage ref = symbolSolver.solveMethod("isEmpty", Collections.emptyList(), call);
+
+        assertEquals("isEmpty", ref.getName());
+        assertEquals("java.lang.String", ref.declaringType().getQualifiedName());
+    }
+
+    @Test
+    public void resolveGenericReturnTypeOfMethodInJar() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr call = Navigator.findMethodCall(method, "getTypes").get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar));
+        MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call);
+
+        assertEquals("getTypes", methodUsage.getName());
+        assertEquals("java.util.List<com.github.javaparser.ast.body.TypeDeclaration>", methodUsage.returnType().describe());
+        assertEquals(1, methodUsage.returnType().asReferenceType().typeParametersValues().size());
+        assertEquals("com.github.javaparser.ast.body.TypeDeclaration", methodUsage.returnType().asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveTypeUsageOfFirstMethodInGenericClass() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr callToGetTypes = Navigator.findMethodCall(method, "getTypes").get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar));
+        MethodUsage filterUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToGetTypes);
+
+        assertEquals("java.util.List<com.github.javaparser.ast.body.TypeDeclaration>", filterUsage.returnType().describe());
+        assertEquals(1, filterUsage.returnType().asReferenceType().typeParametersValues().size());
+        assertEquals("com.github.javaparser.ast.body.TypeDeclaration", filterUsage.returnType().asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveTypeUsageOfMethodInGenericClass() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr callToStream = Navigator.findMethodCall(method, "stream").get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar));
+        MethodUsage filterUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToStream);
+
+        assertEquals("java.util.stream.Stream<com.github.javaparser.ast.body.TypeDeclaration>", filterUsage.returnType().describe());
+    }
+
+    @Test
+    public void resolveTypeUsageOfCascadeMethodInGenericClass() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr callToFilter = Navigator.findMethodCall(method, "filter").get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar));
+        MethodUsage filterUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToFilter);
+
+        assertEquals("java.util.stream.Stream<com.github.javaparser.ast.body.TypeDeclaration>", filterUsage.returnType().describe());
+    }
+
+    @Test
+    public void resolveLambdaType() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr callToFilter = Navigator.findMethodCall(method, "filter").get();
+        Expression lambdaExpr = callToFilter.getArguments().get(0);
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar));
+        ResolvedType typeOfLambdaExpr = JavaParserFacade.get(typeSolver).getType(lambdaExpr);
+
+        assertEquals("java.util.function.Predicate<? super com.github.javaparser.ast.body.TypeDeclaration>", typeOfLambdaExpr.describe());
+    }
+
+    @Test
+    public void resolveReferenceToLambdaParam() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr callToGetName = Navigator.findMethodCall(method, "getName").get();
+        Expression referenceToT = callToGetName.getScope().get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar));
+        ResolvedType typeOfT = JavaParserFacade.get(typeSolver).getType(referenceToT);
+
+        assertEquals("? super com.github.javaparser.ast.body.TypeDeclaration", typeOfT.describe());
+    }
+
+    @Test
+    public void resolveReferenceToCallOnLambdaParam() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("Navigator");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Navigator");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "findType");
+        MethodCallExpr callToGetName = Navigator.findMethodCall(method, "getName").get();
+
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JarTypeSolver(pathToJar));
+        MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(callToGetName);
+
+        assertEquals("getName", methodUsage.getName());
+        assertEquals("com.github.javaparser.ast.body.TypeDeclaration", methodUsage.declaringType().getQualifiedName());
+    }
+
+    @Test
+    public void resolveReferenceToOverloadMethodWithNullParam() {
+        CompilationUnit cu = parseSample("OverloadedMethods");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "OverloadedMethods");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "m1");
+        MethodCallExpr call = Navigator.findMethodCall(method, "overloaded").get();
+
+        ReflectionTypeSolver typeSolver = new ReflectionTypeSolver();
+        MethodUsage ref = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call);
+
+        assertEquals("overloaded", ref.getName());
+        assertEquals(1, ref.getNoParams());
+        assertEquals("java.lang.String", ref.getParamTypes().get(0).describe());
+    }
+
+    @Test
+    public void resolveReferenceToOverloadMethodFindStricter() {
+        CompilationUnit cu = parseSample("OverloadedMethods");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "OverloadedMethods");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "m2");
+        MethodCallExpr call = Navigator.findMethodCall(method, "overloaded").get();
+
+        ReflectionTypeSolver typeSolver = new ReflectionTypeSolver();
+        MethodUsage ref = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call);
+
+        assertEquals("overloaded", ref.getName());
+        assertEquals(1, ref.getNoParams());
+        assertEquals("java.lang.String", ref.getParamTypes().get(0).describe());
+    }
+
+    @Test
+    public void resolveInheritedMethodFromInterface() {
+        CompilationUnit cu = parseSample("InterfaceInheritance");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Test");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "test");
+        MethodCallExpr call = Navigator.findMethodCall(method, "foobar").get();
+
+        File src = adaptPath(new File("src/test/resources"));
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(src));
+        ResolvedType type = JavaParserFacade.get(typeSolver).getType(call);
+
+        assertEquals("double", type.describe());
+    }
+
+    @Test
+    public void resolveReferenceToOverloadMethodFindOnlyCompatible() {
+        CompilationUnit cu = parseSample("OverloadedMethods");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "OverloadedMethods");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "m3");
+        MethodCallExpr call = Navigator.findMethodCall(method, "overloaded").get();
+
+        ReflectionTypeSolver typeSolver = new ReflectionTypeSolver();
+        MethodUsage ref = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call);
+
+        assertEquals("overloaded", ref.getName());
+        assertEquals(1, ref.getNoParams());
+        assertEquals("java.lang.Object", ref.getParamTypes().get(0).describe());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java
new file mode 100644
index 0000000..5fcead0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/DefaultPackageTest.java
@@ -0,0 +1,158 @@
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.*;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver;
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * See issue #16
+ */
+public class DefaultPackageTest {
+
+    private class MyClassDeclaration extends AbstractClassDeclaration {
+
+        private String qualifiedName;
+
+        private MyClassDeclaration(String qualifiedName) {
+            this.qualifiedName = qualifiedName;
+        }
+
+        @Override
+        public AccessSpecifier accessSpecifier() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
+            return new LinkedList<>();
+        }
+
+        @Override
+        public Set<ResolvedReferenceTypeDeclaration> internalTypes() {
+            return new HashSet<>();
+        }
+
+        @Override
+        public String getName() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<ResolvedReferenceType> getAncestors() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<ResolvedFieldDeclaration> getAllFields() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public Set<ResolvedMethodDeclaration> getDeclaredMethods() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isAssignableBy(ResolvedType type) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isAssignableBy(ResolvedReferenceTypeDeclaration other) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean hasDirectlyAnnotation(String qualifiedName) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ResolvedReferenceType getSuperClass() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<ResolvedReferenceType> getInterfaces() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public List<ResolvedConstructorDeclaration> getConstructors() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        protected ResolvedReferenceType object() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String getPackageName() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String getClassName() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String getQualifiedName() {
+            return qualifiedName;
+        }
+
+        @Override
+        public Optional<ResolvedReferenceTypeDeclaration> containerType() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Test
+    public void aClassInDefaultPackageCanBeAccessedFromTheDefaultPackage() {
+        String code = "class A extends B {}";
+        MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver();
+        memoryTypeSolver.addDeclaration("B", new MyClassDeclaration("B"));
+
+        ClassOrInterfaceType jpType = JavaParser.parse(code).getClassByName("A").get().getExtendedTypes(0);
+        ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(jpType);
+        assertEquals("B", resolvedType.asReferenceType().getQualifiedName());
+    }
+
+    @Test(expected = UnsolvedSymbolException.class)
+    public void aClassInDefaultPackageCanBeAccessedFromOutsideTheDefaultPackageImportingIt() {
+        String code = "package myPackage; import B; class A extends B {}";
+        MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver();
+        memoryTypeSolver.addDeclaration("B", new MyClassDeclaration("B"));
+
+        ClassOrInterfaceType jpType = JavaParser.parse(code).getClassByName("A").get().getExtendedTypes(0);
+        ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(jpType);
+        assertEquals("B", resolvedType.asReferenceType().getQualifiedName());
+    }
+
+    @Test(expected = UnsolvedSymbolException.class)
+    public void aClassInDefaultPackageCanBeAccessedFromOutsideTheDefaultPackageWithoutImportingIt() {
+        String code = "package myPackage; class A extends B {}";
+        MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver();
+        memoryTypeSolver.addDeclaration("B", new MyClassDeclaration("B"));
+
+        ResolvedType resolvedType = JavaParserFacade.get(memoryTypeSolver).convertToUsage(JavaParser.parse(code).getClassByName("A").get().getExtendedTypes(0));
+        assertEquals("B", resolvedType.asReferenceType().getQualifiedName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/EnumResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/EnumResolutionTest.java
new file mode 100644
index 0000000..edeaf80
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/EnumResolutionTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class EnumResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void switchOnEnum() {
+        CompilationUnit cu = parseSample("SwitchOnEnum");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SwitchOnEnum");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo");
+        SwitchStmt switchStmt = Navigator.findSwitch(method);
+        Expression expression = switchStmt.getEntries().get(0).getLabel().get();
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+        assertTrue(ref.isSolved());
+        assertEquals("SwitchOnEnum.MyEnum", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void enumAndStaticInitializer() {
+        CompilationUnit cu = parseSample("EnumAndStaticInitializer");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass");
+        MethodCallExpr call = Navigator.findMethodCall(clazz, "put").get();
+
+        ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(call);
+        assertEquals("MyClass.Primitive", ref.describe());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/FieldsResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/FieldsResolutionTest.java
new file mode 100644
index 0000000..fd95e73
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/FieldsResolutionTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class FieldsResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void accessClassFieldThroughThis() {
+        CompilationUnit cu = parseSample("AccessClassMemberThroughThis");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessClassMemberThroughThis");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "getLabel2");
+        ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0);
+        Expression expression = returnStmt.getExpression().get();
+
+        ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+        assertEquals("java.lang.String", ref.describe());
+    }
+
+    @Test
+    public void accessClassFieldThroughThisWithCompetingSymbolInParentContext() {
+        CompilationUnit cu = parseSample("AccessClassMemberThroughThis");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessClassMemberThroughThis");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "setLabel");
+        ExpressionStmt expressionStmt = (ExpressionStmt) method.getBody().get().getStatements().get(0);
+        AssignExpr assignExpr = (AssignExpr) expressionStmt.getExpression();
+        FieldAccessExpr fieldAccessExpr = (FieldAccessExpr) assignExpr.getTarget();
+
+        File src = adaptPath(new File("src/test/resources"));
+        CombinedTypeSolver typeSolver = new CombinedTypeSolver(new JavaParserTypeSolver(src), new ReflectionTypeSolver());
+        SymbolSolver symbolSolver = new SymbolSolver(typeSolver);
+        SymbolReference<? extends ResolvedValueDeclaration> ref = symbolSolver.solveSymbol(fieldAccessExpr.getName().getId(), fieldAccessExpr);
+
+        assertTrue(ref.isSolved());
+        assertTrue(ref.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void accessEnumFieldThroughThis() {
+        CompilationUnit cu = parseSample("AccessEnumMemberThroughThis");
+        com.github.javaparser.ast.body.EnumDeclaration enumDecl = Navigator.demandEnum(cu, "AccessEnumMemberThroughThis");
+        MethodDeclaration method = Navigator.demandMethod(enumDecl, "getLabel");
+        SimpleName expression = Navigator.findSimpleName(method, "label").get();
+
+        SymbolReference ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+        assertTrue(ref.isSolved());
+        assertEquals("label", ref.getCorrespondingDeclaration().getName());
+    }
+
+    @Test
+    public void accessEnumMethodThroughThis() {
+        CompilationUnit cu = parseSample("AccessEnumMemberThroughThis");
+        com.github.javaparser.ast.body.EnumDeclaration enumDecl = Navigator.demandEnum(cu, "AccessEnumMemberThroughThis");
+        MethodDeclaration method = Navigator.demandMethod(enumDecl, "getLabel2");
+        ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0);
+        Expression expression = returnStmt.getExpression().get();
+
+        ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+        assertEquals("java.lang.String", ref.describe());
+    }
+
+    @Test
+    public void accessFieldThroughSuper() {
+        CompilationUnit cu = parseSample("AccessThroughSuper");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessThroughSuper.SubClass");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "fieldTest");
+        ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0);
+        Expression expression = returnStmt.getExpression().get();
+
+        ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+        assertEquals("java.lang.String", ref.describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/GenericsResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/GenericsResolutionTest.java
new file mode 100644
index 0000000..bfc4bfd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/GenericsResolutionTest.java
@@ -0,0 +1,440 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+
+public class GenericsResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void resolveFieldWithGenericTypeToString() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics");
+        VariableDeclarator fieldS = Navigator.demandField(clazz, "s");
+
+        SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver());
+        Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("s", fieldS);
+
+        assertEquals(true, symbolReference.isPresent());
+        assertEquals("s", symbolReference.get().getName());
+
+        ResolvedType type = symbolReference.get().getType();
+        assertEquals(1, type.asReferenceType().typeParametersValues().size());
+        assertEquals("java.lang.String", type.asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveFieldWithGenericTypeToDeclaredClass() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics");
+        VariableDeclarator fieldS = Navigator.demandField(clazz, "g");
+
+        SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver());
+        Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("g", fieldS);
+
+        assertEquals(true, symbolReference.isPresent());
+        assertEquals("g", symbolReference.get().getName());
+
+        ResolvedType type = symbolReference.get().getType();
+        assertEquals(1, type.asReferenceType().typeParametersValues().size());
+        assertEquals("me.tomassetti.symbolsolver.javaparser.Generics", type.asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveFieldWithGenericTypeToInteger() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics");
+        VariableDeclarator fieldS = Navigator.demandField(clazz, "i");
+
+        SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver());
+        Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("i", fieldS);
+
+        assertEquals(true, symbolReference.isPresent());
+        assertEquals("i", symbolReference.get().getName());
+
+        ResolvedType type = symbolReference.get().getType();
+        assertEquals(1, type.asReferenceType().typeParametersValues().size());
+        assertEquals("java.lang.Integer", type.asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveFieldOfVariableType() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection");
+        VariableDeclarator field = Navigator.demandField(clazz, "a");
+
+        SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver());
+        Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("a", field);
+
+        assertEquals(true, symbolReference.isPresent());
+        assertEquals("a", symbolReference.get().getName());
+
+        ResolvedType type = symbolReference.get().getType();
+        assertEquals(true, type.isTypeVariable());
+        assertEquals("A", type.describe());
+    }
+
+    @Test
+    public void resolveFieldOfGenericReferringToVariableType() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection");
+        VariableDeclarator field = Navigator.demandField(clazz, "as");
+
+        SymbolSolver symbolSolver = new SymbolSolver(new ReflectionTypeSolver());
+        Optional<Value> symbolReference = symbolSolver.solveSymbolAsValue("as", field);
+
+        assertEquals(true, symbolReference.isPresent());
+        assertEquals("as", symbolReference.get().getName());
+
+        ResolvedType type = symbolReference.get().getType();
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("java.util.List<A>", type.describe());
+        assertEquals(1, type.asReferenceType().typeParametersValues().size());
+        ResolvedType typeParam = type.asReferenceType().typeParametersValues().get(0);
+        assertEquals(true, typeParam.isTypeVariable());
+        assertEquals("A", typeParam.describe());
+    }
+
+    @Test
+    public void resolveUsageOfGenericFieldSimpleCase() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo1");
+
+        ExpressionStmt stmt = (ExpressionStmt) method.getBody().get().getStatements().get(0);
+        Expression expression = stmt.getExpression();
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("java.lang.String", type.describe());
+    }
+
+    //PRIMA UN TEST CHE DICA CHE IL TIPO DEL CAMPO AS e' LIST<A> NON LIST<E>
+    @Test
+    public void resolveUsageOfGenericFieldIntermediateCase() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection");
+
+        VariableDeclarator field = Navigator.demandField(clazz, "as");
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(field);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("java.util.List<A>", type.describe());
+        assertEquals(1, type.asReferenceType().typeParametersValues().size());
+        assertEquals(true, type.asReferenceType().typeParametersValues().get(0).isTypeVariable());
+        assertEquals("A", type.asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveUsageOfGenericFieldAdvancedCase() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo2");
+
+        ExpressionStmt stmt = (ExpressionStmt) method.getBody().get().getStatements().get(0);
+        Expression expression = stmt.getExpression();
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("java.util.List<java.lang.String>", type.describe());
+        assertEquals(1, type.asReferenceType().typeParametersValues().size());
+        assertEquals(false, type.asReferenceType().typeParametersValues().get(0).isTypeVariable());
+        assertEquals("java.lang.String", type.asReferenceType().typeParametersValues().get(0).describe());
+    }
+
+    @Test
+    public void resolveUsageOfMethodOfGenericClass() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "GenericMethodCalls.Derived");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "caller");
+        MethodCallExpr expression = Navigator.findMethodCall(method, "callee").get();
+
+        MethodUsage methodUsage = JavaParserFacade.get(new ReflectionTypeSolver()).solveMethodAsUsage(expression);
+
+        assertEquals("callee", methodUsage.getName());
+    }
+
+    @Test
+    public void resolveElementOfList() {
+        CompilationUnit cu = parseSample("ElementOfList");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ElementOfList");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo");
+        VariableDeclarator variableDeclarator = Navigator.demandVariableDeclaration(method, "a").get();
+        Expression expression = variableDeclarator.getInitializer().get();
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("Comment", type.describe());
+    }
+
+    @Test
+    public void resolveElementOfListAdvancedExample() {
+        CompilationUnit cu = parseSample("ElementOfList");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ElementOfList");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "annotations");
+        VariableDeclarator variableDeclarator = Navigator.demandVariableDeclaration(method, "a").get();
+        Expression expression = variableDeclarator.getInitializer().get();
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("AnnotationExpr", type.describe());
+    }
+
+    @Test
+    public void genericsInheritance() {
+        CompilationUnit cu = parseSample("MethodTypeParams");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "VoidVisitorAdapter");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "visit");
+        MethodCallExpr call = Navigator.findMethodCall(method, "accept").get();
+        Expression thisRef = call.getArguments().get(0);
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        ResolvedType voidVisitorAdapterOfA = javaParserFacade.getType(thisRef);
+        List<ResolvedReferenceType> allAncestors = voidVisitorAdapterOfA.asReferenceType().getAllAncestors();
+        assertEquals(2, allAncestors.size());
+    }
+
+    @Test
+    public void methodTypeParams() {
+        CompilationUnit cu = parseSample("MethodTypeParams");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "VoidVisitorAdapter");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "visit");
+        MethodCallExpr call = Navigator.findMethodCall(method, "accept").get();
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(call);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("void", type.describe());
+    }
+
+    @Test
+    public void classCastScope() {
+        CompilationUnit cu = parseSample("ClassCast");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ClassCast");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "getNodesByType");
+        MethodCallExpr call = Navigator.findMethodCall(method, "cast").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        Expression scope = call.getScope().get();
+        ResolvedType type = JavaParserFacade.get(typeSolver).getType(scope);
+
+        //System.out.println(typeUsage);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("java.lang.Class<N>", type.describe());
+    }
+
+    @Test
+    public void classCast() {
+        CompilationUnit cu = parseSample("ClassCast");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ClassCast");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "getNodesByType");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(returnStmt.getExpression().get());
+
+        assertEquals(true, type.isTypeVariable());
+        assertEquals("N", type.describe());
+    }
+
+    @Test
+    public void typeParamOnReturnTypeStep1() {
+        CompilationUnit cu = parseSample("TypeParamOnReturnType");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals");
+        ThisExpr thisExpr = Navigator.findNodeOfGivenClass(method, ThisExpr.class);
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(thisExpr);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("TypeParamOnReturnType", type.describe());
+    }
+
+    @Test
+    public void typeParamOnReturnTypeStep2() {
+        CompilationUnit cu = parseSample("TypeParamOnReturnType");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals");
+        NameExpr n1 = Navigator.findNameExpression(method, "n1").get();
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(n1);
+
+        assertEquals(true, type.isTypeVariable());
+        assertEquals("T", type.describe());
+    }
+
+    @Test
+    public void typeParamOnReturnTypeStep3() {
+        CompilationUnit cu = parseSample("TypeParamOnReturnType");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals");
+        MethodCallExpr call = Navigator.findMethodCall(method, "accept").get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(call);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("java.lang.Boolean", type.describe());
+    }
+
+    @Test
+    public void typeParamOnReturnType() {
+        CompilationUnit cu = parseSample("TypeParamOnReturnType");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypeParamOnReturnType");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "nodeEquals");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(returnStmt.getExpression().get());
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("boolean", type.describe());
+    }
+
+    /*@Test
+    public void genericCollectionWithWildcardsAndExtensionsPrep() {
+        CompilationUnit cu = parseSample("GenericCollectionWithExtension");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "bar");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+
+        TypeSolver typeSolver = new JreTypeSolver();
+        MethodCallExpr call = (MethodCallExpr) returnStmt.getExpr();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        List<TypeUsage> params = new ArrayList<>();
+        if (call.getArgs() != null) {
+            for (Expression param : call.getArgs()) {
+                params.add(javaParserFacade.getType(param, false));
+            }
+        }
+        Context context = JavaParserFactory.getContext(call, typeSolver);
+
+        ReferenceTypeUsage typeOfScope = javaParserFacade.getType(call.getScope()).asReferenceType();
+        me.tomassetti.symbolsolver.model.declarations.TypeDeclaration typeDeclaration = typeOfScope.getTypeDeclaration();
+        List<TypeUsage> typeParametersValues = typeOfScope.typeParametersValues();
+
+        List<MethodUsage> methods = new ArrayList<>();
+        for (Method m : List.class.getMethods()) {
+            if (m.getName().equals("addAll") && !m.isBridge() && !m.isSynthetic()) {
+                me.tomassetti.symbolsolver.model.declarations.MethodDeclaration methodDeclaration = new ReflectionMethodDeclaration(m, typeSolver);
+                if (methods.size() == 0) {
+                    // ok, e' il primo
+                    ReferenceTypeUsage paramType = methodDeclaration.getParam(0).getType(typeSolver).asReferenceType();
+                    assertTrue(paramType.asReferenceType().typeParametersValues().get(0).isWildcard());
+                }
+                MethodUsage mu = new MethodUsage(methodDeclaration, typeSolver);
+                int i = 0;
+                for (TypeParameter tp : typeDeclaration.getTypeParameters()) {
+                    mu = mu.replaceTypeParameter(tp.getName(), typeParametersValues.get(i));
+                    i++;
+                }
+                methods.add(mu);
+            }
+
+        }
+
+        assertTrue(MethodResolutionLogic.isApplicable(methods.get(0), "addAll", params, typeSolver));
+        //Optional<MethodUsage> methodUsage = MethodResolutionLogic.findMostApplicableUsage(methods, "addAll", params, typeSolver);
+
+        //Optional<MethodUsage> methodUsage = typeDeclaration.solveMethodAsUsage("addAll", params, typeSolver, context, typeParametersValues);
+
+        //Optional<MethodUsage> methodUsage = context.solveMethodAsUsage("addAll", params, typeSolver);
+
+        //assertTrue(methodUsage.isPresent());
+
+    }*/
+
+    @Test
+    public void genericCollectionWithWildcardsAndExtensions() {
+        CompilationUnit cu = parseSample("GenericCollectionWithExtension");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "bar");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        Expression returnStmtExpr = returnStmt.getExpression().get();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        ResolvedType type = javaParserFacade.getType(returnStmtExpr);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("boolean", type.describe());
+    }
+
+    @Test
+    public void methodWithGenericParameterTypes() {
+        CompilationUnit cu = parseSample("GenericCollectionWithExtension");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "bar");
+        MethodCallExpr methodCall = Navigator.findMethodCall(method, "foo").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        MethodUsage methodUsage = javaParserFacade.solveMethodAsUsage(methodCall);
+
+        assertEquals("foo", methodUsage.getName());
+    }
+
+    @Test
+    public void genericCollectionWithWildcards() {
+        CompilationUnit cu = parseSample("GenericCollection");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Foo");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "bar");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        Expression returnStmtExpr = returnStmt.getExpression().get();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+
+        ResolvedType type = javaParserFacade.getType(returnStmtExpr);
+
+        assertEquals(false, type.isTypeVariable());
+        assertEquals("boolean", type.describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java
new file mode 100644
index 0000000..37fec26
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/JavaParserFacadeResolutionTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.*;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedUnionType;
+import com.github.javaparser.symbolsolver.JavaSymbolSolver;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class JavaParserFacadeResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void typeDeclarationSuperClassImplicitlyIncludeObject() {
+        CompilationUnit cu = parseSample("Generics");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Generics");
+        ResolvedTypeDeclaration typeDeclaration = JavaParserFacade.get(new ReflectionTypeSolver()).getTypeDeclaration(clazz);
+        ResolvedReferenceType superclass = typeDeclaration.asClass().getSuperClass();
+        assertEquals(Object.class.getCanonicalName(), superclass.getQualifiedName());
+    }
+
+    // See issue 42
+    @Test
+    public void solvingReferenceToUnsupportedOperationException() {
+        String code = "public class Bla {\n" +
+                "    public void main()\n" +
+                "    {\n" +
+                "        try\n" +
+                "        {\n" +
+                "            int i = 0;\n" +
+                "        }\n" +
+                "        catch (UnsupportedOperationException e)\n" +
+                "        {\n" +
+                "            String s;\n" +
+                "            e.getMessage();\n" +
+                "        }\n" +
+                "    }\n" +
+                "}";
+        MethodCallExpr methodCallExpr = Navigator.findNodeOfGivenClass(JavaParser.parse(code), MethodCallExpr.class);
+        MethodUsage methodUsage = JavaParserFacade.get(new ReflectionTypeSolver()).solveMethodAsUsage(methodCallExpr);
+        assertEquals("java.lang.Throwable.getMessage()", methodUsage.getQualifiedSignature());
+    }
+
+    // See issue 46
+    @Test
+    public void solvingReferenceToCatchClauseParam() {
+        String code = "public class Bla {\n" +
+                "    public void main()\n" +
+                "    {\n" +
+                "        try\n" +
+                "        {\n" +
+                "            int i = 0;\n" +
+                "        }\n" +
+                "        catch (UnsupportedOperationException e)\n" +
+                "        {\n" +
+                "            String s;\n" +
+                "            e.getMessage();\n" +
+                "        }\n" +
+                "    }\n" +
+                "}";
+        MethodCallExpr methodCallExpr = Navigator.findNodeOfGivenClass(JavaParser.parse(code), MethodCallExpr.class);
+        NameExpr nameE = (NameExpr)methodCallExpr.getScope().get();
+        SymbolReference<? extends ResolvedValueDeclaration> symbolReference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameE);
+        assertEquals(true, symbolReference.isSolved());
+        assertEquals(true, symbolReference.getCorrespondingDeclaration().isParameter());
+        assertEquals("e", symbolReference.getCorrespondingDeclaration().asParameter().getName());
+        assertEquals("java.lang.UnsupportedOperationException", symbolReference.getCorrespondingDeclaration().asParameter().getType().asReferenceType().getQualifiedName());
+    }
+
+    // See issue 47
+    @Test
+    public void solvingReferenceToAnAncestorInternalClass() {
+        String code = "public class Foo {\n" +
+                "    public class Base {\n" +
+                "        public class X {\n" +
+                "        }\n" +
+                "    }\n" +
+                "\n" +
+                "    public class Derived extends Base {\n" +
+                "        public X x = null;\n" +
+                "    }\n" +
+                "}";
+        FieldDeclaration fieldDeclaration = Navigator.findNodeOfGivenClass(JavaParser.parse(code), FieldDeclaration.class);
+        Type jpType = fieldDeclaration.getCommonType();
+        ResolvedType jssType = JavaParserFacade.get(new ReflectionTypeSolver()).convertToUsage(jpType);
+        assertEquals("Foo.Base.X", jssType.asReferenceType().getQualifiedName());
+    }
+
+    // See issue 119
+    @Test
+    public void solveTryWithResourceVariable() {
+        String code = "import java.util.Scanner; class A { void foo() { try (Scanner sc = new Scanner(System.in)) {\n" +
+                "    sc.nextLine();\n" +
+                "} } }";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodCallExpr methodCallExpr = Navigator.findMethodCall(cu, "nextLine").get();
+        Expression scope = methodCallExpr.getScope().get();
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(scope);
+        assertEquals(true, type.isReferenceType());
+        assertEquals("java.util.Scanner", type.asReferenceType().getQualifiedName());
+    }
+
+    private CompilationUnit parseWithTypeSolver(String code) {
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ParserConfiguration parserConfiguration = new ParserConfiguration();
+        parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
+        JavaParser javaParser = new JavaParser(parserConfiguration);
+        return javaParser.parse(ParseStart.COMPILATION_UNIT, new StringProvider(code)).getResult().get();
+    }
+
+    @Test
+    public void solveMultiCatchType() {
+        String code = "class A {\n" +
+                "        public void foo() {\n" +
+                "            try {\n" +
+                "                \n" +
+                "            } catch (IllegalStateException | IllegalArgumentException e) {\n" +
+                "                \n" +
+                "            }\n" +
+                "        }\n" +
+                "    }";
+        CompilationUnit cu = parseWithTypeSolver(code);
+        CatchClause catchClause = Navigator.findNodeOfGivenClass(cu, CatchClause.class);
+        Type jpType = catchClause.getParameter().getType();
+        ResolvedType jssType = jpType.resolve();
+        assertEquals(true, jssType instanceof ResolvedUnionType);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/LambdaResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/LambdaResolutionTest.java
new file mode 100644
index 0000000..3620c52
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/LambdaResolutionTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class LambdaResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void lambdaMapParameter() {
+        CompilationUnit cu = parseSample("Lambda");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) returnStmt.getExpression().get();
+        Expression expression = methodCallExpr.getArguments().get(0);
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(expression);
+        assertEquals("java.util.function.Function<? super java.lang.String, ? extends java.lang.String>", type.describe());
+    }
+
+    @Test
+    public void personsStream() {
+        CompilationUnit cu = parseSample("Lambda");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expression = returnStmt.getExpression().get();
+        expression = Navigator.findMethodCall(expression, "stream").get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(expression);
+        assertEquals("java.util.stream.Stream<java.lang.String>", type.describe());
+    }
+
+    @Test
+    public void lambdaMap() {
+        CompilationUnit cu = parseSample("Lambda");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration m1 = Navigator.demandMethod(clazz, "lambdaMap");
+        MethodDeclaration m2 = Navigator.demandMethod(clazz, "lambdaMap2");
+        ReturnStmt returnStmt1 = Navigator.findReturnStmt(m1);
+        ReturnStmt returnStmt2 = Navigator.findReturnStmt(m2);
+        Expression e1 = returnStmt1.getExpression().get();
+        Expression e2 = returnStmt2.getExpression().get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type1 = javaParserFacade.getType(e1);
+        ResolvedType type2 = javaParserFacade.getType(e2);
+        assertEquals("java.util.stream.Stream<java.lang.String>", type1.describe());
+        assertEquals("java.util.stream.Stream<java.util.stream.IntStream>", type2.describe());
+    }
+
+    @Test
+    public void lambdaReduce() {
+        CompilationUnit cu = parseSample("Lambda");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "reduce");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expr = returnStmt.getExpression().get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type1 = javaParserFacade.getType(expr);
+        assertEquals("java.util.Optional<java.lang.Integer>", type1.describe());
+    }
+
+    @Test
+    public void lambdaBifunc() {
+        CompilationUnit cu = parseSample("Lambda");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "bifunc");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expr = returnStmt.getExpression().get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type1 = javaParserFacade.getType(expr);
+        assertEquals("double", type1.describe());
+    }
+
+    @Test
+    public void lambdaCollectParam() {
+        CompilationUnit cu = parseSample("LambdaCollect");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) returnStmt.getExpression().get();
+        // Collectors.toList()
+        Expression expression = methodCallExpr.getArguments().get(0);
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(expression);
+        assertEquals("java.util.stream.Collector<T, ? extends java.lang.Object, java.util.List<T>>", type.describe());
+    }
+
+    @Test
+    public void lambdaCollect() {
+        CompilationUnit cu = parseSample("LambdaCollect");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expression = returnStmt.getExpression().get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(expression);
+        assertEquals("java.util.List<java.lang.String>", type.describe());
+    }
+
+    @Test
+    public void lambdaBlockExplicitReturn() {
+        CompilationUnit cu = parseSample("LambdaMulti");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaSingleReturn");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expression = returnStmt.getExpression().get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(expression);
+        assertEquals("java.lang.String", type.describe());
+    }
+
+    @Test
+    public void lambdaBlockMultiLineReturn() {
+        CompilationUnit cu = parseSample("LambdaMulti");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "multiLineReturn");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expression = returnStmt.getExpression().get();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(expression);
+        assertEquals("java.lang.String", type.describe());
+    }
+
+    @Test
+    public void typeOfVoidLambda() {
+        CompilationUnit cu = parseSample("LambdaVoid");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaEmpty");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expression = returnStmt.getExpression().get();
+        LambdaExpr lambdaExpr = Navigator.findNodeOfGivenClass(expression, LambdaExpr.class);
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(lambdaExpr);
+        assertEquals("void", type.describe());
+    }
+
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionLogicTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionLogicTest.java
new file mode 100644
index 0000000..b53607d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionLogicTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+
+public class MethodsResolutionLogicTest extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        File srcNewCode = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+        CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver();
+        combinedTypeSolverNewCode.add(new ReflectionTypeSolver());
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(srcNewCode));
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        typeSolver = combinedTypeSolverNewCode;
+    }
+
+    @Test
+    public void compatibilityShouldConsiderAlsoTypeVariablesNegative() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        ResolvedReferenceType stringType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(String.class, typeSolver);
+        ResolvedReferenceType rawClassType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolver);
+        assertEquals(true, rawClassType.isRawType());
+        ResolvedReferenceType classOfStringType = (ResolvedReferenceType) rawClassType.replaceTypeVariables(rawClassType.getTypeDeclaration().getTypeParameters().get(0), stringType);
+        MethodUsage mu = constructorDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().getSignature().equals("isThrows(java.lang.Class<? extends java.lang.Throwable>)")).findFirst().get();
+
+        assertEquals(false, MethodResolutionLogic.isApplicable(mu, "isThrows", ImmutableList.of(classOfStringType), typeSolver));
+    }
+
+    @Test
+    public void compatibilityShouldConsiderAlsoTypeVariablesRaw() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        ResolvedReferenceType rawClassType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolver);
+        MethodUsage mu = constructorDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().getSignature().equals("isThrows(java.lang.Class<? extends java.lang.Throwable>)")).findFirst().get();
+
+        assertEquals(true, MethodResolutionLogic.isApplicable(mu, "isThrows", ImmutableList.of(rawClassType), typeSolver));
+    }
+
+    @Test
+    public void compatibilityShouldConsiderAlsoTypeVariablesPositive() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolver.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        ResolvedReferenceType runtimeException = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(RuntimeException.class, typeSolver);
+        ResolvedReferenceType rawClassType = (ResolvedReferenceType) ReflectionFactory.typeUsageFor(Class.class, typeSolver);
+        ResolvedReferenceType classOfRuntimeType = (ResolvedReferenceType) rawClassType.replaceTypeVariables(rawClassType.getTypeDeclaration().getTypeParameters().get(0), runtimeException);
+        MethodUsage mu = constructorDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().getSignature().equals("isThrows(java.lang.Class<? extends java.lang.Throwable>)")).findFirst().get();
+
+        assertEquals(true, MethodResolutionLogic.isApplicable(mu, "isThrows", ImmutableList.of(classOfRuntimeType), typeSolver));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionTest.java
new file mode 100644
index 0000000..2e6dc94
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/MethodsResolutionTest.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class MethodsResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void solveMethodAccessThroughSuper() {
+        CompilationUnit cu = parseSample("AccessThroughSuper");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "AccessThroughSuper.SubClass");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "methodTest");
+        ReturnStmt returnStmt = (ReturnStmt) method.getBody().get().getStatements().get(0);
+        Expression expression = returnStmt.getExpression().get();
+
+        ResolvedType ref = JavaParserFacade.get(new ReflectionTypeSolver()).getType(expression);
+        assertEquals("java.lang.String", ref.describe());
+    }
+
+    @Test
+    public void solveMethodWithClassExpressionAsParameter() {
+        CompilationUnit cu = parseSample("ClassExpression");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "ClassExpression");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo");
+        MethodCallExpr expression = Navigator.findMethodCall(method, "noneOf").get();
+
+        MethodUsage methodUsage = JavaParserFacade.get(new ReflectionTypeSolver()).solveMethodAsUsage(expression);
+        assertEquals("noneOf", methodUsage.getName());
+    }
+
+    @Test
+    public void solveMethodInInterfaceParent() {
+        CompilationUnit cu = parseSample("MethodCalls");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "inheritedInterfaceMethod");
+        MethodCallExpr expression = Navigator.findMethodCall(method, "toString").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        MethodUsage call1 = javaParserFacade.solveMethodAsUsage(expression);
+        assertEquals("java.lang.Object.toString()", call1.getQualifiedSignature());
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToLong() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingLong");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToInt() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingInt");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("intParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("intParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("intParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToShort() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingShort");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("shortParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("shortParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToByte() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotions");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingByte");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("byteParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToLongWithExtraParam() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingLong");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("longParam", reference.getCorrespondingDeclaration().getName());
+        }
+
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToIntWithExtraParam() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingInt");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("intParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("intParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("intParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToShortWithExtraParam() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingShort");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("shortParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("shortParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+
+    }
+
+    @Test
+    public void solveMethodWithTypePromotionsToByteWithExtraParam() {
+        CompilationUnit cu = parseSample("Issue338");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "TypePromotionsWithExtraParam");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "callingByte");
+
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(0).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(true, reference.isSolved());
+            assertEquals("byteParam", reference.getCorrespondingDeclaration().getName());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(1).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(2).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+        {
+            MethodCallExpr expression = method.getBody().get().getStatements().get(3).asExpressionStmt().getExpression().asMethodCallExpr();
+            SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(expression);
+            assertEquals(false, reference.isSolved());
+        }
+
+    }
+
+    @Test
+    public void callOnThisInAnonymousClass() {
+        CompilationUnit cu = parseSample("ThisInAnonymousClass");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Bar");
+
+        MethodCallExpr fooCall = Navigator.findMethodCall(clazz, "foo").get();
+
+        SymbolReference<ResolvedMethodDeclaration> reference = JavaParserFacade.get(new ReflectionTypeSolver()).solve(fooCall);
+        assertEquals(true, reference.isSolved());
+    }
+
+    @Test
+    public void thisInAnonymousClass() {
+        CompilationUnit cu = parseSample("ThisInAnonymousClass");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Bar");
+
+        ThisExpr thisExpression = Navigator.findNodeOfGivenClass(clazz, ThisExpr.class);
+
+        ResolvedType type = JavaParserFacade.get(new ReflectionTypeSolver()).getType(thisExpression);
+        assertEquals(true, type.isReferenceType());
+        assertEquals(true, type.asReferenceType().getTypeDeclaration() instanceof JavaParserAnonymousClassDeclaration);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/QualifiedNameResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/QualifiedNameResolutionTest.java
new file mode 100644
index 0000000..906ac68
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/QualifiedNameResolutionTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class QualifiedNameResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void resolveLocalVariableInParentOfParent() {
+        CompilationUnit cu = parseSample("QualifiedNameTest");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "QualifiedNameTest");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo1");
+        NameExpr nameExpr = Navigator.findNameExpression(method, "s").get();
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr);
+        assertTrue(ref.isSolved());
+        assertEquals("java.util.Scanner", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/StatementContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/StatementContextResolutionTest.java
new file mode 100644
index 0000000..b96abf7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/StatementContextResolutionTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class StatementContextResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void resolveLocalVariableInParentOfParent() {
+        CompilationUnit cu = parseSample("LocalVariableInParent");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo1");
+        NameExpr nameExpr = Navigator.findNameExpression(method, "s").get();
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr);
+        assertTrue(ref.isSolved());
+        assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void resolveLocalVariableInParent() {
+        CompilationUnit cu = parseSample("LocalVariableInParent");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo3");
+        NameExpr nameExpr = Navigator.findNameExpression(method, "s").get();
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr);
+        assertTrue(ref.isSolved());
+        assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void resolveLocalVariableInSameParent() {
+        CompilationUnit cu = parseSample("LocalVariableInParent");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo2");
+        NameExpr nameExpr = Navigator.findNameExpression(method, "s").get();
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(new ReflectionTypeSolver()).solve(nameExpr);
+        assertTrue(ref.isSolved());
+        assertEquals("java.lang.String", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void resolveLocalAndSeveralAnnidatedLevels() {
+        CompilationUnit cu = parseSample("LocalVariableInParent");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo4");
+        MethodCallExpr call = Navigator.findMethodCall(method, "add").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(typeSolver).solve(call.getScope().get());
+        assertTrue(ref.isSolved());
+        assertEquals("java.util.List<Comment>", ref.getCorrespondingDeclaration().getType().describe());
+
+        MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call);
+        assertEquals("add", methodUsage.getName());
+    }
+
+    @Test
+    public void resolveMethodOnGenericClass() {
+        CompilationUnit cu = parseSample("LocalVariableInParent");
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration referencesToField = Navigator.demandClass(cu, "LocalVariableInParent");
+        MethodDeclaration method = Navigator.demandMethod(referencesToField, "foo5");
+        MethodCallExpr call = Navigator.findMethodCall(method, "add").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = JavaParserFacade.get(typeSolver).solve(call.getScope().get());
+        assertTrue(ref.isSolved());
+        assertEquals("java.util.List<Comment>", ref.getCorrespondingDeclaration().getType().describe());
+
+        MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(call);
+        assertEquals("add", methodUsage.getName());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverTest.java
new file mode 100644
index 0000000..eafe601
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class SymbolSolverTest extends AbstractTest {
+
+    private TypeSolver typeSolverNewCode;
+    private SymbolSolver symbolSolver;
+
+    @Before
+    public void setup() {
+
+        File srcNewCode = adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-core"));
+        CombinedTypeSolver combinedTypeSolverNewCode = new CombinedTypeSolver();
+        combinedTypeSolverNewCode.add(new ReflectionTypeSolver());
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(srcNewCode));
+        combinedTypeSolverNewCode.add(new JavaParserTypeSolver(adaptPath(new File("src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources"))));
+        typeSolverNewCode = combinedTypeSolverNewCode;
+
+        symbolSolver = new SymbolSolver(typeSolverNewCode);
+    }
+
+    @Test
+    public void testSolveSymbolUnexisting() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "unexisting");
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolveSymbolToDeclaredField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "name");
+        assertEquals(true, res.isSolved());
+        assertEquals(true, res.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void testSolveSymbolToInheritedPublicField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "NODE_BY_BEGIN_POSITION");
+        assertEquals(true, res.isSolved());
+        assertEquals(true, res.getCorrespondingDeclaration().isField());
+    }
+
+    @Test
+    public void testSolveSymbolToInheritedPrivateField() {
+        JavaParserClassDeclaration constructorDeclaration = (JavaParserClassDeclaration) typeSolverNewCode.solveType("com.github.javaparser.ast.body.ConstructorDeclaration");
+
+        SymbolReference<? extends ResolvedValueDeclaration> res = symbolSolver.solveSymbolInType(constructorDeclaration, "parentNode");
+        assertEquals(false, res.isSolved());
+    }
+
+    @Test
+    public void testSolvePackageLocalClass() {
+        assertTrue(typeSolverNewCode.solveType("com.github.javaparser.FooClass").isClass());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistClassTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistClassTest.java
new file mode 100644
index 0000000..cf103f1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistClassTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class SymbolSolverWithJavassistClassTest extends AbstractTest {
+    private TypeSolver typeSolver;
+    private SymbolSolver symbolSolver;
+    private JavassistClassDeclaration classDeclarationConcreteClass;
+    private JavassistClassDeclaration classDeclarationSubClassOwnJar;
+    private JavassistClassDeclaration classDeclarationInterfaceUserOwnJar;
+    private JavassistClassDeclaration classDeclarationSubClassIncludedJar;
+    private JavassistClassDeclaration classDeclarationInterfaceUserIncludedJar;
+    private JavassistClassDeclaration classDeclarationSubClassExcludedJar;
+    private JavassistClassDeclaration classDeclarationInterfaceUserExcludedJar;
+
+    @Before
+    public void setup() throws IOException {
+        final String pathToMainJar = adaptPath("src/test/resources/javassist_symbols/main_jar/main_jar.jar");
+        final String pathToIncludedJar = adaptPath("src/test/resources/javassist_symbols/included_jar/included_jar.jar");
+        typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToIncludedJar), new JarTypeSolver(pathToMainJar), new ReflectionTypeSolver());
+
+        symbolSolver = new SymbolSolver(typeSolver);
+
+        classDeclarationConcreteClass = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.ConcreteClass");
+        classDeclarationSubClassOwnJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubClassOwnJar");
+        classDeclarationSubClassIncludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubClassIncludedJar");
+        classDeclarationSubClassExcludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubClassExcludedJar");
+        classDeclarationInterfaceUserOwnJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.InterfaceUserOwnJar");
+        classDeclarationInterfaceUserIncludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.InterfaceUserIncludedJar");
+        classDeclarationInterfaceUserExcludedJar = (JavassistClassDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.InterfaceUserExcludedJar");
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanSolveFirstOwnField() {
+        assertCanSolveSymbol("STATIC_STRING", classDeclarationConcreteClass);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanSolveSecondOwnField() {
+        assertCanSolveSymbol("SECOND_STRING", classDeclarationConcreteClass);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCantResolveNonExistentField() {
+        SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(classDeclarationConcreteClass, "FIELD_THAT_DOES_NOT_EXIST");
+
+        assertFalse(solvedSymbol.isSolved());
+
+        try {
+            solvedSymbol.getCorrespondingDeclaration();
+        } catch (Exception e) {
+            assertTrue(e instanceof UnsupportedOperationException);
+            assertEquals("CorrespondingDeclaration not available for unsolved symbol.", e.getMessage());
+            return;
+        }
+        fail("Expected UnsupportedOperationException when requesting CorrespondingDeclaration on unsolved SymbolRefernce");
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInSuper() {
+        assertCanSolveSymbol("SUPER_FIELD", classDeclarationSubClassOwnJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInSuperIncludedJar() {
+        assertCanSolveSymbol("SUPER_FIELD", classDeclarationSubClassIncludedJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInSuperExcludedJar() {
+        try {
+            symbolSolver.solveSymbolInType(classDeclarationSubClassExcludedJar, "SUPER_FIELD");
+        } catch (Exception e) {
+            assertTrue(e instanceof UnsolvedSymbolException);
+            assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.SuperClassExcludedJar", e.getMessage());
+            return;
+        }
+        fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception.");
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInInterface() {
+        assertCanSolveSymbol("INTERFACE_FIELD", classDeclarationInterfaceUserOwnJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInInterfaceIncludedJar() {
+        assertCanSolveSymbol("INTERFACE_FIELD", classDeclarationInterfaceUserIncludedJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInInterfaceExcludedJar() {
+        try {
+            symbolSolver.solveSymbolInType(classDeclarationInterfaceUserExcludedJar, "INTERFACE_FIELD");
+        } catch (Exception e) {
+            assertTrue(e instanceof UnsolvedSymbolException);
+            assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar", e.getMessage());
+            return;
+        }
+        fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception.");
+    }
+
+    private void assertCanSolveSymbol(String symbolName, JavassistClassDeclaration classDeclaration) {
+        SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(classDeclaration, symbolName);
+
+        assertTrue(solvedSymbol.isSolved());
+        assertEquals(symbolName, solvedSymbol.getCorrespondingDeclaration().asField().getName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistEnumTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistEnumTest.java
new file mode 100644
index 0000000..120d2f1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistEnumTest.java
@@ -0,0 +1,106 @@
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+import static org.junit.Assert.fail;
+
+public class SymbolSolverWithJavassistEnumTest extends AbstractTest {
+    private TypeSolver typeSolver;
+    private SymbolSolver symbolSolver;
+    private JavassistEnumDeclaration enumDeclarationConcrete;
+    private JavassistEnumDeclaration enumDeclarationInterfaceUserOwnJar;
+    private JavassistEnumDeclaration enumDeclarationInterfaceUserIncludedJar;
+    private JavassistEnumDeclaration enumDeclarationInterfaceUserExcludedJar;
+
+    @Before
+    public void setup() throws IOException {
+        final String pathToMainJar = adaptPath("src/test/resources/javassist_symbols/main_jar/main_jar.jar");
+        final String pathToIncludedJar = adaptPath("src/test/resources/javassist_symbols/included_jar/included_jar.jar");
+        typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToIncludedJar), new JarTypeSolver(pathToMainJar), new ReflectionTypeSolver());
+
+        symbolSolver = new SymbolSolver(typeSolver);
+
+        enumDeclarationConcrete = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.ConcreteEnum");
+        enumDeclarationInterfaceUserOwnJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserOwnJar");
+        enumDeclarationInterfaceUserIncludedJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserIncludedJar");
+        enumDeclarationInterfaceUserExcludedJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserExcludedJar");
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFirstEnumValue() {
+        assertCanSolveSymbol("ENUM_VAL_ONE", enumDeclarationConcrete);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveSecondEnumValue() {
+        assertCanSolveSymbol("ENUM_VAL_TWO", enumDeclarationConcrete);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFirstNormalField() {
+        assertCanSolveSymbol("STATIC_STRING", enumDeclarationConcrete);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveSecondNormalField() {
+        assertCanSolveSymbol("SECOND_STRING", enumDeclarationConcrete);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCantResolveNonExistentField() {
+        SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(enumDeclarationConcrete, "FIELD_THAT_DOES_NOT_EXIST");
+
+        assertFalse(solvedSymbol.isSolved());
+
+        try {
+            solvedSymbol.getCorrespondingDeclaration();
+        } catch (Exception e) {
+            assertTrue(e instanceof UnsupportedOperationException);
+            assertEquals("CorrespondingDeclaration not available for unsolved symbol.", e.getMessage());
+            return;
+        }
+        fail("Expected UnsupportedOperationException when requesting CorrespondingDeclaration on unsolved SymbolRefernce");
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInInterface() {
+        assertCanSolveSymbol("INTERFACE_FIELD", enumDeclarationInterfaceUserOwnJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInInterfaceIncludedJar() {
+        assertCanSolveSymbol("INTERFACE_FIELD", enumDeclarationInterfaceUserIncludedJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInInterfaceExcludedJar() {
+        try {
+            symbolSolver.solveSymbolInType(enumDeclarationInterfaceUserExcludedJar, "INTERFACE_FIELD");
+        } catch (Exception e) {
+            assertTrue(e instanceof UnsolvedSymbolException);
+            assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar", e.getMessage());
+            return;
+        }
+        fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception.");
+    }
+
+    private void assertCanSolveSymbol(String symbolName, JavassistEnumDeclaration enumDeclaration) {
+        SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(enumDeclaration, symbolName);
+
+        assertTrue(solvedSymbol.isSolved());
+        assertEquals(symbolName, solvedSymbol.getCorrespondingDeclaration().asField().getName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistInterfaceTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistInterfaceTest.java
new file mode 100644
index 0000000..7745e81
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/SymbolSolverWithJavassistInterfaceTest.java
@@ -0,0 +1,96 @@
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.resolution.UnsolvedSymbolException;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.AbstractTest;
+import com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.*;
+
+public class SymbolSolverWithJavassistInterfaceTest extends AbstractTest {
+    private TypeSolver typeSolver;
+    private SymbolSolver symbolSolver;
+    private JavassistInterfaceDeclaration interfaceDeclarationStandalone;
+    private JavassistInterfaceDeclaration interfaceDeclarationSubInterfaceOwnJar;
+    private JavassistInterfaceDeclaration interfaceDeclarationSubInterfaceIncludedJar;
+    private JavassistInterfaceDeclaration interfaceDeclarationSubInterfaceExcludedJar;
+
+    @Before
+    public void setup() throws IOException {
+        final String pathToMainJar = adaptPath("src/test/resources/javassist_symbols/main_jar/main_jar.jar");
+        final String pathToIncludedJar = adaptPath("src/test/resources/javassist_symbols/included_jar/included_jar.jar");
+        typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToIncludedJar), new JarTypeSolver(pathToMainJar), new ReflectionTypeSolver());
+
+        symbolSolver = new SymbolSolver(typeSolver);
+
+        interfaceDeclarationStandalone = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.StandaloneInterface");
+        interfaceDeclarationSubInterfaceOwnJar = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubInterfaceOwnJar");
+        interfaceDeclarationSubInterfaceIncludedJar = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubInterfaceIncludedJar");
+        interfaceDeclarationSubInterfaceExcludedJar = (JavassistInterfaceDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.SubInterfaceExcludedJar");
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFirstNormalField() {
+        assertCanSolveSymbol("STATIC_STRING", interfaceDeclarationStandalone);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveSecondNormalField() {
+        assertCanSolveSymbol("SECOND_STRING", interfaceDeclarationStandalone);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCantResolveNonExistentField() {
+        SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(interfaceDeclarationStandalone, "FIELD_THAT_DOES_NOT_EXIST");
+
+        assertFalse(solvedSymbol.isSolved());
+
+        try {
+            solvedSymbol.getCorrespondingDeclaration();
+        } catch (Exception e) {
+            assertTrue(e instanceof UnsupportedOperationException);
+            assertEquals("CorrespondingDeclaration not available for unsolved symbol.", e.getMessage());
+            return;
+        }
+        fail("Expected UnsupportedOperationException when requesting CorrespondingDeclaration on unsolved SymbolRefernce");
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInExtendedInterfaceOwnJar() {
+        assertCanSolveSymbol("INTERFACE_FIELD", interfaceDeclarationSubInterfaceOwnJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeCanResolveFieldInExtendedInterfaceIncludedJar() {
+        assertCanSolveSymbol("INTERFACE_FIELD", interfaceDeclarationSubInterfaceIncludedJar);
+    }
+
+    @Test
+    public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInExtendedInterfaceExcludedJar() {
+        try {
+            symbolSolver.solveSymbolInType(interfaceDeclarationSubInterfaceExcludedJar, "INTERFACE_FIELD");
+        } catch (Exception e) {
+            assertTrue(e instanceof UnsolvedSymbolException);
+            assertEquals("Unsolved symbol : com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar", e.getMessage());
+            return;
+        }
+        fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception.");
+    }
+
+    private void assertCanSolveSymbol(String symbolName, JavassistInterfaceDeclaration interfaceDeclaration) {
+        SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(interfaceDeclaration, symbolName);
+
+        assertTrue(solvedSymbol.isSolved());
+        assertEquals(symbolName, solvedSymbol.getCorrespondingDeclaration().asField().getName());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/VariadicResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/VariadicResolutionTest.java
new file mode 100644
index 0000000..48c0ca7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/VariadicResolutionTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class VariadicResolutionTest extends AbstractResolutionTest {
+
+	@Test
+    public void issue7() {
+        CompilationUnit cu = parseSample("Generics_issue7");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "SomeCollection");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo3");
+
+        ReturnStmt stmt = (ReturnStmt) method.getBody().get().getStatements().get(0);
+        Expression expression = stmt.getExpression().get();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(new ReflectionTypeSolver());
+        ResolvedType type = javaParserFacade.getType(expression);
+        assertEquals(true, type.isReferenceType());
+        assertEquals(List.class.getCanonicalName(), type.asReferenceType().getQualifiedName());
+        assertEquals("java.util.List<java.lang.Long>", type.describe());
+    }
+	
+	@Test
+    public void methodCallWithReferenceTypeAsVaridicArgumentIsSolved() {
+        CompilationUnit cu = parseSample("MethodCalls");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "variadicMethod");
+        MethodCallExpr callExpr = Navigator.findMethodCall(method, "variadicMethod").get();
+        
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        MethodUsage callee = javaParserFacade.solveMethodAsUsage(callExpr);
+        assertEquals("variadicMethod", callee.getName());
+    }
+
+    @Test
+    public void resolveVariadicMethodWithGenericArgument() {
+        CompilationUnit cu = parseSample("MethodCalls");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "genericMethodTest");
+        MethodCallExpr callExpr = Navigator.findMethodCall(method, "variadicWithGenericArg").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        MethodUsage callee = javaParserFacade.solveMethodAsUsage(callExpr);
+        assertEquals("variadicWithGenericArg", callee.getName());
+    }
+
+    @Test
+    public void selectMostSpecificVariadic() {
+        CompilationUnit cu = parseSample("MethodCalls");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls");
+
+        MethodDeclaration method = Navigator.demandMethod(clazz, "variadicTest");
+        List<MethodCallExpr> calls = method.findAll(MethodCallExpr.class);
+
+        File src = adaptPath(new File("src/test/resources"));
+        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver(), new JavaParserTypeSolver(src));
+
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        MethodUsage call1 = javaParserFacade.solveMethodAsUsage(calls.get(0));
+        MethodUsage call2 = javaParserFacade.solveMethodAsUsage(calls.get(1));
+        assertEquals("int", call1.returnType().describe());
+        assertEquals("void", call2.returnType().describe());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/VarTypeTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/VarTypeTest.java
new file mode 100644
index 0000000..d8d0eaf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/VarTypeTest.java
@@ -0,0 +1,62 @@
+package com.github.javaparser.symbolsolver.resolution.javaparser;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseStart;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.type.VarType;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.JavaSymbolSolver;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_10;
+import static com.github.javaparser.Providers.provider;
+import static org.junit.Assert.assertEquals;
+
+public class VarTypeTest {
+    private final TypeSolver typeSolver = new ReflectionTypeSolver();
+    private final JavaParser javaParser = new JavaParser(new ParserConfiguration()
+            .setLanguageLevel(JAVA_10)
+            .setSymbolResolver(new JavaSymbolSolver(typeSolver)));
+
+    @Test
+    public void resolveAPrimitive() {
+        CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(){var abc = 1;}}")).getResult().get();
+        VarType varType = ast.findFirst(VarType.class).get();
+
+        ResolvedType resolvedType = varType.resolve();
+
+        assertEquals(ResolvedPrimitiveType.INT, resolvedType);
+    }
+
+    @Test
+    public void resolveAReferenceType() {
+        CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(){var abc = \"\";}}")).getResult().get();
+        VarType varType = ast.findFirst(VarType.class).get();
+
+        ResolvedType resolvedType = varType.resolve();
+
+        assertEquals(new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver), resolvedType);
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void failResolveNoInitializer() {
+        CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(){var abc;}}")).getResult().get();
+        VarType varType = ast.findFirst(VarType.class).get();
+
+        varType.resolve();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void failResolveWrongLocation() {
+        CompilationUnit ast = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{void x(var x){};}")).getResult().get();
+        VarType varType = ast.findFirst(VarType.class).get();
+
+        varType.resolve();
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContextResolutionTest.java
new file mode 100644
index 0000000..a559418
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/ClassOrInterfaceDeclarationContextResolutionTest.java
@@ -0,0 +1,490 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.contexts;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.resolution.MethodAmbiguityException;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.NullType;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class ClassOrInterfaceDeclarationContextResolutionTest extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+    }
+
+    @Test
+    public void getParentForTopClass() {
+        CompilationUnit cu = parseSample("ClassWithTypeVariables");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        assertFalse(null == context.getParent());
+        assertEquals(new CompilationUnitContext(cu, typeSolver), context.getParent());
+    }
+
+    @Test
+    public void solveExistingGenericType() {
+        CompilationUnit cu = parseSample("ClassWithTypeVariables");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<ResolvedType> a = context.solveGenericType("A", new MemoryTypeSolver());
+        Optional<ResolvedType> b = context.solveGenericType("B", new MemoryTypeSolver());
+        Optional<ResolvedType> c = context.solveGenericType("C", new MemoryTypeSolver());
+
+        assertEquals(true, a.isPresent());
+        assertEquals("A", a.get().describe());
+        assertEquals(true, a.get().isTypeVariable());
+        assertEquals(true, b.isPresent());
+        assertEquals("B", b.get().describe());
+        assertEquals(true, b.get().isTypeVariable());
+        assertEquals(true, c.isPresent());
+        assertEquals("C", c.get().describe());
+        assertEquals(true, c.get().isTypeVariable());
+    }
+
+    @Test
+    public void solveUnexistingGenericType() {
+        CompilationUnit cu = parseSample("ClassWithTypeVariables");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<ResolvedType> d = context.solveGenericType("D", new MemoryTypeSolver());
+
+        assertEquals(false, d.isPresent());
+    }
+
+    @Test
+    public void solveSymbolReferringToDeclaredInstanceField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("i", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("int", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolReferringToDeclaredStaticField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("j", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("long", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolReferringToInheritedInstanceField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("k", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("boolean", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolReferringToInterfaceInheritedInstanceField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("o", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("int", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolReferringToInheritedStaticField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("m", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("char", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolReferringToUnknownElement() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("zzz", new MemoryTypeSolver());
+        assertEquals(false, ref.isSolved());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToDeclaredInstanceField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("i", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("int", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToDeclaredStaticField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("j", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("long", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToInheritedInstanceField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("k", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("boolean", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToInterfaceInheritedInstanceField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        ClassOrInterfaceDeclarationContext context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("o", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("int", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToInheritedStaticField() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("m", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("char", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToUnknownElement() {
+        CompilationUnit cu = parseSample("ClassWithSymbols");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("zzz", new MemoryTypeSolver());
+        assertEquals(false, ref.isPresent());
+    }
+
+    @Test
+    public void solveTypeRefToItself() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("A", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToUnexisting() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Foo", new MemoryTypeSolver());
+        assertEquals(false, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToObject() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Object", new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToJavaLangObject() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("java.lang.Object", new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToInternalClass() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("B", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToInternalEnum() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("E", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToInternalOfInternalClass() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("C", new MemoryTypeSolver());
+        assertEquals(false, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToAnotherClassInFile() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Super", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToQualifiedInternalClass() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("A.B", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToQualifiedInternalOfInternalClass() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("B.C", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveTypeRefToMoreQualifiedInternalOfInternalClass() {
+        CompilationUnit cu = parseSample("ClassWithTypes");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("A.B.C", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+
+    @Test
+    public void solveMethodSimpleCase() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo0", ImmutableList.of(), false, new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName());
+        assertEquals(0, ref.getCorrespondingDeclaration().getNumberOfParams());
+    }
+
+    @Test
+    public void solveMethodOverrideCase() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo1", ImmutableList.of(), false, new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName());
+        assertEquals(0, ref.getCorrespondingDeclaration().getNumberOfParams());
+    }
+
+    @Test
+    public void solveMethodInheritedCase() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo2", ImmutableList.of(), false, new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("Super", ref.getCorrespondingDeclaration().declaringType().getName());
+        assertEquals(0, ref.getCorrespondingDeclaration().getNumberOfParams());
+    }
+
+    @Test
+    public void solveMethodWithPrimitiveParameters() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        ResolvedType intType = ResolvedPrimitiveType.INT;
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo3", ImmutableList.of(intType), false, new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName());
+        assertEquals(1, ref.getCorrespondingDeclaration().getNumberOfParams());
+    }
+
+    @Test
+    public void solveMethodWithMoreSpecializedParameter() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        ResolvedType stringType = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo4", ImmutableList.of(stringType), false, new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("A", ref.getCorrespondingDeclaration().declaringType().getName());
+        assertEquals(1, ref.getCorrespondingDeclaration().getNumberOfParams());
+    }
+
+    @Test(expected = MethodAmbiguityException.class)
+    public void solveMethodWithAmbiguosCall() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("foo5", ImmutableList.of(NullType.INSTANCE), false, new ReflectionTypeSolver());
+    }
+
+    @Test
+    public void solveMethodAsUsageSimpleCase() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage("foo0", ImmutableList.of(), new ReflectionTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("A", ref.get().declaringType().getName());
+        assertEquals(0, ref.get().getNoParams());
+    }
+
+    @Test
+    public void solveMethodAsUsageOverrideCase() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage("foo1", ImmutableList.of(), new ReflectionTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("A", ref.get().declaringType().getName());
+        assertEquals(0, ref.get().getNoParams());
+    }
+
+    @Test
+    public void solveMethodAsUsageInheritedCase() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage("foo2", ImmutableList.of(), new ReflectionTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("Super", ref.get().declaringType().getName());
+        assertEquals(0, ref.get().getNoParams());
+    }
+
+    @Test
+    public void solveMethodAsUsageWithPrimitiveParameters() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        ResolvedType intType = ResolvedPrimitiveType.INT;
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage("foo3", ImmutableList.of(intType), new ReflectionTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("A", ref.get().declaringType().getName());
+        assertEquals(1, ref.get().getNoParams());
+    }
+
+    @Test
+    public void solveMethodAsUsageWithMoreSpecializedParameter() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        ResolvedType stringType = new ReferenceTypeImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage("foo4", ImmutableList.of(stringType), new ReflectionTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("A", ref.get().declaringType().getName());
+        assertEquals(1, ref.get().getNoParams());
+    }
+
+    @Test(expected = MethodAmbiguityException.class)
+    public void solveMethodAsUsageWithAmbiguosCall() {
+        CompilationUnit cu = parseSample("ClassWithMethods");
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = Navigator.demandClass(cu, "A");
+        Context context = new ClassOrInterfaceDeclarationContext(classOrInterfaceDeclaration, typeSolver);
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage("foo5", ImmutableList.of(NullType.INSTANCE), new ReflectionTypeSolver());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/CompilationUnitContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/CompilationUnitContextResolutionTest.java
new file mode 100644
index 0000000..c079e59
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/CompilationUnitContextResolutionTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.contexts;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.model.typesystem.NullType;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import com.google.common.collect.ImmutableList;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class CompilationUnitContextResolutionTest extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+    }
+
+    @Test
+    public void getParent() {
+        CompilationUnit cu = parseSample("ClassWithTypeVariables");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        assertTrue(null == context.getParent());
+    }
+
+    @Test
+    public void solveExistingGenericType() {
+        CompilationUnit cu = parseSample("ClassWithTypeVariables");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        Optional<ResolvedType> a = context.solveGenericType("A", new MemoryTypeSolver());
+        Optional<ResolvedType> b = context.solveGenericType("B", new MemoryTypeSolver());
+        Optional<ResolvedType> c = context.solveGenericType("C", new MemoryTypeSolver());
+
+        assertEquals(false, a.isPresent());
+        assertEquals(false, b.isPresent());
+        assertEquals(false, c.isPresent());
+    }
+
+    @Test
+    public void solveUnexistingGenericType() {
+        CompilationUnit cu = parseSample("ClassWithTypeVariables");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        Optional<ResolvedType> d = context.solveGenericType("D", new MemoryTypeSolver());
+
+        assertEquals(false, d.isPresent());
+    }
+
+    @Test
+    public void solveSymbolReferringToStaticallyImportedValue() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitSymbols");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        CombinedTypeSolver typeSolver = new CombinedTypeSolver();
+        typeSolver.add(new ReflectionTypeSolver());
+        typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("out", typeSolver);
+        assertEquals(true, ref.isSolved());
+        assertEquals("java.io.PrintStream", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void solveSymbolReferringToStaticallyImportedUsingAsteriskValue() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitSymbols");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        CombinedTypeSolver typeSolver = new CombinedTypeSolver();
+        typeSolver.add(new ReflectionTypeSolver());
+        typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("err", typeSolver);
+        assertEquals(true, ref.isSolved());
+        assertEquals("java.io.PrintStream", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void solveSymbolReferringToStaticField() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitSymbols");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("java.lang.System.out", new ReflectionTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("java.io.PrintStream", ref.getCorrespondingDeclaration().getType().asReferenceType().getQualifiedName());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToStaticallyImportedValue() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitSymbols");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        CombinedTypeSolver typeSolver = new CombinedTypeSolver();
+        typeSolver.add(new ReflectionTypeSolver());
+        typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        Optional<Value> ref = context.solveSymbolAsValue("out", typeSolver);
+        assertEquals(true, ref.isPresent());
+        assertEquals("java.io.PrintStream", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToStaticallyImportedUsingAsteriskValue() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitSymbols");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        CombinedTypeSolver typeSolver = new CombinedTypeSolver();
+        typeSolver.add(new ReflectionTypeSolver());
+        typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        Optional<Value> ref = context.solveSymbolAsValue("err", typeSolver);
+        assertEquals(true, ref.isPresent());
+        assertEquals("java.io.PrintStream", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToStaticField() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitSymbols");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("java.lang.System.out", new ReflectionTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("java.io.PrintStream", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveTypeInSamePackage() {
+        CompilationUnit cu = parseSample("CompilationUnitWithImports");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        ResolvedReferenceTypeDeclaration otherClass = mock(ResolvedReferenceTypeDeclaration.class);
+        when(otherClass.getQualifiedName()).thenReturn("com.foo.OtherClassInSamePackage");
+        MemoryTypeSolver memoryTypeSolver = new MemoryTypeSolver();
+        memoryTypeSolver.addDeclaration("com.foo.OtherClassInSamePackage", otherClass);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("OtherClassInSamePackage", memoryTypeSolver);
+        assertEquals(true, ref.isSolved());
+        assertEquals("com.foo.OtherClassInSamePackage", ref.getCorrespondingDeclaration().getQualifiedName());
+    }
+
+    @Test
+    public void solveTypeImported() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitWithImports");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("Assert", new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        assertEquals(true, ref.isSolved());
+        assertEquals("org.junit.Assert", ref.getCorrespondingDeclaration().getQualifiedName());
+    }
+
+    @Test
+    public void solveTypeNotImported() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitWithImports");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("org.junit.Assume", new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        assertEquals(true, ref.isSolved());
+        assertEquals("org.junit.Assume", ref.getCorrespondingDeclaration().getQualifiedName());
+    }
+
+    @Test
+    public void solveMethodStaticallyImportedWithAsterisk() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitWithImports");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        CombinedTypeSolver typeSolver = new CombinedTypeSolver();
+        typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        typeSolver.add(new ReflectionTypeSolver());
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("assertFalse", ImmutableList.of(ResolvedPrimitiveType.BOOLEAN), false, typeSolver);
+        assertEquals(true, ref.isSolved());
+        assertEquals("assertFalse", ref.getCorrespondingDeclaration().getName());
+        assertEquals(1, ref.getCorrespondingDeclaration().getNumberOfParams());
+        assertEquals("boolean", ref.getCorrespondingDeclaration().getParam(0).getType().describe());
+        assertEquals(true, ref.getCorrespondingDeclaration().getParam(0).getType().isPrimitive());
+    }
+
+    @Test
+    public void solveMethodStaticallyImportedWithoutAsterisk() throws ParseException, IOException {
+        CompilationUnit cu = parseSample("CompilationUnitSymbols");
+        Context context = new CompilationUnitContext(cu, typeSolver);
+
+        CombinedTypeSolver typeSolver = new CombinedTypeSolver();
+        typeSolver.add(new JarTypeSolver(adaptPath("src/test/resources/junit-4.8.1.jar")));
+        typeSolver.add(new ReflectionTypeSolver());
+
+        SymbolReference<ResolvedMethodDeclaration> ref = context.solveMethod("assertEquals", ImmutableList.of(NullType.INSTANCE, NullType.INSTANCE), false, typeSolver);
+        assertEquals(true, ref.isSolved());
+        assertEquals("assertEquals", ref.getCorrespondingDeclaration().getName());
+        assertEquals(2, ref.getCorrespondingDeclaration().getNumberOfParams());
+        assertEquals("java.lang.Object", ref.getCorrespondingDeclaration().getParam(0).getType().asReferenceType().getQualifiedName());
+        assertEquals("java.lang.Object", ref.getCorrespondingDeclaration().getParam(1).getType().asReferenceType().getQualifiedName());
+
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContextResolutionTest.java
new file mode 100644
index 0000000..93af30e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/EnumDeclarationContextResolutionTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.contexts;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.EnumDeclarationContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Federico Tomassetti
+ */
+public class EnumDeclarationContextResolutionTest extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+    }
+
+    @Test
+    public void solveSymbolReferringToDeclaredInstanceField() {
+        CompilationUnit cu = parseSample("AnEnum");
+        com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum");
+        Context context = new EnumDeclarationContext(enumDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("i", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("int", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolReferringToDeclaredStaticField() {
+        CompilationUnit cu = parseSample("AnEnum");
+        com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum");
+        Context context = new EnumDeclarationContext(enumDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("j", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("long", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolReferringToValue() {
+        CompilationUnit cu = parseSample("AnEnum");
+        com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum");
+        Context context = new EnumDeclarationContext(enumDeclaration, typeSolver);
+
+        SymbolReference<? extends ResolvedValueDeclaration> ref = context.solveSymbol("E1", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+        assertEquals("MyEnum", ref.getCorrespondingDeclaration().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToDeclaredInstanceField() {
+        CompilationUnit cu = parseSample("AnEnum");
+        com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum");
+        Context context = new EnumDeclarationContext(enumDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("i", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("int", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToDeclaredStaticField() {
+        CompilationUnit cu = parseSample("AnEnum");
+        com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum");
+        Context context = new EnumDeclarationContext(enumDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("j", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("long", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveSymbolAsValueReferringToValue() {
+        CompilationUnit cu = parseSample("AnEnum");
+        com.github.javaparser.ast.body.EnumDeclaration enumDeclaration = Navigator.demandEnum(cu, "MyEnum");
+        Context context = new EnumDeclarationContext(enumDeclaration, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("E1", new MemoryTypeSolver());
+        assertEquals(true, ref.isPresent());
+        assertEquals("MyEnum", ref.get().getType().describe());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/FieldAccessContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/FieldAccessContextResolutionTest.java
new file mode 100644
index 0000000..b13737e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/FieldAccessContextResolutionTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.contexts;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Malte Langkabel
+ */
+public class FieldAccessContextResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void solveMethodCallInFieldAccessContext() {
+        CompilationUnit cu = parseSample("MethodCalls");
+
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "bar2");
+        MethodCallExpr methodCallExpr = Navigator.findMethodCall(method, "getSelf").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        MethodUsage methodUsage = JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr);
+
+        assertEquals(methodUsage.getName(), "getSelf");
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/LambdaExprContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/LambdaExprContextResolutionTest.java
new file mode 100644
index 0000000..63e513c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/LambdaExprContextResolutionTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.contexts;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.LambdaExprContext;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.resolution.Value;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Malte Langkabel
+ */
+public class LambdaExprContextResolutionTest extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+    }
+
+    @Test
+    public void solveParameterOfLambdaInMethodCallExpr() {
+        CompilationUnit cu = parseSample("Lambda");
+
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "lambdaMap");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) returnStmt.getExpression().get();
+        LambdaExpr lambdaExpr = (LambdaExpr) methodCallExpr.getArguments().get(0);
+
+        Context context = new LambdaExprContext(lambdaExpr, typeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("p", typeSolver);
+        assertTrue(ref.isPresent());
+        assertEquals("? super java.lang.String", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveParameterOfLambdaInFieldDecl() {
+        CompilationUnit cu = parseSample("Lambda");
+
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        VariableDeclarator field = Navigator.demandField(clazz, "functional");
+        LambdaExpr lambdaExpr = (LambdaExpr) field.getInitializer().get();
+
+        File src = new File("src/test/resources");
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(adaptPath(src)));
+
+        Context context = new LambdaExprContext(lambdaExpr, combinedTypeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("p", typeSolver);
+        assertTrue(ref.isPresent());
+        assertEquals("java.lang.String", ref.get().getType().describe());
+    }
+
+    @Test
+    public void solveParameterOfLambdaInVarDecl() {
+        CompilationUnit cu = parseSample("Lambda");
+
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "Agenda");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "testFunctionalVar");
+        VariableDeclarator varDecl = Navigator.demandVariableDeclaration(method, "a").get();
+        LambdaExpr lambdaExpr = (LambdaExpr) varDecl.getInitializer().get();
+
+        File src = adaptPath(new File("src/test/resources"));
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+
+        Context context = new LambdaExprContext(lambdaExpr, combinedTypeSolver);
+
+        Optional<Value> ref = context.solveSymbolAsValue("p", typeSolver);
+        assertTrue(ref.isPresent());
+        assertEquals("java.lang.String", ref.get().getType().describe());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodCallExprContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodCallExprContextResolutionTest.java
new file mode 100644
index 0000000..7fdaf73
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodCallExprContextResolutionTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.contexts;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.MethodUsage;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Malte Langkabel
+ */
+public class MethodCallExprContextResolutionTest extends AbstractResolutionTest {
+    private MethodCallExpr getMethodCallExpr(String methodName, String callingMethodName) {
+        CompilationUnit cu = parseSample("MethodCalls");
+
+        com.github.javaparser.ast.body.ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MethodCalls");
+        MethodDeclaration method = Navigator.demandMethod(clazz, methodName);
+        return Navigator.findMethodCall(method, callingMethodName).get();
+    }
+
+    private CombinedTypeSolver createTypeSolver() {
+        File src = adaptPath(new File("src/test/resources"));
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver());
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+        return combinedTypeSolver;
+    }
+
+    @Test
+    public void solveNestedMethodCallExprContextWithoutScope() {
+        MethodCallExpr methodCallExpr = getMethodCallExpr("bar1", "foo");
+        CombinedTypeSolver typeSolver = createTypeSolver();
+
+        Context context = new MethodCallExprContext(methodCallExpr, typeSolver);
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage("foo", Collections.emptyList(), typeSolver);
+        assertTrue(ref.isPresent());
+        assertEquals("MethodCalls", ref.get().declaringType().getQualifiedName());
+    }
+
+    @Test
+    public void solveGenericMethodCallMustUseProvidedTypeArgs() {
+        assertCanSolveGenericMethodCallMustUseProvidedTypeArgs("genericMethod0");
+    }
+
+    @Test
+    public void solveStaticGenericMethodCallMustUseProvidedTypeArgs() {
+        assertCanSolveGenericMethodCallMustUseProvidedTypeArgs("staticGenericMethod0");
+    }
+
+    private void assertCanSolveGenericMethodCallMustUseProvidedTypeArgs(String callMethodName) {
+        MethodCallExpr methodCallExpr = getMethodCallExpr("genericMethodTest", callMethodName);
+        CombinedTypeSolver typeSolver = createTypeSolver();
+
+        MethodCallExprContext context = new MethodCallExprContext(methodCallExpr, typeSolver);
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage(callMethodName, Collections.emptyList(), typeSolver);
+        assertTrue(ref.isPresent());
+        assertEquals("MethodCalls", ref.get().declaringType().getQualifiedName());
+        assertEquals(Collections.singletonList("java.lang.Integer"), ref.get().typeParametersMap().getTypes().stream().map(ty -> ty.asReferenceType().describe()).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void solveGenericMethodCallCanInferFromArguments() {
+        assertCanSolveGenericMethodCallCanInferFromArguments("genericMethod1");
+    }
+
+    @Test
+    public void solveStaticGenericMethodCallCanInferFromArguments() {
+        assertCanSolveGenericMethodCallCanInferFromArguments("staticGenericMethod1");
+    }
+
+    private void assertCanSolveGenericMethodCallCanInferFromArguments(String callMethodName) {
+        MethodCallExpr methodCallExpr = getMethodCallExpr("genericMethodTest", callMethodName);
+        CombinedTypeSolver typeSolver = createTypeSolver();
+
+        MethodCallExprContext context = new MethodCallExprContext(methodCallExpr, typeSolver);
+
+        ResolvedReferenceTypeDeclaration stringType = typeSolver.solveType("java.lang.String");
+
+        List<ResolvedType> argumentsTypes = new ArrayList<>();
+        argumentsTypes.add(new ReferenceTypeImpl(stringType, typeSolver));
+
+        Optional<MethodUsage> ref = context.solveMethodAsUsage(callMethodName, argumentsTypes, typeSolver);
+        assertTrue(ref.isPresent());
+        assertEquals("MethodCalls", ref.get().declaringType().getQualifiedName());
+        assertEquals(Collections.singletonList("java.lang.String"), ref.get().typeParametersMap().getTypes().stream().map(ty -> ty.asReferenceType().describe()).collect(Collectors.toList()));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodContextResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodContextResolutionTest.java
new file mode 100644
index 0000000..17d9780
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/contexts/MethodContextResolutionTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.contexts;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeDeclaration;
+import com.github.javaparser.symbolsolver.core.resolution.Context;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodContext;
+import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Malte Langkabel
+ */
+public class MethodContextResolutionTest extends AbstractResolutionTest {
+
+    private TypeSolver typeSolver;
+
+    @Before
+    public void setup() {
+        typeSolver = new ReflectionTypeSolver();
+    }
+
+    @Test
+    public void solveTypeRefToLocalClass() {
+        CompilationUnit cu = parseSample("MethodWithTypes");
+        ClassOrInterfaceDeclaration cd = Navigator.demandClass(cu, "Main");
+        MethodDeclaration md = Navigator.demandMethod(cd, "methodWithLocalTypes");
+        Context context = new MethodContext(md, typeSolver);
+
+        SymbolReference<ResolvedTypeDeclaration> ref = context.solveType("LocalClass", new MemoryTypeSolver());
+        assertEquals(true, ref.isSolved());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameterResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameterResolutionTest.java
new file mode 100644
index 0000000..c72e772
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/javaparser/declarations/JavaParserTypeParameterResolutionTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.javaparser.declarations;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class JavaParserTypeParameterResolutionTest extends AbstractResolutionTest {
+
+    private void testGenericArguments(String containingMethodName) {
+        CompilationUnit cu = parseSample("GenericMethodArguments");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        ClassOrInterfaceDeclaration classDecl = Navigator.demandClass(cu, "GenericMethodArguments");
+        MethodDeclaration containingMethod = Navigator.demandMethod(classDecl, containingMethodName);
+        MethodCallExpr bar = Navigator.findMethodCall(containingMethod, "apply").get();
+
+        assertTrue(javaParserFacade.solve(bar).isSolved());
+    }
+
+    @Test
+    public void genericMethodWithGenericClassBasedArgument() {
+        testGenericArguments("useCase1");
+    }
+
+    @Test
+    public void genericMethodWithGenericClassArgument() {
+        testGenericArguments("useCase2");
+    }
+
+    @Test
+    public void declaredOnMethodPositiveCase() {
+        CompilationUnit cu = parseSample("MethodTypeParameter");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        ClassOrInterfaceDeclaration classDecl = Navigator.demandClass(cu, "Foo");
+        MethodDeclaration methodDecl = Navigator.demandMethod(classDecl, "usage");
+        MethodCallExpr callToFoo = (MethodCallExpr) Navigator.findReturnStmt(methodDecl).getExpression().get();
+        ResolvedMethodDeclaration methodDeclaration = javaParserFacade.solve(callToFoo).getCorrespondingDeclaration();
+        for (ResolvedTypeParameterDeclaration tp : methodDeclaration.getTypeParameters()) {
+            assertTrue(tp instanceof JavaParserTypeParameter);
+            assertEquals("C", tp.getName());
+            assertEquals(true, tp.declaredOnMethod());
+            assertEquals(false, tp.declaredOnType());
+        }
+    }
+
+    @Test
+    public void declaredOnMethodNegativeCase() {
+        CompilationUnit cu = parseSample("ClassTypeParameter");
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        JavaParserFacade javaParserFacade = JavaParserFacade.get(typeSolver);
+        ClassOrInterfaceDeclaration classDecl = Navigator.demandClass(cu, "Foo");
+        MethodDeclaration methodDecl = Navigator.demandMethod(classDecl, "usage");
+        MethodCallExpr callToFoo = (MethodCallExpr) Navigator.findReturnStmt(methodDecl).getExpression().get();
+        ResolvedMethodDeclaration methodDeclaration = javaParserFacade.solve(callToFoo).getCorrespondingDeclaration();
+        ResolvedReferenceTypeDeclaration typeDeclaration = methodDeclaration.declaringType();
+        assertEquals(2, typeDeclaration.getTypeParameters().size());
+        assertTrue(typeDeclaration.getTypeParameters().get(0) instanceof JavaParserTypeParameter);
+        assertEquals("A", typeDeclaration.getTypeParameters().get(0).getName());
+        assertEquals(false, typeDeclaration.getTypeParameters().get(0).declaredOnMethod());
+        assertEquals(true, typeDeclaration.getTypeParameters().get(0).declaredOnType());
+        assertTrue(typeDeclaration.getTypeParameters().get(1) instanceof JavaParserTypeParameter);
+        assertEquals("B", typeDeclaration.getTypeParameters().get(1).getName());
+        assertEquals(false, typeDeclaration.getTypeParameters().get(1).declaredOnMethod());
+        assertEquals(true, typeDeclaration.getTypeParameters().get(1).declaredOnType());
+
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/reflectionmodel/SymbolResolutionResolutionTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/reflectionmodel/SymbolResolutionResolutionTest.java
new file mode 100644
index 0000000..8e0989f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/reflectionmodel/SymbolResolutionResolutionTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.reflectionmodel;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.javaparser.Navigator;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SymbolResolutionResolutionTest extends AbstractResolutionTest {
+
+    @Test
+    public void getTypeOfField() {
+        CompilationUnit cu = parseSample("ReflectionFieldOfItself");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass");
+        VariableDeclarator field = Navigator.demandField(clazz, "PUBLIC");
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType ref = JavaParserFacade.get(typeSolver).getType(field);
+        assertEquals("int", ref.describe());
+    }
+
+    @Test
+    public void getTypeOfFieldAccess() {
+        CompilationUnit cu = parseSample("ReflectionFieldOfItself");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass");
+        VariableDeclarator field = Navigator.demandField(clazz, "PUBLIC");
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType ref = JavaParserFacade.get(typeSolver).getType(field.getInitializer().get());
+        assertEquals("int", ref.describe());
+    }
+
+    @Test
+    public void conditionalExpressionExample() {
+        CompilationUnit cu = parseSample("JreConditionalExpression");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo1");
+        ReturnStmt returnStmt = Navigator.findReturnStmt(method);
+        Expression expression = returnStmt.getExpression().get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType ref = JavaParserFacade.get(typeSolver).getType(expression);
+        assertEquals("java.lang.String", ref.describe());
+    }
+
+    @Test
+    public void conditionalExpressionExampleFollowUp1() {
+        CompilationUnit cu = parseSample("JreConditionalExpression");
+        ClassOrInterfaceDeclaration clazz = Navigator.demandClass(cu, "MyClass");
+        MethodDeclaration method = Navigator.demandMethod(clazz, "foo1");
+        MethodCallExpr expression = Navigator.findMethodCall(method, "next").get();
+
+        TypeSolver typeSolver = new ReflectionTypeSolver();
+        ResolvedType ref = JavaParserFacade.get(typeSolver).getType(expression);
+        assertEquals("java.lang.String", ref.describe());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBoundTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBoundTest.java
new file mode 100644
index 0000000..ba58dc7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SameAsBoundTest.java
@@ -0,0 +1,32 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.bounds;
+
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typeinference.Bound;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable;
+import com.github.javaparser.symbolsolver.resolution.typeinference.Instantiation;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+
+public class SameAsBoundTest {
+
+    private TypeSolver typeSolver = new ReflectionTypeSolver();
+    private ResolvedType stringType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(String.class.getCanonicalName()), typeSolver);
+
+    @Test
+    public void recognizeInstantiation() {
+        // { α = String } contains a single bound, instantiating α as String.
+        InferenceVariable inferenceVariable = new InferenceVariable("α", null);
+        Bound bound1 = new SameAsBound(inferenceVariable, stringType);
+        Bound bound2 = new SameAsBound(stringType, inferenceVariable);
+
+        assertEquals(Optional.of(new Instantiation(inferenceVariable, stringType)), bound1.isAnInstantiation());
+        assertEquals(Optional.of(new Instantiation(inferenceVariable, stringType)), bound2.isAnInstantiation());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBoundTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBoundTest.java
new file mode 100644
index 0000000..ecda077
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/bounds/SubtypeOfBoundTest.java
@@ -0,0 +1,86 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.bounds;
+
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedReferenceType;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.resolution.types.ResolvedWildcard;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typeinference.*;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.symbolsolver.resolution.typeinference.TypeHelper.isProperType;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+public class SubtypeOfBoundTest {
+
+    private TypeSolver typeSolver = new ReflectionTypeSolver();
+    private ResolvedReferenceType iterableType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Iterable.class.getCanonicalName()), typeSolver);
+    private ResolvedReferenceType listType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(List.class.getCanonicalName()), typeSolver);
+    private ResolvedType integerType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Integer.class.getCanonicalName()), typeSolver);
+    private ResolvedType doubleType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Double.class.getCanonicalName()), typeSolver);
+    private ResolvedType objectType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(Object.class.getCanonicalName()), typeSolver);
+
+    @Test
+    public void recognizeProperLowerBound1() {
+        ResolvedTypeParameterDeclaration typeParameterDeclaration = mock(ResolvedTypeParameterDeclaration.class);
+
+        // { Integer <: α, Double <: α, α <: Object } describes two proper lower bounds and one proper upper bound for α.
+
+        InferenceVariable inferenceVariable = new InferenceVariable("α", typeParameterDeclaration);
+        Bound bound = new SubtypeOfBound(integerType, inferenceVariable);
+
+        assertEquals(Optional.of(new ProperLowerBound(inferenceVariable, integerType)), bound.isProperLowerBound());
+    }
+
+    @Test
+    public void recognizeProperLowerBound2() {
+        ResolvedTypeParameterDeclaration typeParameterDeclaration = mock(ResolvedTypeParameterDeclaration.class);
+
+        // { Integer <: α, Double <: α, α <: Object } describes two proper lower bounds and one proper upper bound for α.
+
+        InferenceVariable inferenceVariable = new InferenceVariable("α", typeParameterDeclaration);
+        Bound bound = new SubtypeOfBound(doubleType, inferenceVariable);
+
+        assertEquals(Optional.of(new ProperLowerBound(inferenceVariable, doubleType)), bound.isProperLowerBound());
+    }
+
+    @Test
+    public void recognizeProperUpperBound1() {
+        ResolvedTypeParameterDeclaration typeParameterDeclaration = mock(ResolvedTypeParameterDeclaration.class);
+
+        // { Integer <: α, Double <: α, α <: Object } describes two proper lower bounds and one proper upper bound for α.
+
+        InferenceVariable inferenceVariable = new InferenceVariable("α", typeParameterDeclaration);
+        Bound bound = new SubtypeOfBound(inferenceVariable, objectType);
+
+        assertEquals(Optional.of(new ProperUpperBound(inferenceVariable, objectType)), bound.isProperUpperBound());
+    }
+
+    @Test
+    public void recognizeProperUpperBound2() {
+        ResolvedTypeParameterDeclaration typeParameterDeclaration1 = mock(ResolvedTypeParameterDeclaration.class);
+        ResolvedTypeParameterDeclaration typeParameterDeclaration2 = mock(ResolvedTypeParameterDeclaration.class);
+        // { α <: Iterable<?>, β <: Object, α <: List<β> } describes a proper upper bound for each of α and β, along with a dependency between them.
+
+        InferenceVariable alpha = new InferenceVariable("α", typeParameterDeclaration1);
+        InferenceVariable beta = new InferenceVariable("β", typeParameterDeclaration2);
+        ResolvedType iterableOfWildcard = new ReferenceTypeImpl(iterableType.getTypeDeclaration(), Arrays.asList(ResolvedWildcard.UNBOUNDED), typeSolver);
+        ResolvedType listOfBeta = new ReferenceTypeImpl(listType.getTypeDeclaration(), Arrays.asList(beta), typeSolver);
+
+        Bound bound1 = new SubtypeOfBound(alpha, iterableOfWildcard);
+        Bound bound2 = new SubtypeOfBound(beta, objectType);
+        Bound bound3 = new SubtypeOfBound(alpha, listOfBeta);
+
+        assertEquals(false, isProperType(listOfBeta));
+        assertEquals(Optional.of(new ProperUpperBound(alpha, iterableOfWildcard)), bound1.isProperUpperBound());
+        assertEquals(Optional.of(new ProperUpperBound(beta, objectType)), bound2.isProperUpperBound());
+        assertEquals(true, bound3.isADependency());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ConstraintFormulaTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ConstraintFormulaTest.java
new file mode 100644
index 0000000..0563ca5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typeinference/constraintformulas/ConstraintFormulaTest.java
@@ -0,0 +1,70 @@
+package com.github.javaparser.symbolsolver.resolution.typeinference.constraintformulas;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.resolution.declarations.ResolvedTypeParameterDeclaration;
+import com.github.javaparser.resolution.types.ResolvedType;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl;
+import com.github.javaparser.symbolsolver.resolution.typeinference.BoundSet;
+import com.github.javaparser.symbolsolver.resolution.typeinference.ConstraintFormula;
+import com.github.javaparser.symbolsolver.resolution.typeinference.InferenceVariable;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+public class ConstraintFormulaTest {
+
+    private TypeSolver typeSolver = new ReflectionTypeSolver();
+    private ResolvedType stringType = new ReferenceTypeImpl(new ReflectionTypeSolver().solveType(String.class.getCanonicalName()), typeSolver);
+
+    /**
+     * From JLS 18.1.2
+     *
+     * From Collections.singleton("hi"), we have the constraint formula ‹"hi" → α›.
+     * Through reduction, this will become the constraint formula: ‹String <: α›.
+     */
+    @Test
+    public void testExpressionCompatibleWithTypeReduce1() {
+        ResolvedTypeParameterDeclaration tp = mock(ResolvedTypeParameterDeclaration.class);
+
+        Expression e = new StringLiteralExpr("hi");
+        InferenceVariable inferenceVariable = new InferenceVariable("α", tp);
+
+        ExpressionCompatibleWithType formula = new ExpressionCompatibleWithType(typeSolver, e, inferenceVariable);
+
+        ConstraintFormula.ReductionResult res1 = formula.reduce(BoundSet.empty());
+        assertEquals(
+                ConstraintFormula.ReductionResult.empty().withConstraint(new TypeCompatibleWithType(typeSolver, stringType, inferenceVariable)),
+                res1);
+
+        assertEquals(
+                ConstraintFormula.ReductionResult.empty().withConstraint(new TypeSubtypeOfType(typeSolver, stringType, inferenceVariable)),
+                res1.getConstraint(0).reduce(BoundSet.empty()));
+    }
+
+//    /**
+//     * From JLS 18.1.2
+//     *
+//     * From Arrays.asList(1, 2.0), we have the constraint formulas ‹1 → α› and ‹2.0 → α›. Through reduction,
+//     * these will become the constraint formulas ‹int → α› and ‹double → α›, and then ‹Integer <: α› and ‹Double <: α›.
+//     */
+//    @Test
+//    public void testExpressionCompatibleWithTypeReduce2() {
+//        throw new UnsupportedOperationException();
+//    }
+//
+//    /**
+//     * From JLS 18.1.2
+//     *
+//     * From the target type of the constructor invocation List<Thread> lt = new ArrayList<>(), we have the constraint
+//     * formula ‹ArrayList<α> → List<Thread>›. Through reduction, this will become the constraint formula ‹α <= Thread›,
+//     * and then ‹α = Thread›.
+//     */
+//    @Test
+//    public void testExpressionCompatibleWithTypeReduce3() {
+//        throw new UnsupportedOperationException();
+//    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolverTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolverTest.java
new file mode 100644
index 0000000..b9be968
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/AarTypeSolverTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.symbolsolver.AbstractTest;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class AarTypeSolverTest extends AbstractTest {
+
+    @Test
+    public void initial() throws IOException {
+        String pathToJar = adaptPath("src/test/resources/aars/support-compat-24.2.0.aar");
+        AarTypeSolver aarTypeSolver = new AarTypeSolver(new File(pathToJar));
+        assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.ActivityCompat").isSolved());
+        assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.ActivityManagerCompat").isSolved());
+        assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.NotificationCompat").isSolved());
+        assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.NotificationCompat.Action").isSolved());
+        assertEquals(true, aarTypeSolver.tryToSolveType("android.support.v4.app.NotificationCompat.Action.Builder").isSolved());
+        assertEquals(false, aarTypeSolver.tryToSolveType("com.github.javaparser.ASTParser.Foo").isSolved());
+        assertEquals(false, aarTypeSolver.tryToSolveType("com.github.javaparser.Foo").isSolved());
+        assertEquals(false, aarTypeSolver.tryToSolveType("Foo").isSolved());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolverTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolverTest.java
new file mode 100644
index 0000000..346fcfd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/resolution/typesolvers/JarTypeSolverTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Federico Tomassetti
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+package com.github.javaparser.symbolsolver.resolution.typesolvers;
+
+import com.github.javaparser.symbolsolver.AbstractTest;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+
+public class JarTypeSolverTest extends AbstractTest {
+
+    @Test
+    public void initial() throws IOException {
+        String pathToJar = adaptPath("src/test/resources/javaparser-core-2.1.0.jar");
+        JarTypeSolver jarTypeSolver = new JarTypeSolver(pathToJar);
+        assertEquals(true, jarTypeSolver.tryToSolveType("com.github.javaparser.SourcesHelper").isSolved());
+        assertEquals(true, jarTypeSolver.tryToSolveType("com.github.javaparser.Token").isSolved());
+        assertEquals(true, jarTypeSolver.tryToSolveType("com.github.javaparser.ASTParser.JJCalls").isSolved());
+        assertEquals(false, jarTypeSolver.tryToSolveType("com.github.javaparser.ASTParser.Foo").isSolved());
+        assertEquals(false, jarTypeSolver.tryToSolveType("com.github.javaparser.Foo").isSolved());
+        assertEquals(false, jarTypeSolver.tryToSolveType("Foo").isSolved());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/utils/SymbolSolverQuickSetupTest.java b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/utils/SymbolSolverQuickSetupTest.java
new file mode 100644
index 0000000..ddc1bc6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/java/com/github/javaparser/symbolsolver/utils/SymbolSolverQuickSetupTest.java
@@ -0,0 +1,50 @@
+package com.github.javaparser.symbolsolver.utils;
+
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.symbolsolver.JavaSymbolSolver;
+import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
+import com.github.javaparser.utils.SourceRoot;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+
+/**
+ * Try to resolve all the ClassOrInterfaceDeclaration and MethodCallExpr in some resources folder. If it fails to do
+ * so, an IllegalStateException is thrown.
+ */
+public class SymbolSolverQuickSetupTest {
+
+    private Path root = Paths.get("src/test/resources/symbolsolver_quicksetup");
+    private ParserConfiguration parserConfiguration = new ParserConfiguration();
+
+    @Before
+    public void setUp() throws IOException {
+        SymbolSolverQuickSetup ssr = new SymbolSolverQuickSetup(root);
+        TypeSolver typeSolver = ssr.walk();
+
+        parserConfiguration.setSymbolResolver(new JavaSymbolSolver(typeSolver));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void notResolve() throws IOException {
+        SourceRoot sourceRoot = new SourceRoot(root);
+        sourceRoot.tryToParse();
+        // try to resolve, this will fail
+        sourceRoot.getCompilationUnits().forEach(compilationUnit ->
+                compilationUnit.findAll(ClassOrInterfaceDeclaration.class).forEach(ClassOrInterfaceDeclaration::resolve));
+    }
+
+    @Test
+    public void resolve() throws IOException {
+        SourceRoot sourceRoot = new SourceRoot(root, parserConfiguration);
+        sourceRoot.tryToParse();
+        // try to resolve, this should succeed
+        sourceRoot.getCompilationUnits().forEach(compilationUnit ->
+                compilationUnit.findAll(ClassOrInterfaceDeclaration.class).forEach(ClassOrInterfaceDeclaration::resolve));
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/AClassWithFields.java.txt b/javaparser-symbol-solver-testing/src/test/resources/AClassWithFields.java.txt
new file mode 100644
index 0000000..e8e10b6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/AClassWithFields.java.txt
@@ -0,0 +1,11 @@
+class A {
+    String a;
+}
+
+class B extends A {
+    float b;
+}
+
+class C extends B {
+    int c;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/AClassWithFieldsAndGenerics.java.txt b/javaparser-symbol-solver-testing/src/test/resources/AClassWithFieldsAndGenerics.java.txt
new file mode 100644
index 0000000..601ebb6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/AClassWithFieldsAndGenerics.java.txt
@@ -0,0 +1,13 @@
+import java.util.List;
+
+class A {
+    String a;
+}
+
+class B<T> extends A {
+    List<T> b;
+}
+
+class C extends B<String> {
+    int c;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/AccessClassMemberThroughThis.java.txt b/javaparser-symbol-solver-testing/src/test/resources/AccessClassMemberThroughThis.java.txt
new file mode 100644
index 0000000..00ed1ec
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/AccessClassMemberThroughThis.java.txt
@@ -0,0 +1,17 @@
+class AccessClassMemberThroughThis {
+
+	private String label;
+
+	public void setLabel(final String label) {
+		this.label = label;
+	}
+
+	public String getLabel1() {
+		return label;
+	}
+
+	public String getLabel2() {
+		return this.label;
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/AccessEnumMemberThroughThis.java.txt b/javaparser-symbol-solver-testing/src/test/resources/AccessEnumMemberThroughThis.java.txt
new file mode 100644
index 0000000..df6a4db
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/AccessEnumMemberThroughThis.java.txt
@@ -0,0 +1,15 @@
+enum AccessEnumMemberThroughThis {
+
+	CONSTANT("constant");
+
+	private String label;
+
+	public String getLabel() {
+		return this.label;
+	}
+
+	public String getLabel2() {
+		return this.getLabel();
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/AccessThroughSuper.java.txt b/javaparser-symbol-solver-testing/src/test/resources/AccessThroughSuper.java.txt
new file mode 100644
index 0000000..54167ce
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/AccessThroughSuper.java.txt
@@ -0,0 +1,25 @@
+class AccessThroughSuper {
+	
+	class SuperClass {
+
+		protected String field;
+
+		protected String method() { 
+			return field;
+		}
+
+	}
+
+	class SubClass extends SuperClass {
+
+		protected String fieldTest() { 
+			return super.field;
+		}
+
+		protected String methodTest() { 
+			return super.method();
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/AnEnum.java.txt b/javaparser-symbol-solver-testing/src/test/resources/AnEnum.java.txt
new file mode 100644
index 0000000..81cd56f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/AnEnum.java.txt
@@ -0,0 +1,9 @@
+enum MyEnum {
+    E1, E2;
+    int i;
+    static long j;
+
+    void foo(){
+
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Annotations.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Annotations.java.txt
new file mode 100644
index 0000000..910777b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Annotations.java.txt
@@ -0,0 +1,22 @@
+package foo.bar;
+
+public @interface MyAnnotation {
+}
+
+public @interface MyAnnotation2 {
+}
+
+public @interface MyAnnotationWithFields {
+    int field();
+}
+
+@MyAnnotation
+class CA {
+
+}
+
+@MyAnnotation2
+class CB extends CA {
+
+}
+
diff --git a/javaparser-symbol-solver-testing/src/test/resources/AnonymousClassDeclarations.java.txt b/javaparser-symbol-solver-testing/src/test/resources/AnonymousClassDeclarations.java.txt
new file mode 100644
index 0000000..f994225
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/AnonymousClassDeclarations.java.txt
@@ -0,0 +1,71 @@
+class AnonymousClassDeclarations {
+
+    static class DoFn<I,O> {
+        static class ProcessContext {
+            public Long innerClassMethod() {}
+        }
+
+        enum MyEnum {
+            E1, E2, E3
+        }
+
+        public void process(ProcessContext context) {}
+    }
+
+    static class Transform<I,O> {}
+
+    static class ParDo {
+        static <I,O> Transform<I,O> of(DoFn<I,O> doFn) {
+            return null;
+        }
+    }
+
+    void fooBar1() {
+        ParDo.of(new DoFn<Integer,Long>() {});
+    }
+
+    void fooBar2() {
+        ParDo.of(new DoFn<Integer,Long>() {
+            public void process(ProcessContext c){
+                return c.innerClassMethod();
+            }
+        });
+    }
+
+    void fooBar3() {
+        ParDo.of(new DoFn<Integer,Long>() {
+
+            void callAnnonClassInnerMethod() {}
+
+            public void process(ProcessContext c) {
+                callAnnonClassInnerMethod();
+            }
+        });
+    }
+
+     void fooBar4() {
+        ParDo.of(new DoFn<Integer,Long>() {
+
+            void callAnnonClassInnerMethod() {}
+
+            public void process(ProcessContext c) {
+                MyEnum.E3.toString();
+            }
+        });
+    }
+
+    void fooBar5() {
+        ParDo.of(new DoFn<Integer,Long>() {
+
+            void callAnnonClassInnerMethod() {}
+
+            enum MyInnerEnum {
+                E1, E2, E3
+            }
+            public void process(ProcessContext c) {
+                MyInnerEnum.E3.toString();
+            }
+        });
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ArrayAccess.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ArrayAccess.java.txt
new file mode 100644
index 0000000..198a730
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ArrayAccess.java.txt
@@ -0,0 +1,9 @@
+class ArrayAccess {
+
+	private String[] array;
+
+	private char access() {
+		return array[0].trim();
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ClassCast.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ClassCast.java.txt
new file mode 100644
index 0000000..48eab82
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ClassCast.java.txt
@@ -0,0 +1,13 @@
+class Node {
+
+}
+
+class ClassCast {
+
+    public static <N extends Node> List<N> getNodesByType(Node container, Class<N> clazz) {
+        List<N> nodes = new ArrayList<N>();
+        Node child;
+        return clazz.cast(child);
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ClassExpression.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ClassExpression.java.txt
new file mode 100644
index 0000000..ad9038c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ClassExpression.java.txt
@@ -0,0 +1,9 @@
+import java.util.EnumSet;
+
+class ClassExpression {
+
+	private void foo() {
+		EnumSet.noneOf(java.util.Locale.Category.class);
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ClassTypeParameter.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ClassTypeParameter.java.txt
new file mode 100644
index 0000000..c98543b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ClassTypeParameter.java.txt
@@ -0,0 +1,7 @@
+class Foo<A, B> {
+    public void foo(A a);
+
+    public void usage(A a) {
+        return foo(a);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ClassWithMethods.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ClassWithMethods.java.txt
new file mode 100644
index 0000000..dce4766
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ClassWithMethods.java.txt
@@ -0,0 +1,14 @@
+class Super {
+    public void foo1() { }
+    public void foo2() { }
+}
+
+class A extends Super {
+    public void foo0() { }
+    public void foo1() { }
+    public void foo3(int i) { }
+    public void foo4(Object o) { }
+    public void foo4(String a) { }
+    public void foo5(String a) { }
+    public void foo5(A a) { }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ClassWithSymbols.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ClassWithSymbols.java.txt
new file mode 100644
index 0000000..bb693fb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ClassWithSymbols.java.txt
@@ -0,0 +1,39 @@
+class Super {
+    protected boolean k;
+    public static char m;
+}
+
+interface SuperSuperInterface {
+    public int o;
+}
+
+interface SuperInterface extends SuperSuperInterface {
+    public int p;
+}
+
+class A extends Super implements SuperInterface {
+
+    private int i;
+    private static long j;
+
+    public void foo1(){
+        return i;
+    }
+
+    public void foo2(){
+        return j;
+    }
+
+    public void foo3(){
+        return k;
+    }
+
+    public void foo4(){
+        return m;
+    }
+
+    public void foo5(){
+        return o;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ClassWithTypeVariables.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ClassWithTypeVariables.java.txt
new file mode 100644
index 0000000..50e1208
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ClassWithTypeVariables.java.txt
@@ -0,0 +1,3 @@
+class A<A, B extends Object, C> {
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ClassWithTypes.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ClassWithTypes.java.txt
new file mode 100644
index 0000000..0c1ed60
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ClassWithTypes.java.txt
@@ -0,0 +1,19 @@
+class Super {
+    protected boolean k;
+    private static char m;
+
+}
+
+class A extends Super {
+
+    class B {
+        class C {
+
+        }
+    }
+
+    enum E {
+        E1, E2
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/CompilationUnitSymbols.java.txt b/javaparser-symbol-solver-testing/src/test/resources/CompilationUnitSymbols.java.txt
new file mode 100644
index 0000000..9d60fab
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/CompilationUnitSymbols.java.txt
@@ -0,0 +1,5 @@
+package com.foo;
+
+import static org.junit.Assert.assertEquals;
+import static java.lang.System.out;
+import static java.lang.System.*;
diff --git a/javaparser-symbol-solver-testing/src/test/resources/CompilationUnitWithImports.java.txt b/javaparser-symbol-solver-testing/src/test/resources/CompilationUnitWithImports.java.txt
new file mode 100644
index 0000000..df0b415
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/CompilationUnitWithImports.java.txt
@@ -0,0 +1,4 @@
+package com.foo;
+
+import org.junit.Assert;
+import static org.junit.Assert.*;
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ElementOfList.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ElementOfList.java.txt
new file mode 100644
index 0000000..c8b719c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ElementOfList.java.txt
@@ -0,0 +1,23 @@
+import java.util.List;
+
+class Comment {
+
+}
+
+class AnnotationExpr {
+
+}
+
+class ElementOfList {
+
+    void foo() {
+        List<Comment> comments = commentsCollection.getAll();
+        Object a = comments.get(0);
+    }
+
+    void annotations() {
+        List<AnnotationExpr> annotations = new LinkedList<AnnotationExpr>();
+        Object a = annotations.get(annotations.size()-1);
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/EnumAndStaticInitializer.java.txt b/javaparser-symbol-solver-testing/src/test/resources/EnumAndStaticInitializer.java.txt
new file mode 100644
index 0000000..8acb2e6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/EnumAndStaticInitializer.java.txt
@@ -0,0 +1,25 @@
+import java.util.HashMap;
+
+class MyClass {
+
+    public enum Primitive {
+		Boolean ("Boolean"),
+		Char    ("Character"),
+		Byte    ("Byte"),
+		Short   ("Short"),
+		Int     ("Integer"),
+		Long    ("Long"),
+		Float   ("Float"),
+		Double  ("Double");
+
+		final String nameOfBoxedType;
+    }
+
+    static final HashMap<String, Primitive> unboxMap = new HashMap<String, Primitive>();
+	static {
+		for(Primitive unboxedType : Primitive.values()) {
+			unboxMap.put(unboxedType.nameOfBoxedType, unboxedType);
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/GenericCollection.java.txt b/javaparser-symbol-solver-testing/src/test/resources/GenericCollection.java.txt
new file mode 100644
index 0000000..09d4024
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/GenericCollection.java.txt
@@ -0,0 +1,12 @@
+class Node {
+    abstract java.util.List<Node> getChildrenNodes();
+}
+
+class Foo {
+
+    public Object bar() {
+        Node node;
+        java.util.List<Node> children = new java.util.LinkedList<Node>();
+        return children.addAll(node.getChildrenNodes());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/GenericCollectionWithExtension.java.txt b/javaparser-symbol-solver-testing/src/test/resources/GenericCollectionWithExtension.java.txt
new file mode 100644
index 0000000..22261ca
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/GenericCollectionWithExtension.java.txt
@@ -0,0 +1,21 @@
+class Node {
+}
+
+class Comment extends Node {
+}
+
+class Foo {
+
+    public <T> void foo(java.util.List<T> t1, java.util.List<T> t2) {
+    }
+
+    public Object bar() {
+        Node node;
+        java.util.List<Node> children = new java.util.LinkedList<Node>();
+        java.util.List<Comment> commentsToAttribute;
+
+        foo(children, commentsToAttribute);
+
+        return children.addAll(commentsToAttribute);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/GenericFields.java.txt b/javaparser-symbol-solver-testing/src/test/resources/GenericFields.java.txt
new file mode 100644
index 0000000..7313b25
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/GenericFields.java.txt
@@ -0,0 +1,15 @@
+interface I {
+    int i = 0;
+}
+
+class CA<T> implements I {
+
+    T t;
+
+}
+
+class CB extends CA<java.util.List<Boolean>> {
+
+    String s;
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/GenericMethodArguments.java.txt b/javaparser-symbol-solver-testing/src/test/resources/GenericMethodArguments.java.txt
new file mode 100644
index 0000000..eb4b1e1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/GenericMethodArguments.java.txt
@@ -0,0 +1,33 @@
+class GenericMethodArguments {
+
+    static class Items<T> {
+        public <Output extends T> Output apply(Transform<? super Items<T>, Output> t) {
+            return null;
+        }
+    }
+
+    static class Transforms {
+        public static <I, O> Transform<I, O> of(DoFn<I, O> fn) {
+            return null;
+        }
+    }
+
+    static class Transform<Input, Output> {}
+
+    static class DoFn<Input, Output> {}
+
+    static class MyFn1<T> extends DoFn<T, Long> {}
+
+    static class MyFn2 extends MyFn1<Integer> {}
+
+    private Items<Integer> items;
+
+    public void useCase1() {
+        items.apply(Transforms.of(new MyFn2()));
+    }
+
+    public void useCase2() {
+        items.apply(Transforms.of(new DoFn<Integer,Long>(){}));
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Generics.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Generics.java.txt
new file mode 100644
index 0000000..0ce1b02
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Generics.java.txt
@@ -0,0 +1,46 @@
+package me.tomassetti.symbolsolver.javaparser;
+
+import java.util.Optional;
+import java.util.List;
+
+public final class Generics {
+
+    Optional<String> s;
+    Optional<Integer> i;
+    Optional<Generics> g;
+
+}
+
+public final class SomeCollection<A> {
+
+    public A a;
+    public List<A> as;
+
+    public void foo1(){
+        new SomeCollection<String>().a;
+    }
+
+    public void foo2(){
+        new SomeCollection<String>().as;
+    }
+
+}
+
+public final class GenericMethodCalls {
+
+    public class Base <T> {
+
+        public void callee(T data) {
+        }
+
+    }
+
+    public class Derived extends Base<String> {
+
+        public void caller() {
+            callee("test");
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Generics_issue7.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Generics_issue7.java.txt
new file mode 100644
index 0000000..2f12168
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Generics_issue7.java.txt
@@ -0,0 +1,32 @@
+package me.tomassetti.symbolsolver.javaparser;
+
+import java.util.Optional;
+import java.util.List;
+import java.util.Arrays;
+
+public final class Generics {
+
+    Optional<String> s;
+    Optional<Integer> i;
+    Optional<Generics> g;
+
+}
+
+public final class SomeCollection<A> {
+
+    public A a;
+    public List<A> as;
+
+    public void foo1(){
+        new SomeCollection<String>().a;
+    }
+
+    public void foo2(){
+        new SomeCollection<String>().as;
+    }
+
+    public List<Long> foo3(){
+        return Arrays.asList(new Long[]{1L,2L});
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/InterfaceInheritance.java.txt b/javaparser-symbol-solver-testing/src/test/resources/InterfaceInheritance.java.txt
new file mode 100644
index 0000000..27b027e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/InterfaceInheritance.java.txt
@@ -0,0 +1,16 @@
+class Test{
+
+    interface Foo{
+        double foobar();
+    }
+
+    interface Bar extends Foo {
+
+    }
+
+    void test(){
+        Bar b = null;
+        b.foobar();
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue116.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue116.java.txt
new file mode 100644
index 0000000..5e96f6f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue116.java.txt
@@ -0,0 +1,7 @@
+public class JavaTest {
+    public String[] field;
+
+    public void foo(String[] arg){
+        arg;
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue156.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue156.java.txt
new file mode 100644
index 0000000..e8b7da7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue156.java.txt
@@ -0,0 +1,9 @@
+public class Issue156 {
+    String myField;
+
+    class Inner {
+        void foo() {
+            Issue156.this.myField.charAt(0);
+       }
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue18.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue18.java.txt
new file mode 100644
index 0000000..9689294
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue18.java.txt
@@ -0,0 +1,8 @@
+import java.util.*;
+
+class Foo {
+    void bar() {
+        Map m = new HashMap();
+        m.put("a", "b");
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue186.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue186.java.txt
new file mode 100644
index 0000000..f67def2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue186.java.txt
@@ -0,0 +1,23 @@
+import java.util.*;
+import java.util.stream.*;
+
+public class JavaTest {
+
+    public void foo(){
+        List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
+
+        Stream<String> myStream = myList.stream();
+
+        myStream.map(s -> s + ":)")
+        	        .filter(s -> s.length()>1)
+        		    .flatMap(s -> Arrays.stream(s.split("")));
+    }
+
+    public void bar(){
+        Stream<String> myStream;
+        myStream.filter(s -> s.contains("Hamlet"))
+            .map(l -> l.length())
+            .filter(s -> s > 15)
+            .count();
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue200.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue200.java.txt
new file mode 100644
index 0000000..b42ffe3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue200.java.txt
@@ -0,0 +1,32 @@
+import java.util.List;
+
+public class JavaTest {
+    class MethodDeclaration {
+        public <T> List<T> getNodesByType(Class<T> clazz) {
+            return new ArrayList<T>();
+        }
+    }
+    class JavaParserFacade {
+        public Solved solve(MethodDeclaration method) {
+            return new Solved();
+        }
+    }
+    class Solved {
+        public boolean isSolved() {
+            return true;
+        }
+    }
+    private List<String> foo(MethodDeclaration methodDecl) {
+        return methodDecl
+                .getNodesByType(MethodDeclaration.class)
+                .stream()
+                .map(statement -> {
+                    try {
+                        return new JavaParserFacade().solve(statement);
+                    } catch (Throwable e) {
+                        return null;
+                    }
+                })
+                .filter(parsed -> parsed != null && parsed.isSolved());
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue232.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue232.java.txt
new file mode 100644
index 0000000..fbe570a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue232.java.txt
@@ -0,0 +1,12 @@
+class Double {
+}
+
+class DoubleConsumer {
+}
+
+interface OfDouble extends OfPrimitive<Double, DoubleConsumer, OfDouble> {
+
+}
+
+interface OfPrimitive<T, C, S extends OfPrimitive<T, C, S>> {
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue235.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue235.java.txt
new file mode 100644
index 0000000..30ca4ef
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue235.java.txt
@@ -0,0 +1,17 @@
+class Foo {
+    static class Bar {
+        static class Baz {}
+    }
+    static void new_Bar_Baz_direct() {
+        new Bar.Baz();
+    }
+    static void new_Bar_Baz() {
+        new Bar.Baz() {};
+    }
+    static void new_Bar() {
+        new Bar() {};
+    }
+    static void new_Foo_Bar() {
+        new Foo.Bar() {};
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue241.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue241.java.txt
new file mode 100644
index 0000000..11b8b84
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue241.java.txt
@@ -0,0 +1,7 @@
+import static issue241.TypeWithMemberType.MemberInterface; 
+
+public class Main {
+
+	private MemberInterface foo;
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue251.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue251.java.txt
new file mode 100644
index 0000000..3e1e6b6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue251.java.txt
@@ -0,0 +1,17 @@
+class Main {
+	
+	class Foo { }
+	
+	interface GenericBase <F> { }
+	
+	class GenericDerived <F extends Foo> implements GenericBase<F> { }
+
+	private <B extends Foo> void foo(GenericBase<B> g) { }
+	
+	private <D extends Foo> void foo(GenericDerived<D> g) { }
+	
+	void bar() {
+		GenericDerived<Foo> gd = new GenericDerived<>();
+		foo(gd);
+	}
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue338.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue338.java.txt
new file mode 100644
index 0000000..6e8010e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue338.java.txt
@@ -0,0 +1,93 @@
+class TypePromotions {
+
+        public void byteParam(byte p1) {
+
+        }
+
+        public void shortParam(short p1) {
+
+        }
+
+        public void intParam(int p1) {
+
+        }
+
+        public void longParam(long p1) {
+
+        }
+
+        public void callingLong() {
+            longParam((byte)1);
+            longParam((short)1);
+            longParam(1);
+            longParam(1L);
+        }
+
+        public void callingInt() {
+            intParam((byte)1);
+            intParam((short)1);
+            intParam(1);
+            intParam(1L); // fails
+        }
+
+        public void callingShort() {
+            shortParam((byte)1);
+            shortParam((short)1);
+            shortParam(1); // fails
+            shortParam(1L); // fails
+        }
+
+        public void callingByte() {
+            byteParam((byte)1);
+            byteParam((short)1); // fails
+            byteParam(1); // fails
+            byteParam(1L); // fails
+        }
+    }
+
+class TypePromotionsWithExtraParam {
+
+        public void byteParam(int p0, byte p1) {
+
+        }
+
+        public void shortParam(int p0, short p1) {
+
+        }
+
+        public void intParam(int p0, int p1) {
+
+        }
+
+        public void longParam(int p0, long p1) {
+
+        }
+
+        public void callingLong() {
+            longParam(6, (byte)1);
+            longParam(6, (short)1);
+            longParam(6, 1);
+            longParam(6, 1L);
+        }
+
+        public void callingInt() {
+            intParam(6, (byte)1);
+            intParam(6, (short)1);
+            intParam(6, 1);
+            intParam(6, 1L); // fails
+        }
+
+        public void callingShort() {
+            shortParam(6, (byte)1);
+            shortParam(6, (short)1);
+            shortParam(6, 1); // fails
+            shortParam(6, 1L); // fails
+        }
+
+        public void callingByte() {
+            byteParam(6, (byte)1);
+            byteParam(6, (short)1); // fails
+            byteParam(6, 1); // fails
+            byteParam(6, 1L); // fails
+        }
+    }
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Issue84.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Issue84.java.txt
new file mode 100644
index 0000000..4cc3c96
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Issue84.java.txt
@@ -0,0 +1,10 @@
+public class VariadicIssue {
+
+  public static void main(String[] args) {
+     variadicMethod(true, 1, 2, 3);
+  }
+
+  static String variadicMethod(boolean b, int... ints) {
+    return "";
+  }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/JreConditionalExpression.java.txt b/javaparser-symbol-solver-testing/src/test/resources/JreConditionalExpression.java.txt
new file mode 100644
index 0000000..0e8295b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/JreConditionalExpression.java.txt
@@ -0,0 +1,10 @@
+import java.io.*;
+
+class MyClass {
+
+	public void foo1() {
+	    java.util.Scanner s = new java.util.Scanner(in, encoding).useDelimiter("\\A");
+        return s.hasNext() ? s.next() : "";
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Lambda.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Lambda.java.txt
new file mode 100644
index 0000000..6e0cbde
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Lambda.java.txt
@@ -0,0 +1,44 @@
+import java.util.List;
+import java.util.function.BiFunction;
+
+@FunctionalInterface
+public interface Lambda {
+	String process(String value);
+}
+
+public class Agenda {
+	
+	Lambda functional = p -> p.toLowerCase();
+
+    private List<String> persons;
+
+    public void lambdaMap(String personName) {
+        return persons.stream().map(p -> p.toLowerCase());
+    }
+
+    public void lambdaMap2(){
+        return persons.stream().map(p -> p.codePoints());
+    }
+
+    public void reduce(){
+        List<Integer> a;
+        return a.stream().reduce((x,y) -> x * y);
+    }
+
+    double test(BiFunction<Integer,List,String> func){
+        return 0;
+    }
+
+    public double bifunc(){
+        return test((x,y) -> String.valueOf(func(x,y)));
+    }
+
+    int func(int a, List b){
+        return 1;
+    }
+
+    public void testFunctionalVar() {
+    	Lambda a = p -> p.toLowerCase();
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/LambdaCollect.java.txt b/javaparser-symbol-solver-testing/src/test/resources/LambdaCollect.java.txt
new file mode 100644
index 0000000..dc94da2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/LambdaCollect.java.txt
@@ -0,0 +1,12 @@
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Agenda {
+
+    private List<String> persons;
+
+    public void lambdaMap(String personName) {
+        return persons.stream().collect(Collectors.toList());
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/LambdaMulti.java.txt b/javaparser-symbol-solver-testing/src/test/resources/LambdaMulti.java.txt
new file mode 100644
index 0000000..b778453
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/LambdaMulti.java.txt
@@ -0,0 +1,32 @@
+import java.util.List;
+import java.util.stream.IntStream;
+
+public class Agenda {
+
+    private List<String> persons;
+
+    public void lambdaImpliedReturn() {
+        return persons.stream().parallel().map(i -> {
+            addPerson("");
+        }).findFirst().get();
+    }
+
+    public void lambdaSingleReturn() {
+        return persons.stream().parallel().map(i -> {
+            return addPerson("");
+        }).findFirst().get();
+    }
+
+    public void multiLineReturn() {
+        return persons.stream().parallel().map(i -> {
+            int irrelevant;
+            return addPerson("");
+        }).findFirst().get();
+    }
+
+
+    String addPerson(String x){
+
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/LambdaVoid.java.txt b/javaparser-symbol-solver-testing/src/test/resources/LambdaVoid.java.txt
new file mode 100644
index 0000000..97a6ea8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/LambdaVoid.java.txt
@@ -0,0 +1,14 @@
+import java.util.List;
+import java.util.stream.IntStream;
+
+public class Agenda {
+
+    private List<String> persons;
+
+    public void lambdaEmpty() {
+        return persons.stream().forEach(p -> {
+            System.out.println(p);
+        });
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/LocalTypeDeclarations.java.txt b/javaparser-symbol-solver-testing/src/test/resources/LocalTypeDeclarations.java.txt
new file mode 100644
index 0000000..387a43c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/LocalTypeDeclarations.java.txt
@@ -0,0 +1,14 @@
+class Foo {
+
+    void bar(){
+        int a;
+        Integer b;
+        Class<Integer> c;
+        Class<? super Integer> d;
+        Class<? extends Integer> e;
+        Class<? extends Class<? super Class<? extends Integer>>> f;
+        Class<? super Class<? extends Class<? super Integer>>> g;
+        a;b;c;d;e;f;g;
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/LocalVariableInParent.java.txt b/javaparser-symbol-solver-testing/src/test/resources/LocalVariableInParent.java.txt
new file mode 100644
index 0000000..066ab16
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/LocalVariableInParent.java.txt
@@ -0,0 +1,57 @@
+import java.util.List;
+
+class Node {
+}
+
+class Comment {
+}
+
+class LocalVariableInParent {
+
+    void foo1() {
+       for (Node child : null){
+            String s;
+            for (Object c : null){
+                if (true){
+                    s;
+                }
+            }
+        }
+    }
+
+    void foo3() {
+       for (Node child : null){
+            String s;
+            for (Object c : null){
+                s;
+            }
+        }
+    }
+
+    void foo2() {
+       for (Node child : null){
+            String s;
+            s;
+        }
+    }
+
+    void foo4() {
+        List<Node> children = node.getChildrenNodes();
+        for (Node child : children){
+            List<Comment> commentsInsideChild = new LinkedList<Comment>();
+            for (Comment c : commentsToAttribute){
+                if (true){
+                    commentsInsideChild.add(c);
+                }
+            }
+        }
+    }
+
+    void foo5() {
+        List<Comment> commentsInsideChild;
+        Comment c;
+        commentsInsideChild.add(c);
+    }
+
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/MethodCalls.java.txt b/javaparser-symbol-solver-testing/src/test/resources/MethodCalls.java.txt
new file mode 100644
index 0000000..c05119c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/MethodCalls.java.txt
@@ -0,0 +1,70 @@
+import java.util.List;
+
+class MethodCalls {
+
+    public int member;
+    
+    public MethodCalls getSelf()
+    {
+        return this;
+    }
+
+
+    public void foo()
+    {
+    }
+
+    void bar1()
+    {
+        getSelf().getSelf().foo();
+    }
+
+    int bar2()
+    {
+        return getSelf().m;
+    }
+
+    void inheritedInterfaceMethod(){
+        List<Integer> list;
+        list.toString();
+    }
+
+    void variadicTest(){
+        String[] varArg = new String[2];
+        foobar("a");
+        foobar(varArg);
+    }
+
+    int foobar(String s){
+        return 1;
+    }
+
+    void foobar(String... s){
+        return;
+    }
+
+    void variadicMethod(String... s)
+    {
+        this.variadicMethod("test");
+    }
+
+    <T> T genericMethod0() { return null; }
+    <T> T genericMethod1(T x) { return x; }
+
+    static <T> T staticGenericMethod0() { return null; }
+    static <T> T staticGenericMethod1(T x) { return x; }
+
+    static class GenericClass<T> {}
+
+    static void variadicWithGenericArg(int i, GenericClass<?>... c) {}
+
+    void genericMethodTest() {
+        this.<Integer>genericMethod0();
+        this.genericMethod1("Hello");
+
+        MethodCalls.<Integer>staticGenericMethod0();
+        MethodCalls.staticGenericMethod1("Hello");
+
+        MethodCalls.variadicWithGenericArg(1, new GenericClass<Long>());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/MethodTypeParameter.java.txt b/javaparser-symbol-solver-testing/src/test/resources/MethodTypeParameter.java.txt
new file mode 100644
index 0000000..0d0a1d5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/MethodTypeParameter.java.txt
@@ -0,0 +1,7 @@
+class Foo<A, B> {
+    public <C> void foo(C c);
+
+    public void usage(String s) {
+        return foo(s);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/MethodTypeParams.java.txt b/javaparser-symbol-solver-testing/src/test/resources/MethodTypeParams.java.txt
new file mode 100644
index 0000000..d552667
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/MethodTypeParams.java.txt
@@ -0,0 +1,38 @@
+class CompilationUnit {
+
+}
+
+public interface VoidVisitor<A> {
+
+	void visit(CompilationUnit n, A arg);
+
+	void visit(JavadocComment n, A arg);
+}
+
+public interface GenericVisitor<R, A> {
+
+	R visit(CompilationUnit n, A arg);
+
+	R visit(JavadocComment n, A arg);
+}
+
+class JavadocComment {
+
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+}
+
+public abstract class VoidVisitorAdapter<A> implements VoidVisitor<A> {
+
+	@Override public void visit(final AnnotationDeclaration n, final A arg) {
+	    JavadocComment javadocComment;
+		javadocComment.accept(this, arg);
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/MethodWithTypes.java.txt b/javaparser-symbol-solver-testing/src/test/resources/MethodWithTypes.java.txt
new file mode 100644
index 0000000..1b36e22
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/MethodWithTypes.java.txt
@@ -0,0 +1,6 @@
+class Main {
+    public void methodWithLocalTypes() {
+        class LocalClass {
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Navigator.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Navigator.java.txt
new file mode 100644
index 0000000..3b7a656
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Navigator.java.txt
@@ -0,0 +1,26 @@
+package me.tomassetti.symbolsolver.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.expr.NameExpr;
+
+import java.util.Optional;
+
+/**
+ * This class can be used to conveniently retrieve certain node from a JavaParser AST.
+ */
+public final class Navigator {
+
+    private Navigator() {
+        // prevent instantiation
+    }
+
+    public static Optional<TypeDeclaration> findType(CompilationUnit cu, String name) {
+        return cu.getTypes().stream().filter((t) -> t.getName().equals(name)).findFirst();
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Navigator2.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Navigator2.java.txt
new file mode 100644
index 0000000..ea0a463
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Navigator2.java.txt
@@ -0,0 +1,23 @@
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.expr.NameExpr;
+
+import java.util.Optional;
+
+/**
+ * This class can be used to conveniently retrieve certain node from a JavaParser AST.
+ */
+public final class Navigator {
+
+    private Navigator() {
+        // prevent instantiation
+    }
+
+    public static Optional<TypeDeclaration> findType(com.github.javaparser.ast.CompilationUnit cu, String name) {
+        return cu.getTypes().stream().filter((t) -> t.getName().equals(name)).findFirst();
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/Navigator3.java.txt b/javaparser-symbol-solver-testing/src/test/resources/Navigator3.java.txt
new file mode 100644
index 0000000..8ee7478
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/Navigator3.java.txt
@@ -0,0 +1,25 @@
+package my.packagez;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.expr.NameExpr;
+
+import java.util.Optional;
+
+/**
+ * This class can be used to conveniently retrieve certain node from a JavaParser AST.
+ */
+public final class Navigator {
+
+    private Navigator() {
+        // prevent instantiation
+    }
+
+    public static Optional<TypeDeclaration> findType(CompilationUnit cu, String name) {
+        return cu.getTypes().stream().filter((t) -> t.getName().equals(name)).findFirst();
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/NavigatorSimplified.java.txt b/javaparser-symbol-solver-testing/src/test/resources/NavigatorSimplified.java.txt
new file mode 100644
index 0000000..7f856bd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/NavigatorSimplified.java.txt
@@ -0,0 +1,33 @@
+package me.tomassetti.symbolsolver.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.expr.NameExpr;
+
+import java.util.stream.Stream;
+
+import java.util.Optional;
+
+/**
+ * This class can be used to conveniently retrieve certain node from a JavaParser AST.
+ */
+public final class Navigator {
+
+    private Navigator() {
+        // prevent instantiation
+    }
+
+    public static void findType() {
+        Stream<String> s = null;
+        s.filter((t)->t.isEmpty());
+    }
+
+    public void foo(Stream<String> s){
+
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/OverloadedMethods.java.txt b/javaparser-symbol-solver-testing/src/test/resources/OverloadedMethods.java.txt
new file mode 100644
index 0000000..fef317a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/OverloadedMethods.java.txt
@@ -0,0 +1,27 @@
+/**
+ * Created by federico on 02/08/15.
+ */
+public class OverloadedMethods {
+
+    public void overloaded(Object o){
+
+    }
+
+    public void overloaded(String o){
+
+    }
+
+    public void m1(){
+        overloaded(null);
+    }
+
+    public void m2(){
+        String s = null;
+        overloaded(s);
+    }
+
+    public void m3(){
+        Object o = null;
+        overloaded(o);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/QualifiedNameTest.java.txt b/javaparser-symbol-solver-testing/src/test/resources/QualifiedNameTest.java.txt
new file mode 100644
index 0000000..a8f86fe
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/QualifiedNameTest.java.txt
@@ -0,0 +1,8 @@
+class QualifiedNameTest {
+
+	public void foo1() {
+		java.util.Scanner s;
+		return s;
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ReferencesToField.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ReferencesToField.java.txt
new file mode 100644
index 0000000..ec80e90
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ReferencesToField.java.txt
@@ -0,0 +1,18 @@
+class ReferencesToField  {
+
+    int i;
+
+    public void method1(){
+        i = 2;
+    }
+
+}
+
+class ReferencesToFieldExtendingClass extends ReferencesToField {
+
+    public void method2(){
+        i = 2;
+    }
+
+}
+
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ReferencesToParameter.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ReferencesToParameter.java.txt
new file mode 100644
index 0000000..bded951
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ReferencesToParameter.java.txt
@@ -0,0 +1,11 @@
+package samples;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+
+class ReferenceToParameter extends AnnotationExpr {
+
+    public void aMethod(int foo){
+        System.out.println(foo);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ReflectionFieldOfItself.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ReflectionFieldOfItself.java.txt
new file mode 100644
index 0000000..39e812d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ReflectionFieldOfItself.java.txt
@@ -0,0 +1,7 @@
+import java.lang.reflect.Modifier;
+
+public class MyClass {
+
+    public static final int PUBLIC = Modifier.PUBLIC;
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/SwitchOnEnum.java.txt b/javaparser-symbol-solver-testing/src/test/resources/SwitchOnEnum.java.txt
new file mode 100644
index 0000000..47ec37b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/SwitchOnEnum.java.txt
@@ -0,0 +1,15 @@
+class SwitchOnEnum {
+
+    enum MyEnum {
+        E1, E2, E3
+    }
+
+	public void foo() {
+	    MyEnum e;
+		switch (e){
+		    case E1:
+		        break;
+		}
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/SymbolResolverExample.java.txt b/javaparser-symbol-solver-testing/src/test/resources/SymbolResolverExample.java.txt
new file mode 100644
index 0000000..acdaeac
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/SymbolResolverExample.java.txt
@@ -0,0 +1,11 @@
+class A {
+    A[] foo(String[] p1, int[] p2) { }
+}
+
+class B extends A {
+    float b;
+}
+
+class C extends B {
+    int c;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/ThisInAnonymousClass.java.txt b/javaparser-symbol-solver-testing/src/test/resources/ThisInAnonymousClass.java.txt
new file mode 100644
index 0000000..a558365
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/ThisInAnonymousClass.java.txt
@@ -0,0 +1,13 @@
+    class Foo {
+        void foo() { }
+    }
+
+    class Bar {
+        void bar() {
+            new Foo() {
+                void extraFoo() {
+                    this.foo();
+                }
+            };
+        }
+    }
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/TypeParamOnReturnType.java.txt b/javaparser-symbol-solver-testing/src/test/resources/TypeParamOnReturnType.java.txt
new file mode 100644
index 0000000..2140b52
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/TypeParamOnReturnType.java.txt
@@ -0,0 +1,15 @@
+public interface GenericVisitor<R, A> {
+
+}
+
+class Node {
+    public abstract <R, A> R accept(GenericVisitor<R, A> v, A arg);
+}
+
+class TypeParamOnReturnType implements GenericVisitor<Boolean, Node> {
+
+	private <T extends Node> boolean nodeEquals(final T n1, final T n2) {
+		return n1.accept(this, n2).booleanValue();
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/aars/support-compat-24.2.0.aar b/javaparser-symbol-solver-testing/src/test/resources/aars/support-compat-24.2.0.aar
new file mode 100644
index 0000000..ade62e1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/aars/support-compat-24.2.0.aar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/FieldDotExpressions.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/FieldDotExpressions.java
new file mode 100644
index 0000000..63f9b74
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/FieldDotExpressions.java
@@ -0,0 +1,33 @@
+public class FieldDotExpressions {
+    public static void main(String[] args) {
+        InnerClassFieldContainer.outerField.containerField.containerField.firstContainerMethod();
+        InnerClassFieldContainer.InnerClass.innerField.containerField.containerField.secondContainerMethod();
+        InnerClassFieldContainer.InnerClass.InnerInnerClass.InnerInnerInnerClass.innerInnerInnerField.thirdContainerMethod();
+    }
+}
+
+class FieldContainer {
+    FieldContainer containerField = new FieldContainer();
+    public String firstContainerMethod() {
+        return "firstContainerMethod()";
+    }
+    public String secondContainerMethod() {
+        return "secondContainerMethod()";
+    }
+    public String thirdContainerMethod() {
+        return "thirdContainerMethod()";
+    }
+}
+
+class InnerClassFieldContainer {
+    FieldContainer outerField = new FieldContainer();
+    class InnerClass {
+        FieldContainer innerField = new FieldContainer();
+        class InnerInnerClass {
+            FieldContainer innerInnerField = new FieldContainer();
+            class InnerInnerInnerClass {
+                FieldContainer innerInnerInnerField = new FieldContainer();
+            }
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/InnerClassDotExpressions.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/InnerClassDotExpressions.java
new file mode 100644
index 0000000..17b89f0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/InnerClassDotExpressions.java
@@ -0,0 +1,25 @@
+public class InnerClassDotExpressions {
+    public static void main(String[] args) {
+        InnerClassContainer.InnerClass.methodCall();
+        InnerClassContainer.InnerClass.InnerInnerClass.innerMethodCall();
+        InnerClassContainer.InnerClass.InnerInnerClass.InnerInnerInnerClass.innerInnerMethodCall();
+    }
+}
+
+class InnerClassContainer {
+    class InnerClass {
+        public static String methodCall() {
+            return "CalledMethod";
+        }
+        class InnerInnerClass {
+            public static String innerMethodCall() {
+                return "CalledInnerInnerClass";
+            }
+            class InnerInnerInnerClass {
+                public static String innerInnerMethodCall() {
+                    return "CalledInnerInnerInnerClass";
+                }
+            }
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/InnerStaticClassFieldDotExpressions.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/InnerStaticClassFieldDotExpressions.java
new file mode 100644
index 0000000..71cb2d0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/InnerStaticClassFieldDotExpressions.java
@@ -0,0 +1,8 @@
+import com.packageName.InnerStaticClassFieldContainer;
+
+public class InnerStaticClassFieldDotExpressions {
+    public static void main(String[] args) {
+        // force the solving of the argument
+        Integer.parseInt(InnerStaticClassFieldContainer.InnerClass.InnerInnerClass.MY_INT);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/PackageDotExpressions.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/PackageDotExpressions.java
new file mode 100644
index 0000000..eac5d34
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/PackageDotExpressions.java
@@ -0,0 +1,16 @@
+public class PackageDotExpressions {
+    public static void main(String[] args) {
+        // Method call from package prefix
+        com.packageName.ClassInPackage.staticMethod();
+
+        // Static method calls inside inner classes with package prefix
+        com.packageName.InnerClassContainer.InnerClass.methodCall();
+        com.packageName.InnerClassContainer.InnerClass.InnerInnerClass.innerMethodCall();
+        com.packageName.InnerClassContainer.InnerClass.InnerInnerClass.InnerInnerInnerClass.innerInnerMethodCall();
+
+        // Method calls from field objects with package prefix
+        com.packageName.InnerClassFieldContainer.outerField.containerField.containerField.firstContainerMethod();
+        com.packageName.InnerClassFieldContainer.InnerClass.innerField.containerField.containerField.secondContainerMethod();
+        com.packageName.InnerClassFieldContainer.InnerClass.InnerInnerClass.InnerInnerInnerClass.innerInnerInnerField.thirdContainerMethod();
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/ClassInPackage.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/ClassInPackage.java
new file mode 100644
index 0000000..68db33c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/ClassInPackage.java
@@ -0,0 +1,7 @@
+package com.packageName;
+
+public class ClassInPackage {
+    public static String staticMethod() {
+        return "ClassInPackage.staticMethod()";
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerClassContainer.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerClassContainer.java
new file mode 100644
index 0000000..eb80bc9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerClassContainer.java
@@ -0,0 +1,17 @@
+public class InnerClassContainer {
+    class InnerClass {
+        public static String methodCall() {
+            return "CalledMethod";
+        }
+        class InnerInnerClass {
+            public static String innerMethodCall() {
+                return "CalledInnerInnerClass";
+            }
+            class InnerInnerInnerClass {
+                public static String innerInnerMethodCall() {
+                    return "CalledInnerInnerInnerClass";
+                }
+            }
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerClassFieldContainer.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerClassFieldContainer.java
new file mode 100644
index 0000000..5a09bcf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerClassFieldContainer.java
@@ -0,0 +1,25 @@
+public class InnerClassFieldContainer {
+    FieldContainer outerField = new FieldContainer();
+    class InnerClass {
+        FieldContainer innerField = new FieldContainer();
+        class InnerInnerClass {
+            FieldContainer innerInnerField = new FieldContainer();
+            class InnerInnerInnerClass {
+                FieldContainer innerInnerInnerField = new FieldContainer();
+            }
+        }
+    }
+}
+
+class FieldContainer {
+    FieldContainer containerField = new FieldContainer();
+    public String firstContainerMethod() {
+        return "firstContainerMethod()";
+    }
+    public String secondContainerMethod() {
+        return "secondContainerMethod()";
+    }
+    public String thirdContainerMethod() {
+        return "thirdContainerMethod()";
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerStaticClassFieldContainer.java b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerStaticClassFieldContainer.java
new file mode 100644
index 0000000..f9cc6ca
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/differentiate_dot_expressions/com/packageName/InnerStaticClassFieldContainer.java
@@ -0,0 +1,15 @@
+package com.packageName;
+
+public class InnerStaticClassFieldContainer {
+    static class InnerClass {
+        public static String methodCall() {
+            return "CalledMethod";
+        }
+        static class InnerInnerClass {
+            public static final String MY_INT = "1";
+            public static String innerMethodCall() {
+                return "CalledInnerInnerClass";
+            }
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue113/com/foo/Widget.java b/javaparser-symbol-solver-testing/src/test/resources/issue113/com/foo/Widget.java
new file mode 100644
index 0000000..2dcab36
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue113/com/foo/Widget.java
@@ -0,0 +1,45 @@
+/**
+ * (C) 2016 Agilysys NV, LLC.  All Rights Reserved.  Confidential Information of Agilysys NV, LLC.
+ */
+package com.foo;
+
+import java.io.File;
+import java.io.IOException;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
+import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
+
+public class Widget extends com.foo.base.Widget {
+    private static final String PROJECT_ROOT = "/Users/peloquina/dev/javasymbolsolver-issue";
+    private static final String JAVA_ROOT = PROJECT_ROOT + "/src/main/java";
+    private static final String CLASS = JAVA_ROOT + "/com/foo/Widget.java";
+
+    public static void main(String[] args) throws IOException, ParseException {
+        File src = new File(JAVA_ROOT);
+        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();
+        combinedTypeSolver.add(new ReflectionTypeSolver(true));
+        combinedTypeSolver.add(new JavaParserTypeSolver(src));
+
+        CompilationUnit compilationUnit = JavaParser.parse(new File(CLASS));
+
+        JavaParserFacade parserFacade = JavaParserFacade.get(combinedTypeSolver);
+        MethodDeclaration methodDeclaration = compilationUnit.getNodesByType(MethodDeclaration.class).stream()
+              .filter(node -> node.getName().equals("doSomething")).findAny().orElse(null);
+        methodDeclaration.getNodesByType(MethodCallExpr.class).forEach(parserFacade::solve);
+    }
+
+    public void doSomething() {
+        doSomethingMore(new Widget());
+    }
+
+    public void doSomethingMore(Widget value) {
+        // does something
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue113/com/foo/base/Widget.java b/javaparser-symbol-solver-testing/src/test/resources/issue113/com/foo/base/Widget.java
new file mode 100644
index 0000000..cffffef
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue113/com/foo/base/Widget.java
@@ -0,0 +1,6 @@
+/**
+ * (C) 2016 Agilysys NV, LLC.  All Rights Reserved.  Confidential Information of Agilysys NV, LLC.
+ */
+package com.foo.base;
+
+public class Widget {}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue128/foo/Issue128.java b/javaparser-symbol-solver-testing/src/test/resources/issue128/foo/Issue128.java
new file mode 100644
index 0000000..50410e1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue128/foo/Issue128.java
@@ -0,0 +1,10 @@
+package foo;
+
+import static foo.JavaTest.*;
+// here could be the correct import for bar
+
+public class JavaTest {
+	public void test() {
+		bar();
+	}
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue144/HelloWorld.java b/javaparser-symbol-solver-testing/src/test/resources/issue144/HelloWorld.java
new file mode 100644
index 0000000..994d632
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue144/HelloWorld.java
@@ -0,0 +1,8 @@
+public class HelloWorld {
+
+    static String hw="Hello world";
+
+    public static void main(String[] args) {
+        System.out.println(hw);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue241/TypeWithMemberType.java b/javaparser-symbol-solver-testing/src/test/resources/issue241/TypeWithMemberType.java
new file mode 100644
index 0000000..c6d21a1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue241/TypeWithMemberType.java
@@ -0,0 +1,9 @@
+package issue241;
+
+public class TypeWithMemberType {
+
+	public interface MemberInterface {
+	
+	}
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue257/A.java.txt b/javaparser-symbol-solver-testing/src/test/resources/issue257/A.java.txt
new file mode 100644
index 0000000..db5a1d2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue257/A.java.txt
@@ -0,0 +1,9 @@
+package com.testbug;
+import net.testbug.B;
+public class A {
+	private B obj;
+	public void run()
+	{
+		obj.setParameter(null);
+	}
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue257/issue257.jar b/javaparser-symbol-solver-testing/src/test/resources/issue257/issue257.jar
new file mode 100644
index 0000000..5dc1c1a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue257/issue257.jar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/A.java b/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/A.java
new file mode 100644
index 0000000..c302ef3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/A.java
@@ -0,0 +1,11 @@
+package foo;
+
+interface A {
+
+	enum FindMeIfYouCan {
+		CONSTANT
+	}
+	
+	void overrideMe(FindMeIfYouCan v);
+}
+	
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/B.java b/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/B.java
new file mode 100644
index 0000000..69c3b3b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/B.java
@@ -0,0 +1,5 @@
+package foo;
+
+
+public abstract class B implements A {
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/C.java b/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/C.java
new file mode 100644
index 0000000..bc4f5e6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue276/foo/C.java
@@ -0,0 +1,11 @@
+package foo;
+
+public class C {
+	public static A getFoo() {
+		return new B() {
+			@Override
+			public void overrideMe(FindMeIfYouCan v) {
+			}
+		};
+	}
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/issue300/Issue300.java b/javaparser-symbol-solver-testing/src/test/resources/issue300/Issue300.java
new file mode 100644
index 0000000..ae39712
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/issue300/Issue300.java
@@ -0,0 +1,12 @@
+public class Issue300 {
+
+    class A {
+        int i;
+    }
+
+    class B {
+        B() {
+            new A().i = 0;
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser-core-2.1.0.jar b/javaparser-symbol-solver-testing/src/test/resources/javaparser-core-2.1.0.jar
new file mode 100644
index 0000000..38d4ea0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser-core-2.1.0.jar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser-core-3.0.0-alpha.2.jar b/javaparser-symbol-solver-testing/src/test/resources/javaparser-core-3.0.0-alpha.2.jar
new file mode 100644
index 0000000..cbe5b57
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser-core-3.0.0-alpha.2.jar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ASTHelper.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ASTHelper.txt
new file mode 100644
index 0000000..de7fbcf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ASTHelper.txt
@@ -0,0 +1,79 @@
+
+[ Class com.github.javaparser.ASTHelper ]
+  superclass: java.lang.Object
+  Line 58) new PrimitiveType(Primitive.Byte) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 60) new PrimitiveType(Primitive.Short) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 62) new PrimitiveType(Primitive.Int) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 64) new PrimitiveType(Primitive.Long) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 66) new PrimitiveType(Primitive.Float) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 68) new PrimitiveType(Primitive.Double) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 70) new PrimitiveType(Primitive.Boolean) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 72) new PrimitiveType(Primitive.Char) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 74) new VoidType() ==> com.github.javaparser.ast.type.VoidType
+  Line 89) String[] split = qualifiedName.split("\\.") ==> java.lang.String[]
+  Line 89) qualifiedName.split("\\.") ==> java.lang.String[]
+  Line 90) NameExpr ret = new NameExpr(split[0]) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 90) new NameExpr(split[0]) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 91) int i = 1 ==> int
+  Line 91) 1 ==> int
+  Line 91) i < split.length ==> boolean
+  Line 91) i++ ==> int
+  Line 92) ret = new QualifiedNameExpr(ret, split[i]) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 94) ret ==> com.github.javaparser.ast.expr.NameExpr
+  Line 107) new Parameter(type, new VariableDeclaratorId(name)) ==> com.github.javaparser.ast.body.Parameter
+  Line 122) List<VariableDeclarator> variables = new ArrayList<VariableDeclarator>() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 122) new ArrayList<VariableDeclarator>() ==> java.util.ArrayList<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 123) variables.add(variable) ==> boolean
+  Line 124) FieldDeclaration ret = new FieldDeclaration(modifiers, type, variables) ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 124) new FieldDeclaration(modifiers, type, variables) ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 125) ret ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 140) VariableDeclaratorId id = new VariableDeclaratorId(name) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 140) new VariableDeclaratorId(name) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 141) VariableDeclarator variable = new VariableDeclarator(id) ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 141) new VariableDeclarator(id) ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 142) createFieldDeclaration(modifiers, type, variable) ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 155) List<VariableDeclarator> vars = new ArrayList<VariableDeclarator>() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 155) new ArrayList<VariableDeclarator>() ==> java.util.ArrayList<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 156) vars.add(new VariableDeclarator(new VariableDeclaratorId(name))) ==> boolean
+  Line 157) new VariableDeclarationExpr(type, vars) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 170) List<Parameter> parameters = method.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 170) method.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 171) parameters == null ==> boolean
+  Line 172) parameters = new ArrayList<Parameter>() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 173) method.setParameters(parameters) ==> void
+  Line 175) parameters.add(parameter) ==> boolean
+  Line 188) List<Expression> args = call.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 188) call.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 189) args == null ==> boolean
+  Line 190) args = new ArrayList<Expression>() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 191) call.setArgs(args) ==> void
+  Line 193) args.add(arg) ==> boolean
+  Line 206) List<TypeDeclaration> types = cu.getTypes() ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 206) cu.getTypes() ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 207) types == null ==> boolean
+  Line 208) types = new ArrayList<TypeDeclaration>() ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 209) cu.setTypes(types) ==> void
+  Line 211) types.add(type) ==> boolean
+  Line 225) new ReferenceType(new ClassOrInterfaceType(name), arrayCount) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 238) new ReferenceType(type, arrayCount) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 249) List<Statement> stmts = block.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 249) block.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 250) stmts == null ==> boolean
+  Line 251) stmts = new ArrayList<Statement>() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 252) block.setStmts(stmts) ==> void
+  Line 254) stmts.add(stmt) ==> boolean
+  Line 265) addStmt(block, new ExpressionStmt(expr)) ==> void
+  Line 278) List<BodyDeclaration> members = type.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 278) type.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 279) members == null ==> boolean
+  Line 280) members = new ArrayList<BodyDeclaration>() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 281) type.setMembers(members) ==> void
+  Line 283) members.add(decl) ==> boolean
+  Line 287) List<N> nodes = new ArrayList<N>() ==> java.util.List<N>
+  Line 287) new ArrayList<N>() ==> java.util.ArrayList<N>
+  Line 288) Node child ==> com.github.javaparser.ast.Node
+  Line 288) container.getChildrenNodes() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 289) clazz.isInstance(child) ==> boolean
+  Line 290) nodes.add(clazz.cast(child)) ==> boolean
+  Line 292) nodes.addAll(getNodesByType(child, clazz)) ==> boolean
+  Line 294) nodes ==> java.util.List<N>
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_JavaParser.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_JavaParser.txt
new file mode 100644
index 0000000..bf12360
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_JavaParser.txt
@@ -0,0 +1,155 @@
+
+[ Class com.github.javaparser.JavaParser ]
+  superclass: java.lang.Object
+  Line 68) true ==> boolean
+  Line 70) false ==> boolean
+  Line 74) _doNotConsiderAnnotationsAsNodeStartForCodeAttribution ==> boolean
+  Line 78) _doNotConsiderAnnotationsAsNodeStartForCodeAttribution = doNotConsiderAnnotationsAsNodeStartForCodeAttribution ==> boolean
+  Line 83) _doNotAssignCommentsPreceedingEmptyLines ==> boolean
+  Line 88) _doNotAssignCommentsPreceedingEmptyLines = doNotAssignCommentsPreceedingEmptyLines ==> boolean
+  Line 93) parse(in, encoding, true) ==> com.github.javaparser.ast.CompilationUnit
+  Line 111) String code = SourcesHelper.streamToString(in, encoding) ==> java.lang.String
+  Line 111) SourcesHelper.streamToString(in, encoding) ==> java.lang.String
+  Line 112) InputStream in1 = SourcesHelper.stringToStream(code, encoding) ==> java.io.InputStream
+  Line 112) SourcesHelper.stringToStream(code, encoding) ==> java.io.InputStream
+  Line 113) CompilationUnit cu = new ASTParser(in1, encoding).CompilationUnit() ==> com.github.javaparser.ast.CompilationUnit
+  Line 113) new ASTParser(in1, encoding).CompilationUnit() ==> com.github.javaparser.ast.CompilationUnit
+  Line 114) considerComments ==> boolean
+  Line 115) insertComments(cu, code) ==> void
+  Line 117) cu ==> com.github.javaparser.ast.CompilationUnit
+  Line 119) new ParseException(ioe.getMessage()) ==> com.github.javaparser.ParseException
+  Line 135) parse(in, null, true) ==> com.github.javaparser.ast.CompilationUnit
+  Line 140) parse(file, encoding, true) ==> com.github.javaparser.ast.CompilationUnit
+  Line 158) final FileInputStream in = new FileInputStream(file) ==> java.io.FileInputStream
+  Line 158) new FileInputStream(file) ==> java.io.FileInputStream
+  Line 160) parse(in, encoding, considerComments) ==> com.github.javaparser.ast.CompilationUnit
+  Line 162) in.close() ==> void
+  Line 179) parse(file, null, true) ==> com.github.javaparser.ast.CompilationUnit
+  Line 185) String code = SourcesHelper.readerToString(reader) ==> java.lang.String
+  Line 185) SourcesHelper.readerToString(reader) ==> java.lang.String
+  Line 186) Reader reader1 = SourcesHelper.stringToReader(code) ==> java.io.Reader
+  Line 186) SourcesHelper.stringToReader(code) ==> java.io.Reader
+  Line 187) CompilationUnit cu = new ASTParser(reader1).CompilationUnit() ==> com.github.javaparser.ast.CompilationUnit
+  Line 187) new ASTParser(reader1).CompilationUnit() ==> com.github.javaparser.ast.CompilationUnit
+  Line 188) considerComments ==> boolean
+  Line 189) insertComments(cu, code) ==> void
+  Line 191) cu ==> com.github.javaparser.ast.CompilationUnit
+  Line 193) new ParseException(ioe.getMessage()) ==> com.github.javaparser.ParseException
+  Line 209) StringReader sr = new StringReader(blockStatement) ==> java.io.StringReader
+  Line 209) new StringReader(blockStatement) ==> java.io.StringReader
+  Line 210) BlockStmt result = new ASTParser(sr).Block() ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 210) new ASTParser(sr).Block() ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 211) sr.close() ==> void
+  Line 212) result ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 226) StringReader sr = new StringReader(statement) ==> java.io.StringReader
+  Line 226) new StringReader(statement) ==> java.io.StringReader
+  Line 227) Statement stmt = new ASTParser(sr).Statement() ==> com.github.javaparser.ast.stmt.Statement
+  Line 227) new ASTParser(sr).Statement() ==> com.github.javaparser.ast.stmt.Statement
+  Line 228) sr.close() ==> void
+  Line 229) stmt ==> com.github.javaparser.ast.stmt.Statement
+  Line 243) StringReader sr = new StringReader(importDeclaration) ==> java.io.StringReader
+  Line 243) new StringReader(importDeclaration) ==> java.io.StringReader
+  Line 244) ImportDeclaration id = new ASTParser(sr).ImportDeclaration() ==> com.github.javaparser.ast.ImportDeclaration
+  Line 244) new ASTParser(sr).ImportDeclaration() ==> com.github.javaparser.ast.ImportDeclaration
+  Line 245) sr.close() ==> void
+  Line 246) id ==> com.github.javaparser.ast.ImportDeclaration
+  Line 260) StringReader sr = new StringReader(expression) ==> java.io.StringReader
+  Line 260) new StringReader(expression) ==> java.io.StringReader
+  Line 261) Expression e = new ASTParser(sr).Expression() ==> com.github.javaparser.ast.expr.Expression
+  Line 261) new ASTParser(sr).Expression() ==> com.github.javaparser.ast.expr.Expression
+  Line 262) sr.close() ==> void
+  Line 263) e ==> com.github.javaparser.ast.expr.Expression
+  Line 277) StringReader sr = new StringReader(annotation) ==> java.io.StringReader
+  Line 277) new StringReader(annotation) ==> java.io.StringReader
+  Line 278) AnnotationExpr ae = new ASTParser(sr).Annotation() ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 278) new ASTParser(sr).Annotation() ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 279) sr.close() ==> void
+  Line 280) ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 294) StringReader sr = new StringReader(body) ==> java.io.StringReader
+  Line 294) new StringReader(body) ==> java.io.StringReader
+  Line 295) BodyDeclaration bd = new ASTParser(sr).AnnotationBodyDeclaration() ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 295) new ASTParser(sr).AnnotationBodyDeclaration() ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 296) sr.close() ==> void
+  Line 297) bd ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 305) commentsCollection.size() == 0 ==> boolean
+  Line 312) List<Comment> comments = commentsCollection.getAll() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 312) commentsCollection.getAll() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 313) PositionUtils.sortByBeginPosition(comments) ==> void
+  Line 314) List<Node> children = cu.getChildrenNodes() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 314) cu.getChildrenNodes() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 315) PositionUtils.sortByBeginPosition(children) ==> void
+  Line 317) cu.getPackage() != null && (children.size() == 0 || PositionUtils.areInOrder(comments.get(0), children.get(0))) ==> boolean
+  Line 318) cu.setComment(comments.get(0)) ==> void
+  Line 319) comments.remove(0) ==> com.github.javaparser.ast.comments.Comment
+  Line 322) insertCommentsInNode(cu, comments) ==> void
+  Line 329) node.getBeginLine() == lineComment.getBeginLine() && !node.hasComment() ==> boolean
+  Line 331) node.setComment(lineComment) ==> void
+  Line 332) true ==> boolean
+  Line 336) List<Node> children = new LinkedList<Node>() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 336) new LinkedList<Node>() ==> java.util.LinkedList<com.github.javaparser.ast.Node>
+  Line 337) children.addAll(node.getChildrenNodes()) ==> boolean
+  Line 338) PositionUtils.sortByBeginPosition(children) ==> void
+  Line 339) Collections.reverse(children) ==> void
+  Line 341) Node child ==> com.github.javaparser.ast.Node
+  Line 341) children ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 343) attributeLineCommentToNodeOrChild(child, lineComment) ==> boolean
+  Line 345) true ==> boolean
+  Line 349) false ==> boolean
+  Line 358) commentsToAttribute.size() == 0 ==> boolean
+  Line 365) List<Node> children = node.getChildrenNodes() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 365) node.getChildrenNodes() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 366) PositionUtils.sortByBeginPosition(children) ==> void
+  Line 368) Node child ==> com.github.javaparser.ast.Node
+  Line 368) children ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 369) List<Comment> commentsInsideChild = new LinkedList<Comment>() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 369) new LinkedList<Comment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.Comment>
+  Line 370) Comment c ==> com.github.javaparser.ast.comments.Comment
+  Line 370) commentsToAttribute ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 371) PositionUtils.nodeContains(child, c, _doNotConsiderAnnotationsAsNodeStartForCodeAttribution) ==> boolean
+  Line 372) commentsInsideChild.add(c) ==> boolean
+  Line 375) commentsToAttribute.removeAll(commentsInsideChild) ==> boolean
+  Line 376) insertCommentsInNode(child, commentsInsideChild) ==> void
+  Line 381) List<Comment> attributedComments = new LinkedList<Comment>() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 381) new LinkedList<Comment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.Comment>
+  Line 382) Comment comment ==> com.github.javaparser.ast.comments.Comment
+  Line 382) commentsToAttribute ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 384) comment.isLineComment() ==> boolean
+  Line 386) Node child ==> com.github.javaparser.ast.Node
+  Line 386) children ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 388) child.getEndLine() == comment.getBeginLine() ==> boolean
+  Line 390) attributeLineCommentToNodeOrChild(child, comment.asLineComment()) ==> boolean
+  Line 392) attributedComments.add(comment) ==> boolean
+  Line 400) Comment previousComment = null ==> com.github.javaparser.ast.comments.Comment
+  Line 400) null ==> null
+  Line 401) attributedComments = new LinkedList<Comment>() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 402) List<Node> childrenAndComments = new LinkedList<Node>() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 402) new LinkedList<Node>() ==> java.util.LinkedList<com.github.javaparser.ast.Node>
+  Line 403) childrenAndComments.addAll(children) ==> boolean
+  Line 404) childrenAndComments.addAll(commentsToAttribute) ==> boolean
+  Line 405) PositionUtils.sortByBeginPosition(childrenAndComments, _doNotConsiderAnnotationsAsNodeStartForCodeAttribution) ==> void
+  Line 407) Node thing ==> com.github.javaparser.ast.Node
+  Line 407) childrenAndComments ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 408) thing instanceof Comment ==> boolean
+  Line 409) previousComment = (Comment) thing ==> com.github.javaparser.ast.comments.Comment
+  Line 410) !previousComment.isOrphan() ==> boolean
+  Line 412) previousComment = null ==> com.github.javaparser.ast.comments.Comment
+  Line 415) previousComment != null && !thing.hasComment() ==> boolean
+  Line 416) !_doNotAssignCommentsPreceedingEmptyLines || !thereAreLinesBetween(previousComment, thing) ==> boolean
+  Line 417) thing.setComment(previousComment) ==> void
+  Line 418) attributedComments.add(previousComment) ==> boolean
+  Line 419) previousComment = null ==> com.github.javaparser.ast.comments.Comment
+  Line 425) commentsToAttribute.removeAll(attributedComments) ==> boolean
+  Line 428) Comment c ==> com.github.javaparser.ast.comments.Comment
+  Line 428) commentsToAttribute ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 429) c.isOrphan() ==> boolean
+  Line 430) node.addOrphanComment(c) ==> void
+  Line 437) !PositionUtils.areInOrder(a, b) ==> boolean
+  Line 439) thereAreLinesBetween(b, a) ==> boolean
+  Line 441) int endOfA = a.getEndLine() ==> int
+  Line 441) a.getEndLine() ==> int
+  Line 442) b.getBeginLine() > (a.getEndLine() + 1) ==> boolean
+  Line 446) CommentsParser commentsParser = new CommentsParser() ==> com.github.javaparser.ast.comments.CommentsParser
+  Line 446) new CommentsParser() ==> com.github.javaparser.ast.comments.CommentsParser
+  Line 447) CommentsCollection allComments = commentsParser.parse(code) ==> com.github.javaparser.ast.comments.CommentsCollection
+  Line 447) commentsParser.parse(code) ==> com.github.javaparser.ast.comments.CommentsCollection
+  Line 449) insertCommentsInCu(cu, allComments) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_Position.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_Position.txt
new file mode 100644
index 0000000..6e16538
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_Position.txt
@@ -0,0 +1,11 @@
+
+[ Class com.github.javaparser.Position ]
+  superclass: java.lang.Object
+  Line 30) new Position(Node.ABSOLUTE_BEGIN_LINE, -1) ==> com.github.javaparser.Position
+  Line 31) new Position(Node.ABSOLUTE_END_LINE, -1) ==> com.github.javaparser.Position
+  Line 34) new Position(node.getBeginLine(), node.getBeginColumn()) ==> com.github.javaparser.Position
+  Line 38) new Position(node.getEndLine(), node.getEndColumn()) ==> com.github.javaparser.Position
+  Line 42) this.line = line ==> int
+  Line 43) this.column = column ==> int
+  Line 47) this.line ==> int
+  Line 51) this.column ==> int
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_PositionUtils.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_PositionUtils.txt
new file mode 100644
index 0000000..c9df886
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_PositionUtils.txt
@@ -0,0 +1,68 @@
+
+[ Class com.github.javaparser.PositionUtils ]
+  superclass: java.lang.Object
+  Line 46) sortByBeginPosition(nodes, false) ==> void
+  Line 50) Collections.sort(nodes, new Comparator<Node>() {
+
+    @Override
+    public int compare(Node o1, Node o2) {
+        return PositionUtils.compare(o1, o2, ignoringAnnotations);
+    }
+}) ==> void
+  Line 53) PositionUtils.compare(o1, o2, ignoringAnnotations) ==> int
+  Line 59) areInOrder(a, b, false) ==> boolean
+  Line 63) compare(a, b, ignoringAnnotations) <= 0 ==> boolean
+  Line 67) ignoringAnnotations ==> boolean
+  Line 68) int signLine = signum(beginLineWithoutConsideringAnnotation(a) - beginLineWithoutConsideringAnnotation(b)) ==> int
+  Line 68) signum(beginLineWithoutConsideringAnnotation(a) - beginLineWithoutConsideringAnnotation(b)) ==> int
+  Line 69) signLine == 0 ==> boolean
+  Line 70) signum(beginColumnWithoutConsideringAnnotation(a) - beginColumnWithoutConsideringAnnotation(b)) ==> int
+  Line 72) signLine ==> int
+  Line 76) int signLine = signum(a.getBeginLine() - b.getBeginLine()) ==> int
+  Line 76) signum(a.getBeginLine() - b.getBeginLine()) ==> int
+  Line 77) signLine == 0 ==> boolean
+  Line 78) signum(a.getBeginColumn() - b.getBeginColumn()) ==> int
+  Line 80) signLine ==> int
+  Line 85) node instanceof AnnotableNode ==> boolean
+  Line 86) List<AnnotationExpr> annotations = new LinkedList<AnnotationExpr>() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 86) new LinkedList<AnnotationExpr>() ==> java.util.LinkedList<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 87) annotations.addAll(((AnnotableNode) node).getAnnotations()) ==> boolean
+  Line 88) annotations.size() == 0 ==> boolean
+  Line 89) null ==> null
+  Line 91) sortByBeginPosition(annotations) ==> void
+  Line 92) annotations.get(annotations.size() - 1) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 94) null ==> null
+  Line 99) beginNodeWithoutConsideringAnnotations(node).getBeginLine() ==> int
+  Line 104) beginNodeWithoutConsideringAnnotations(node).getBeginColumn() ==> int
+  Line 108) node instanceof MethodDeclaration ==> boolean
+  Line 109) MethodDeclaration casted = (MethodDeclaration) node ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 109) (MethodDeclaration) node ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 110) casted.getType() ==> com.github.javaparser.ast.type.Type
+  Line 111) node instanceof FieldDeclaration ==> boolean
+  Line 112) FieldDeclaration casted = (FieldDeclaration) node ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 112) (FieldDeclaration) node ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 113) casted.getType() ==> com.github.javaparser.ast.type.Type
+  Line 114) node instanceof ClassOrInterfaceDeclaration ==> boolean
+  Line 115) ClassOrInterfaceDeclaration casted = (ClassOrInterfaceDeclaration) node ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 115) (ClassOrInterfaceDeclaration) node ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 116) casted.getNameExpr() ==> com.github.javaparser.ast.expr.NameExpr
+  Line 118) node ==> com.github.javaparser.ast.Node
+  Line 123) !ignoringAnnotations || PositionUtils.getLastAnnotation(container) == null ==> boolean
+  Line 124) container.contains(contained) ==> boolean
+  Line 126) !container.contains(contained) ==> boolean
+  Line 127) false ==> boolean
+  Line 131) container instanceof AnnotableNode ==> boolean
+  Line 132) int bl = beginLineWithoutConsideringAnnotation(container) ==> int
+  Line 132) beginLineWithoutConsideringAnnotation(container) ==> int
+  Line 133) int bc = beginColumnWithoutConsideringAnnotation(container) ==> int
+  Line 133) beginColumnWithoutConsideringAnnotation(container) ==> int
+  Line 134) bl > contained.getBeginLine() ==> boolean
+  Line 134) false ==> boolean
+  Line 135) bl == contained.getBeginLine() && bc > contained.getBeginColumn() ==> boolean
+  Line 135) false ==> boolean
+  Line 136) container.getEndLine() < contained.getEndLine() ==> boolean
+  Line 136) false ==> boolean
+  Line 137) container.getEndLine() == contained.getEndLine() && container.getEndColumn() < contained.getEndColumn() ==> boolean
+  Line 137) false ==> boolean
+  Line 138) true ==> boolean
+  Line 140) true ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_SourcesHelper.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_SourcesHelper.txt
new file mode 100644
index 0000000..d61fa52
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_SourcesHelper.txt
@@ -0,0 +1,23 @@
+
+[ Class com.github.javaparser.SourcesHelper ]
+  superclass: java.lang.Object
+  Line 29) encoding == null ==> boolean
+  Line 30) streamToString(in) ==> java.lang.String
+  Line 32) java.util.Scanner s = new java.util.Scanner(in, encoding).useDelimiter("\\A") ==> java.util.Scanner
+  Line 32) new java.util.Scanner(in, encoding).useDelimiter("\\A") ==> java.util.Scanner
+  Line 33) s.hasNext() ? s.next() : "" ==> java.lang.String
+  Line 38) java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\A") ==> java.util.Scanner
+  Line 38) new java.util.Scanner(in).useDelimiter("\\A") ==> java.util.Scanner
+  Line 39) s.hasNext() ? s.next() : "" ==> java.lang.String
+  Line 43) byte[] rawData = encoding != null ? s.getBytes(encoding) : s.getBytes() ==> byte[]
+  Line 43) encoding != null ? s.getBytes(encoding) : s.getBytes() ==> byte[]
+  Line 44) new ByteArrayInputStream(rawData) ==> java.io.ByteArrayInputStream
+  Line 48) char[] arr = new char[8 * 1024] ==> char[]
+  Line 48) new char[8 * 1024] ==> char[]
+  Line 49) StringBuilder buf = new StringBuilder() ==> java.lang.StringBuilder
+  Line 49) new StringBuilder() ==> java.lang.StringBuilder
+  Line 50) int numChars ==> int
+  Line 52) (numChars = reader.read(arr, 0, arr.length)) > 0 ==> boolean
+  Line 53) buf.append(arr, 0, numChars) ==> java.lang.StringBuilder
+  Line 56) buf.toString() ==> java.lang.String
+  Line 60) new StringReader(s) ==> java.io.StringReader
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_AccessSpecifier.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_AccessSpecifier.txt
new file mode 100644
index 0000000..94d2571
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_AccessSpecifier.txt
@@ -0,0 +1,2 @@
+  Line 41) this.codeRepresenation = codeRepresentation ==> java.lang.String
+  Line 45) this.codeRepresenation ==> java.lang.String
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_CompilationUnit.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_CompilationUnit.txt
new file mode 100644
index 0000000..320568f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_CompilationUnit.txt
@@ -0,0 +1,28 @@
+
+[ Class com.github.javaparser.ast.CompilationUnit ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 63) setPackage(pakage) ==> void
+  Line 64) setImports(imports) ==> void
+  Line 65) setTypes(types) ==> void
+  Line 69) beginLine ==> int
+  Line 69) beginColumn ==> int
+  Line 69) endLine ==> int
+  Line 69) endColumn ==> int
+  Line 70) setPackage(pakage) ==> void
+  Line 71) setImports(imports) ==> void
+  Line 72) setTypes(types) ==> void
+  Line 77) v.visit(this, arg) ==> R
+  Line 82) v.visit(this, arg) ==> void
+  Line 98) this.getAllContainedComments() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 108) imports ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 119) pakage ==> com.github.javaparser.ast.PackageDeclaration
+  Line 133) types ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 143) new RuntimeException("Not implemented!") ==> java.lang.RuntimeException
+  Line 154) this.imports = imports ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 155) setAsParentNodeOf(this.imports) ==> void
+  Line 166) this.pakage = pakage ==> com.github.javaparser.ast.PackageDeclaration
+  Line 167) setAsParentNodeOf(this.pakage) ==> void
+  Line 177) this.types = types ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 178) setAsParentNodeOf(this.types) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_DocumentableNode.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_DocumentableNode.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_DocumentableNode.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_ImportDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_ImportDeclaration.txt
new file mode 100644
index 0000000..28ebfa8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_ImportDeclaration.txt
@@ -0,0 +1,24 @@
+
+[ Class com.github.javaparser.ast.ImportDeclaration ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 53) setAsterisk(isAsterisk) ==> void
+  Line 54) setName(name) ==> void
+  Line 55) setStatic(isStatic) ==> void
+  Line 59) beginLine ==> int
+  Line 59) beginColumn ==> int
+  Line 59) endLine ==> int
+  Line 59) endColumn ==> int
+  Line 60) setAsterisk(isAsterisk) ==> void
+  Line 61) setName(name) ==> void
+  Line 62) setStatic(isStatic) ==> void
+  Line 67) v.visit(this, arg) ==> R
+  Line 72) v.visit(this, arg) ==> void
+  Line 81) name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 91) asterisk ==> boolean
+  Line 101) static_ ==> boolean
+  Line 111) this.asterisk = asterisk ==> boolean
+  Line 121) this.name = name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 122) setAsParentNodeOf(this.name) ==> void
+  Line 132) this.static_ = static_ ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_NamedNode.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_NamedNode.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_NamedNode.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_Node.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_Node.txt
new file mode 100644
index 0000000..e6070da
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_Node.txt
@@ -0,0 +1,95 @@
+
+[ Class com.github.javaparser.ast.Node ]
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 52) new LinkedList<Node>() ==> java.util.LinkedList<com.github.javaparser.ast.Node>
+  Line 53) new LinkedList<Comment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.Comment>
+  Line 66) this.beginLine = beginLine ==> int
+  Line 67) this.beginColumn = beginColumn ==> int
+  Line 68) this.endLine = endLine ==> int
+  Line 69) this.endColumn = endColumn ==> int
+  Line 105) beginColumn ==> int
+  Line 114) beginLine ==> int
+  Line 123) comment ==> com.github.javaparser.ast.comments.Comment
+  Line 132) data ==> java.lang.Object
+  Line 141) endColumn ==> int
+  Line 150) endLine ==> int
+  Line 160) this.beginColumn = beginColumn ==> int
+  Line 170) this.beginLine = beginLine ==> int
+  Line 179) comment != null && (this instanceof Comment) ==> boolean
+  Line 180) new RuntimeException("A comment can not be commented") ==> java.lang.RuntimeException
+  Line 182) this.comment != null ==> boolean
+  Line 184) this.comment.setCommentedNode(null) ==> void
+  Line 186) this.comment = comment ==> com.github.javaparser.ast.comments.Comment
+  Line 187) comment != null ==> boolean
+  Line 188) this.comment.setCommentedNode(this) ==> void
+  Line 198) this.data = data ==> java.lang.Object
+  Line 208) this.endColumn = endColumn ==> int
+  Line 218) this.endLine = endLine ==> int
+  Line 228) final DumpVisitor visitor = new DumpVisitor() ==> com.github.javaparser.ast.visitor.DumpVisitor
+  Line 228) new DumpVisitor() ==> com.github.javaparser.ast.visitor.DumpVisitor
+  Line 229) accept(visitor, null) ==> void
+  Line 230) visitor.getSource() ==> java.lang.String
+  Line 234) final DumpVisitor visitor = new DumpVisitor(false) ==> com.github.javaparser.ast.visitor.DumpVisitor
+  Line 234) new DumpVisitor(false) ==> com.github.javaparser.ast.visitor.DumpVisitor
+  Line 235) accept(visitor, null) ==> void
+  Line 236) visitor.getSource() ==> java.lang.String
+  Line 241) toString().hashCode() ==> int
+  Line 246) obj == null || !(obj instanceof Node) ==> boolean
+  Line 247) false ==> boolean
+  Line 249) EqualsVisitor.equals(this, (Node) obj) ==> boolean
+  Line 254) this.accept(new CloneVisitor(), null) ==> com.github.javaparser.ast.Node
+  Line 258) parentNode ==> com.github.javaparser.ast.Node
+  Line 262) childrenNodes ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 266) getBeginLine() > other.getBeginLine() ==> boolean
+  Line 266) false ==> boolean
+  Line 267) getBeginLine() == other.getBeginLine() && getBeginColumn() > other.getBeginColumn() ==> boolean
+  Line 267) false ==> boolean
+  Line 268) getEndLine() < other.getEndLine() ==> boolean
+  Line 268) false ==> boolean
+  Line 269) getEndLine() == other.getEndLine() && getEndColumn() < other.getEndColumn() ==> boolean
+  Line 269) false ==> boolean
+  Line 270) true ==> boolean
+  Line 274) orphanComments.add(comment) ==> boolean
+  Line 275) comment.setParentNode(this) ==> void
+  Line 290) orphanComments ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 300) List<Comment> comments = new LinkedList<Comment>() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 300) new LinkedList<Comment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.Comment>
+  Line 301) comments.addAll(getOrphanComments()) ==> boolean
+  Line 303) Node child ==> com.github.javaparser.ast.Node
+  Line 303) getChildrenNodes() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 304) child.getComment() != null ==> boolean
+  Line 305) comments.add(child.getComment()) ==> boolean
+  Line 307) comments.addAll(child.getAllContainedComments()) ==> boolean
+  Line 310) comments ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 321) this.parentNode != null ==> boolean
+  Line 322) this.parentNode.childrenNodes.remove(this) ==> boolean
+  Line 324) this.parentNode = parentNode ==> com.github.javaparser.ast.Node
+  Line 326) this.parentNode != null ==> boolean
+  Line 327) this.parentNode.childrenNodes.add(this) ==> boolean
+  Line 332) childNodes != null ==> boolean
+  Line 333) Iterator<? extends Node> it = childNodes.iterator() ==> java.util.Iterator<? extends com.github.javaparser.ast.Node>
+  Line 333) childNodes.iterator() ==> java.util.Iterator<? extends com.github.javaparser.ast.Node>
+  Line 334) it.hasNext() ==> boolean
+  Line 335) Node current = it.next() ==> com.github.javaparser.ast.Node
+  Line 335) it.next() ==> ? extends com.github.javaparser.ast.Node
+  Line 336) current.setParentNode(this) ==> void
+  Line 342) childNode != null ==> boolean
+  Line 343) childNode.setParentNode(this) ==> void
+  Line 347) -1 ==> int
+  Line 348) -2 ==> int
+  Line 351) line == ABSOLUTE_BEGIN_LINE ==> boolean
+  Line 351) true ==> boolean
+  Line 352) getBeginLine() > line ==> boolean
+  Line 353) true ==> boolean
+  Line 354) getBeginLine() == line ==> boolean
+  Line 355) getBeginColumn() > column ==> boolean
+  Line 357) false ==> boolean
+  Line 362) line == ABSOLUTE_END_LINE ==> boolean
+  Line 362) true ==> boolean
+  Line 363) getEndLine() < line ==> boolean
+  Line 364) true ==> boolean
+  Line 365) getEndLine() == line ==> boolean
+  Line 366) getEndColumn() < column ==> boolean
+  Line 368) false ==> boolean
+  Line 374) comment != null ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_PackageDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_PackageDeclaration.txt
new file mode 100644
index 0000000..a6ccfcd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_PackageDeclaration.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.PackageDeclaration ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 54) setName(name) ==> void
+  Line 58) setAnnotations(annotations) ==> void
+  Line 59) setName(name) ==> void
+  Line 63) beginLine ==> int
+  Line 63) beginColumn ==> int
+  Line 63) endLine ==> int
+  Line 63) endColumn ==> int
+  Line 64) setAnnotations(annotations) ==> void
+  Line 65) setName(name) ==> void
+  Line 70) v.visit(this, arg) ==> R
+  Line 75) v.visit(this, arg) ==> void
+  Line 85) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 94) name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 102) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 103) setAsParentNodeOf(this.annotations) ==> void
+  Line 113) this.name = name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 114) setAsParentNodeOf(this.name) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_TreeVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_TreeVisitor.txt
new file mode 100644
index 0000000..dfb295e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_TreeVisitor.txt
@@ -0,0 +1,7 @@
+
+[ Class com.github.javaparser.ast.TreeVisitor ]
+  superclass: java.lang.Object
+  Line 27) process(node) ==> void
+  Line 28) Node child ==> com.github.javaparser.ast.Node
+  Line 28) node.getChildrenNodes() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 29) visitDepthFirst(child) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_TypeParameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_TypeParameter.txt
new file mode 100644
index 0000000..159adf0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_TypeParameter.txt
@@ -0,0 +1,32 @@
+
+[ Class com.github.javaparser.ast.TypeParameter ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  Line 55) setName(name) ==> void
+  Line 56) setTypeBound(typeBound) ==> void
+  Line 61) beginLine ==> int
+  Line 61) beginColumn ==> int
+  Line 61) endLine ==> int
+  Line 61) endColumn ==> int
+  Line 62) setName(name) ==> void
+  Line 63) setTypeBound(typeBound) ==> void
+  Line 68) beginLine ==> int
+  Line 68) beginColumn ==> int
+  Line 68) endLine ==> int
+  Line 68) endColumn ==> int
+  Line 68) name ==> java.lang.String
+  Line 68) typeBound ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 69) setName(name) ==> void
+  Line 70) setTypeBound(typeBound) ==> void
+  Line 71) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 75) v.visit(this, arg) ==> R
+  Line 79) v.visit(this, arg) ==> void
+  Line 88) name ==> java.lang.String
+  Line 98) typeBound ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 108) this.name = name ==> java.lang.String
+  Line 118) this.typeBound = typeBound ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 119) setAsParentNodeOf(typeBound) ==> void
+  Line 123) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 127) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotableNode.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotableNode.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotableNode.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotationDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotationDeclaration.txt
new file mode 100644
index 0000000..f68d9dd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotationDeclaration.txt
@@ -0,0 +1,28 @@
+
+[ Class com.github.javaparser.ast.body.AnnotationDeclaration ]
+  superclass: com.github.javaparser.ast.body.TypeDeclaration
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  interface: com.github.javaparser.ast.NamedNode
+  Line 41) modifiers ==> int
+  Line 41) name ==> java.lang.String
+  Line 45) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 45) modifiers ==> int
+  Line 45) name ==> java.lang.String
+  Line 45) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 49) beginLine ==> int
+  Line 49) beginColumn ==> int
+  Line 49) endLine ==> int
+  Line 49) endColumn ==> int
+  Line 49) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 49) modifiers ==> int
+  Line 49) name ==> java.lang.String
+  Line 49) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 54) v.visit(this, arg) ==> R
+  Line 59) v.visit(this, arg) ==> void
+  Line 64) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 69) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotationMemberDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotationMemberDeclaration.txt
new file mode 100644
index 0000000..9376579
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_AnnotationMemberDeclaration.txt
@@ -0,0 +1,41 @@
+
+[ Class com.github.javaparser.ast.body.AnnotationMemberDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 52) setModifiers(modifiers) ==> void
+  Line 53) setType(type) ==> void
+  Line 54) setName(name) ==> void
+  Line 55) setDefaultValue(defaultValue) ==> void
+  Line 59) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 60) setModifiers(modifiers) ==> void
+  Line 61) setType(type) ==> void
+  Line 62) setName(name) ==> void
+  Line 63) setDefaultValue(defaultValue) ==> void
+  Line 67) beginLine ==> int
+  Line 67) beginColumn ==> int
+  Line 67) endLine ==> int
+  Line 67) endColumn ==> int
+  Line 67) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 68) setModifiers(modifiers) ==> void
+  Line 69) setType(type) ==> void
+  Line 70) setName(name) ==> void
+  Line 71) setDefaultValue(defaultValue) ==> void
+  Line 76) v.visit(this, arg) ==> R
+  Line 81) v.visit(this, arg) ==> void
+  Line 85) defaultValue ==> com.github.javaparser.ast.expr.Expression
+  Line 95) modifiers ==> int
+  Line 99) name ==> java.lang.String
+  Line 103) type ==> com.github.javaparser.ast.type.Type
+  Line 107) this.defaultValue = defaultValue ==> com.github.javaparser.ast.expr.Expression
+  Line 108) setAsParentNodeOf(defaultValue) ==> void
+  Line 112) this.modifiers = modifiers ==> int
+  Line 116) this.name = name ==> java.lang.String
+  Line 120) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 121) setAsParentNodeOf(type) ==> void
+  Line 126) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 131) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_BaseParameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_BaseParameter.txt
new file mode 100644
index 0000000..57f8ed2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_BaseParameter.txt
@@ -0,0 +1,26 @@
+
+[ Class com.github.javaparser.ast.body.BaseParameter ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) setId(id) ==> void
+  Line 44) setModifiers(modifiers) ==> void
+  Line 45) setId(id) ==> void
+  Line 49) setModifiers(modifiers) ==> void
+  Line 50) setAnnotations(annotations) ==> void
+  Line 51) setId(id) ==> void
+  Line 55) beginLine ==> int
+  Line 55) beginColumn ==> int
+  Line 55) endLine ==> int
+  Line 55) endColumn ==> int
+  Line 56) setModifiers(modifiers) ==> void
+  Line 57) setAnnotations(annotations) ==> void
+  Line 58) setId(id) ==> void
+  Line 62) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 66) id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 76) modifiers ==> int
+  Line 80) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 81) setAsParentNodeOf(this.annotations) ==> void
+  Line 85) this.id = id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 86) setAsParentNodeOf(this.id) ==> void
+  Line 90) this.modifiers = modifiers ==> int
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_BodyDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_BodyDeclaration.txt
new file mode 100644
index 0000000..577b700
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_BodyDeclaration.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.body.BodyDeclaration ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  interface: java.lang.Cloneable
+  Line 41) setAnnotations(annotations) ==> void
+  Line 45) beginLine ==> int
+  Line 45) beginColumn ==> int
+  Line 45) endLine ==> int
+  Line 45) endColumn ==> int
+  Line 46) setAnnotations(annotations) ==> void
+  Line 50) annotations == null ==> boolean
+  Line 51) annotations = new ArrayList<AnnotationExpr>() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 53) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 57) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 58) setAsParentNodeOf(this.annotations) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ClassOrInterfaceDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ClassOrInterfaceDeclaration.txt
new file mode 100644
index 0000000..2882229
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ClassOrInterfaceDeclaration.txt
@@ -0,0 +1,48 @@
+
+[ Class com.github.javaparser.ast.body.ClassOrInterfaceDeclaration ]
+  superclass: com.github.javaparser.ast.body.TypeDeclaration
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  interface: com.github.javaparser.ast.NamedNode
+  Line 52) modifiers ==> int
+  Line 52) name ==> java.lang.String
+  Line 53) setInterface(isInterface) ==> void
+  Line 60) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 60) modifiers ==> int
+  Line 60) name ==> java.lang.String
+  Line 60) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 61) setInterface(isInterface) ==> void
+  Line 62) setTypeParameters(typeParameters) ==> void
+  Line 63) setExtends(extendsList) ==> void
+  Line 64) setImplements(implementsList) ==> void
+  Line 72) beginLine ==> int
+  Line 72) beginColumn ==> int
+  Line 72) endLine ==> int
+  Line 72) endColumn ==> int
+  Line 72) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 72) modifiers ==> int
+  Line 72) name ==> java.lang.String
+  Line 72) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 73) setInterface(isInterface) ==> void
+  Line 74) setTypeParameters(typeParameters) ==> void
+  Line 75) setExtends(extendsList) ==> void
+  Line 76) setImplements(implementsList) ==> void
+  Line 80) v.visit(this, arg) ==> R
+  Line 84) v.visit(this, arg) ==> void
+  Line 88) extendsList ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 92) implementsList ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 96) typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 100) interface_ ==> boolean
+  Line 104) this.extendsList = extendsList ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 105) setAsParentNodeOf(this.extendsList) ==> void
+  Line 109) this.implementsList = implementsList ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 110) setAsParentNodeOf(this.implementsList) ==> void
+  Line 114) this.interface_ = interface_ ==> boolean
+  Line 118) this.typeParameters = typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 119) setAsParentNodeOf(this.typeParameters) ==> void
+  Line 124) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 129) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ConstructorDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ConstructorDeclaration.txt
new file mode 100644
index 0000000..187757a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ConstructorDeclaration.txt
@@ -0,0 +1,89 @@
+
+[ Class com.github.javaparser.ast.body.ConstructorDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: com.github.javaparser.ast.body.WithDeclaration
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 60) setModifiers(modifiers) ==> void
+  Line 61) setName(name) ==> void
+  Line 66) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 67) setModifiers(modifiers) ==> void
+  Line 68) setTypeParameters(typeParameters) ==> void
+  Line 69) setName(name) ==> void
+  Line 70) setParameters(parameters) ==> void
+  Line 71) setThrows(throws_) ==> void
+  Line 72) setBlock(block) ==> void
+  Line 78) beginLine ==> int
+  Line 78) beginColumn ==> int
+  Line 78) endLine ==> int
+  Line 78) endColumn ==> int
+  Line 78) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 79) setModifiers(modifiers) ==> void
+  Line 80) setTypeParameters(typeParameters) ==> void
+  Line 81) setName(name) ==> void
+  Line 82) setParameters(parameters) ==> void
+  Line 83) setThrows(throws_) ==> void
+  Line 84) setBlock(block) ==> void
+  Line 89) v.visit(this, arg) ==> R
+  Line 94) v.visit(this, arg) ==> void
+  Line 98) block ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 108) modifiers ==> int
+  Line 112) name == null ? null : name.getName() ==> null
+  Line 116) name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 120) parameters == null ==> boolean
+  Line 121) parameters = new ArrayList<Parameter>() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 123) parameters ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 127) throws_ == null ==> boolean
+  Line 128) throws_ = new ArrayList<NameExpr>() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 130) throws_ ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 134) typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 138) this.block = block ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 139) setAsParentNodeOf(this.block) ==> void
+  Line 143) this.modifiers = modifiers ==> int
+  Line 147) this.name = new NameExpr(name) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 151) this.name = name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 155) this.parameters = parameters ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 156) setAsParentNodeOf(this.parameters) ==> void
+  Line 160) this.throws_ = throws_ ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 161) setAsParentNodeOf(this.throws_) ==> void
+  Line 165) this.typeParameters = typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 166) setAsParentNodeOf(this.typeParameters) ==> void
+  Line 178) StringBuffer sb = new StringBuffer() ==> java.lang.StringBuffer
+  Line 178) new StringBuffer() ==> java.lang.StringBuffer
+  Line 179) includingModifiers ==> boolean
+  Line 180) AccessSpecifier accessSpecifier = ModifierSet.getAccessSpecifier(getModifiers()) ==> com.github.javaparser.ast.AccessSpecifier
+  Line 180) ModifierSet.getAccessSpecifier(getModifiers()) ==> com.github.javaparser.ast.AccessSpecifier
+  Line 181) sb.append(accessSpecifier.getCodeRepresenation()) ==> java.lang.StringBuffer
+  Line 182) sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ") ==> java.lang.StringBuffer
+  Line 184) sb.append(getName()) ==> java.lang.StringBuffer
+  Line 185) sb.append("(") ==> java.lang.StringBuffer
+  Line 186) boolean firstParam = true ==> boolean
+  Line 186) true ==> boolean
+  Line 187) Parameter param ==> com.github.javaparser.ast.body.Parameter
+  Line 187) getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 189) firstParam ==> boolean
+  Line 190) firstParam = false ==> boolean
+  Line 192) sb.append(", ") ==> java.lang.StringBuffer
+  Line 194) includingParameterName ==> boolean
+  Line 195) sb.append(param.toStringWithoutComments()) ==> java.lang.StringBuffer
+  Line 197) sb.append(param.getType().toStringWithoutComments()) ==> java.lang.StringBuffer
+  Line 200) sb.append(")") ==> java.lang.StringBuffer
+  Line 201) includingThrows ==> boolean
+  Line 202) boolean firstThrow = true ==> boolean
+  Line 202) true ==> boolean
+  Line 203) NameExpr thr ==> com.github.javaparser.ast.expr.NameExpr
+  Line 203) getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 204) firstThrow ==> boolean
+  Line 205) firstThrow = false ==> boolean
+  Line 206) sb.append(" throws ") ==> java.lang.StringBuffer
+  Line 208) sb.append(", ") ==> java.lang.StringBuffer
+  Line 210) sb.append(thr.toStringWithoutComments()) ==> java.lang.StringBuffer
+  Line 213) sb.toString() ==> java.lang.String
+  Line 218) getDeclarationAsString(includingModifiers, includingThrows, true) ==> java.lang.String
+  Line 223) getDeclarationAsString(true, true, true) ==> java.lang.String
+  Line 228) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 233) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EmptyMemberDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EmptyMemberDeclaration.txt
new file mode 100644
index 0000000..8e2d00b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EmptyMemberDeclaration.txt
@@ -0,0 +1,18 @@
+
+[ Class com.github.javaparser.ast.body.EmptyMemberDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 35) null ==> null
+  Line 39) beginLine ==> int
+  Line 39) beginColumn ==> int
+  Line 39) endLine ==> int
+  Line 39) endColumn ==> int
+  Line 39) null ==> null
+  Line 44) v.visit(this, arg) ==> R
+  Line 49) v.visit(this, arg) ==> void
+  Line 54) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 59) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EmptyTypeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EmptyTypeDeclaration.txt
new file mode 100644
index 0000000..d85d12b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EmptyTypeDeclaration.txt
@@ -0,0 +1,25 @@
+
+[ Class com.github.javaparser.ast.body.EmptyTypeDeclaration ]
+  superclass: com.github.javaparser.ast.body.TypeDeclaration
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  interface: com.github.javaparser.ast.NamedNode
+  Line 35) null ==> null
+  Line 35) 0 ==> int
+  Line 35) null ==> null
+  Line 35) null ==> null
+  Line 39) beginLine ==> int
+  Line 39) beginColumn ==> int
+  Line 39) endLine ==> int
+  Line 39) endColumn ==> int
+  Line 39) null ==> null
+  Line 39) 0 ==> int
+  Line 39) null ==> null
+  Line 39) null ==> null
+  Line 44) v.visit(this, arg) ==> R
+  Line 54) v.visit(this, arg) ==> void
+  Line 59) null ==> null
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EnumConstantDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EnumConstantDeclaration.txt
new file mode 100644
index 0000000..045f010
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EnumConstantDeclaration.txt
@@ -0,0 +1,34 @@
+
+[ Class com.github.javaparser.ast.body.EnumConstantDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 49) setName(name) ==> void
+  Line 53) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 54) setName(name) ==> void
+  Line 55) setArgs(args) ==> void
+  Line 56) setClassBody(classBody) ==> void
+  Line 60) beginLine ==> int
+  Line 60) beginColumn ==> int
+  Line 60) endLine ==> int
+  Line 60) endColumn ==> int
+  Line 60) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 61) setName(name) ==> void
+  Line 62) setArgs(args) ==> void
+  Line 63) setClassBody(classBody) ==> void
+  Line 68) v.visit(this, arg) ==> R
+  Line 73) v.visit(this, arg) ==> void
+  Line 77) args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 81) classBody ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 85) name ==> java.lang.String
+  Line 89) this.args = args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 90) setAsParentNodeOf(this.args) ==> void
+  Line 94) this.classBody = classBody ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 95) setAsParentNodeOf(this.classBody) ==> void
+  Line 99) this.name = name ==> java.lang.String
+  Line 104) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 109) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EnumDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EnumDeclaration.txt
new file mode 100644
index 0000000..0a26913
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_EnumDeclaration.txt
@@ -0,0 +1,38 @@
+
+[ Class com.github.javaparser.ast.body.EnumDeclaration ]
+  superclass: com.github.javaparser.ast.body.TypeDeclaration
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  interface: com.github.javaparser.ast.NamedNode
+  Line 46) modifiers ==> int
+  Line 46) name ==> java.lang.String
+  Line 50) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 50) modifiers ==> int
+  Line 50) name ==> java.lang.String
+  Line 50) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 51) setImplements(implementsList) ==> void
+  Line 52) setEntries(entries) ==> void
+  Line 56) beginLine ==> int
+  Line 56) beginColumn ==> int
+  Line 56) endLine ==> int
+  Line 56) endColumn ==> int
+  Line 56) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 56) modifiers ==> int
+  Line 56) name ==> java.lang.String
+  Line 56) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 57) setImplements(implementsList) ==> void
+  Line 58) setEntries(entries) ==> void
+  Line 63) v.visit(this, arg) ==> R
+  Line 69) v.visit(this, arg) ==> void
+  Line 73) entries ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 77) implementsList ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 81) this.entries = entries ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 82) setAsParentNodeOf(this.entries) ==> void
+  Line 86) this.implementsList = implementsList ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 87) setAsParentNodeOf(this.implementsList) ==> void
+  Line 92) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 97) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_FieldDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_FieldDeclaration.txt
new file mode 100644
index 0000000..bfb7f72
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_FieldDeclaration.txt
@@ -0,0 +1,41 @@
+
+[ Class com.github.javaparser.ast.body.FieldDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 49) setModifiers(modifiers) ==> void
+  Line 50) setType(type) ==> void
+  Line 51) List<VariableDeclarator> aux = new ArrayList<VariableDeclarator>() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 51) new ArrayList<VariableDeclarator>() ==> java.util.ArrayList<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 52) aux.add(variable) ==> boolean
+  Line 53) setVariables(aux) ==> void
+  Line 57) setModifiers(modifiers) ==> void
+  Line 58) setType(type) ==> void
+  Line 59) setVariables(variables) ==> void
+  Line 63) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 64) setModifiers(modifiers) ==> void
+  Line 65) setType(type) ==> void
+  Line 66) setVariables(variables) ==> void
+  Line 70) beginLine ==> int
+  Line 70) beginColumn ==> int
+  Line 70) endLine ==> int
+  Line 70) endColumn ==> int
+  Line 70) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 71) setModifiers(modifiers) ==> void
+  Line 72) setType(type) ==> void
+  Line 73) setVariables(variables) ==> void
+  Line 78) v.visit(this, arg) ==> R
+  Line 83) v.visit(this, arg) ==> void
+  Line 93) modifiers ==> int
+  Line 97) type ==> com.github.javaparser.ast.type.Type
+  Line 101) variables ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 105) this.modifiers = modifiers ==> int
+  Line 109) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 110) setAsParentNodeOf(this.type) ==> void
+  Line 114) this.variables = variables ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 115) setAsParentNodeOf(this.variables) ==> void
+  Line 120) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 125) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_InitializerDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_InitializerDeclaration.txt
new file mode 100644
index 0000000..d433226
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_InitializerDeclaration.txt
@@ -0,0 +1,27 @@
+
+[ Class com.github.javaparser.ast.body.InitializerDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 43) null ==> null
+  Line 44) setStatic(isStatic) ==> void
+  Line 45) setBlock(block) ==> void
+  Line 49) beginLine ==> int
+  Line 49) beginColumn ==> int
+  Line 49) endLine ==> int
+  Line 49) endColumn ==> int
+  Line 49) null ==> null
+  Line 50) setStatic(isStatic) ==> void
+  Line 51) setBlock(block) ==> void
+  Line 56) v.visit(this, arg) ==> R
+  Line 61) v.visit(this, arg) ==> void
+  Line 65) block ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 69) isStatic ==> boolean
+  Line 73) this.block = block ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 74) setAsParentNodeOf(this.block) ==> void
+  Line 78) this.isStatic = isStatic ==> boolean
+  Line 83) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 88) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_MethodDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_MethodDeclaration.txt
new file mode 100644
index 0000000..4d7faf9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_MethodDeclaration.txt
@@ -0,0 +1,120 @@
+
+[ Class com.github.javaparser.ast.body.MethodDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.DocumentableNode
+  interface: com.github.javaparser.ast.body.WithDeclaration
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 60) false ==> boolean
+  Line 66) setModifiers(modifiers) ==> void
+  Line 67) setType(type) ==> void
+  Line 68) setName(name) ==> void
+  Line 72) setModifiers(modifiers) ==> void
+  Line 73) setType(type) ==> void
+  Line 74) setName(name) ==> void
+  Line 75) setParameters(parameters) ==> void
+  Line 81) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 82) setModifiers(modifiers) ==> void
+  Line 83) setTypeParameters(typeParameters) ==> void
+  Line 84) setType(type) ==> void
+  Line 85) setName(name) ==> void
+  Line 86) setParameters(parameters) ==> void
+  Line 87) setArrayCount(arrayCount) ==> void
+  Line 88) setThrows(throws_) ==> void
+  Line 89) setBody(block) ==> void
+  Line 96) beginLine ==> int
+  Line 96) beginColumn ==> int
+  Line 96) endLine ==> int
+  Line 96) endColumn ==> int
+  Line 96) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 97) setModifiers(modifiers) ==> void
+  Line 98) setTypeParameters(typeParameters) ==> void
+  Line 99) setType(type) ==> void
+  Line 100) setName(name) ==> void
+  Line 101) setParameters(parameters) ==> void
+  Line 102) setArrayCount(arrayCount) ==> void
+  Line 103) setThrows(throws_) ==> void
+  Line 104) setBody(block) ==> void
+  Line 108) v.visit(this, arg) ==> R
+  Line 112) v.visit(this, arg) ==> void
+  Line 116) arrayCount ==> int
+  Line 121) body ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 131) modifiers ==> int
+  Line 135) name.getName() ==> java.lang.String
+  Line 139) name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 143) parameters == null ==> boolean
+  Line 144) parameters = new ArrayList<Parameter>() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 146) parameters ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 150) throws_ == null ==> boolean
+  Line 151) throws_ = new ArrayList<NameExpr>() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 153) throws_ ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 157) type ==> com.github.javaparser.ast.type.Type
+  Line 161) typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 165) this.arrayCount = arrayCount ==> int
+  Line 169) this.body = body ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 170) setAsParentNodeOf(this.body) ==> void
+  Line 174) this.modifiers = modifiers ==> int
+  Line 178) this.name = new NameExpr(name) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 182) this.name = name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 186) this.parameters = parameters ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 187) setAsParentNodeOf(this.parameters) ==> void
+  Line 191) this.throws_ = throws_ ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 192) setAsParentNodeOf(this.throws_) ==> void
+  Line 196) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 197) setAsParentNodeOf(this.type) ==> void
+  Line 201) this.typeParameters = typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 202) setAsParentNodeOf(typeParameters) ==> void
+  Line 207) isDefault ==> boolean
+  Line 211) this.isDefault = isDefault ==> boolean
+  Line 217) getDeclarationAsString(true, true, true) ==> java.lang.String
+  Line 222) getDeclarationAsString(includingModifiers, includingThrows, true) ==> java.lang.String
+  Line 235) StringBuffer sb = new StringBuffer() ==> java.lang.StringBuffer
+  Line 235) new StringBuffer() ==> java.lang.StringBuffer
+  Line 236) includingModifiers ==> boolean
+  Line 237) AccessSpecifier accessSpecifier = ModifierSet.getAccessSpecifier(getModifiers()) ==> com.github.javaparser.ast.AccessSpecifier
+  Line 237) ModifierSet.getAccessSpecifier(getModifiers()) ==> com.github.javaparser.ast.AccessSpecifier
+  Line 238) sb.append(accessSpecifier.getCodeRepresenation()) ==> java.lang.StringBuffer
+  Line 239) sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ") ==> java.lang.StringBuffer
+  Line 240) ModifierSet.isStatic(getModifiers()) ==> boolean
+  Line 241) sb.append("static ") ==> java.lang.StringBuffer
+  Line 243) ModifierSet.isAbstract(getModifiers()) ==> boolean
+  Line 244) sb.append("abstract ") ==> java.lang.StringBuffer
+  Line 246) ModifierSet.isFinal(getModifiers()) ==> boolean
+  Line 247) sb.append("final ") ==> java.lang.StringBuffer
+  Line 249) ModifierSet.isNative(getModifiers()) ==> boolean
+  Line 250) sb.append("native ") ==> java.lang.StringBuffer
+  Line 252) ModifierSet.isSynchronized(getModifiers()) ==> boolean
+  Line 253) sb.append("synchronized ") ==> java.lang.StringBuffer
+  Line 257) sb.append(getType().toStringWithoutComments()) ==> java.lang.StringBuffer
+  Line 258) sb.append(" ") ==> java.lang.StringBuffer
+  Line 259) sb.append(getName()) ==> java.lang.StringBuffer
+  Line 260) sb.append("(") ==> java.lang.StringBuffer
+  Line 261) boolean firstParam = true ==> boolean
+  Line 261) true ==> boolean
+  Line 262) Parameter param ==> com.github.javaparser.ast.body.Parameter
+  Line 262) getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 264) firstParam ==> boolean
+  Line 265) firstParam = false ==> boolean
+  Line 267) sb.append(", ") ==> java.lang.StringBuffer
+  Line 269) includingParameterName ==> boolean
+  Line 270) sb.append(param.toStringWithoutComments()) ==> java.lang.StringBuffer
+  Line 272) sb.append(param.getType().toStringWithoutComments()) ==> java.lang.StringBuffer
+  Line 273) param.isVarArgs() ==> boolean
+  Line 274) sb.append("...") ==> java.lang.StringBuffer
+  Line 278) sb.append(")") ==> java.lang.StringBuffer
+  Line 279) includingThrows ==> boolean
+  Line 280) boolean firstThrow = true ==> boolean
+  Line 280) true ==> boolean
+  Line 281) NameExpr thr ==> com.github.javaparser.ast.expr.NameExpr
+  Line 281) getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 282) firstThrow ==> boolean
+  Line 283) firstThrow = false ==> boolean
+  Line 284) sb.append(" throws ") ==> java.lang.StringBuffer
+  Line 286) sb.append(", ") ==> java.lang.StringBuffer
+  Line 288) sb.append(thr.toStringWithoutComments()) ==> java.lang.StringBuffer
+  Line 291) sb.toString() ==> java.lang.String
+  Line 296) this.javadocComment = javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 301) javadocComment ==> com.github.javaparser.ast.comments.JavadocComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ModifierSet.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ModifierSet.txt
new file mode 100644
index 0000000..382c1fb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_ModifierSet.txt
@@ -0,0 +1,36 @@
+
+[ Class com.github.javaparser.ast.body.ModifierSet ]
+  superclass: java.lang.Object
+  Line 37) Modifier.PUBLIC ==> int
+  Line 39) Modifier.PRIVATE ==> int
+  Line 41) Modifier.PROTECTED ==> int
+  Line 43) Modifier.STATIC ==> int
+  Line 45) Modifier.FINAL ==> int
+  Line 47) Modifier.SYNCHRONIZED ==> int
+  Line 49) Modifier.VOLATILE ==> int
+  Line 51) Modifier.TRANSIENT ==> int
+  Line 53) Modifier.NATIVE ==> int
+  Line 55) Modifier.ABSTRACT ==> int
+  Line 57) Modifier.STRICT ==> int
+  Line 60) isPublic(modifiers) ==> boolean
+  Line 61) AccessSpecifier.PUBLIC ==> com.github.javaparser.ast.AccessSpecifier
+  Line 62) isProtected(modifiers) ==> boolean
+  Line 63) AccessSpecifier.PROTECTED ==> com.github.javaparser.ast.AccessSpecifier
+  Line 64) isPrivate(modifiers) ==> boolean
+  Line 65) AccessSpecifier.PRIVATE ==> com.github.javaparser.ast.AccessSpecifier
+  Line 67) AccessSpecifier.DEFAULT ==> com.github.javaparser.ast.AccessSpecifier
+  Line 72) modifiers | mod ==> int
+  Line 76) (modifiers & modifier) != 0 ==> boolean
+  Line 80) (modifiers & ABSTRACT) != 0 ==> boolean
+  Line 84) (modifiers & FINAL) != 0 ==> boolean
+  Line 88) (modifiers & NATIVE) != 0 ==> boolean
+  Line 92) (modifiers & PRIVATE) != 0 ==> boolean
+  Line 96) (modifiers & PROTECTED) != 0 ==> boolean
+  Line 107) !isPublic(modifiers) && !isProtected(modifiers) && !isPrivate(modifiers) ==> boolean
+  Line 111) (modifiers & PUBLIC) != 0 ==> boolean
+  Line 115) (modifiers & STATIC) != 0 ==> boolean
+  Line 119) (modifiers & STRICTFP) != 0 ==> boolean
+  Line 123) (modifiers & SYNCHRONIZED) != 0 ==> boolean
+  Line 127) (modifiers & TRANSIENT) != 0 ==> boolean
+  Line 131) (modifiers & VOLATILE) != 0 ==> boolean
+  Line 141) modifiers & ~mod ==> int
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_MultiTypeParameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_MultiTypeParameter.txt
new file mode 100644
index 0000000..8e46971
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_MultiTypeParameter.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.body.MultiTypeParameter ]
+  superclass: com.github.javaparser.ast.body.BaseParameter
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 37) modifiers ==> int
+  Line 37) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 37) id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 38) this.types = types ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 42) beginLine ==> int
+  Line 42) beginColumn ==> int
+  Line 42) endLine ==> int
+  Line 42) endColumn ==> int
+  Line 42) modifiers ==> int
+  Line 42) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 42) id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 43) this.types = types ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 48) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) types ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 61) this.types = types ==> java.util.List<com.github.javaparser.ast.type.Type>
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_Parameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_Parameter.txt
new file mode 100644
index 0000000..203748a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_Parameter.txt
@@ -0,0 +1,27 @@
+
+[ Class com.github.javaparser.ast.body.Parameter ]
+  superclass: com.github.javaparser.ast.body.BaseParameter
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 43) id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 44) setType(type) ==> void
+  Line 48) modifiers ==> int
+  Line 48) id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 49) setType(type) ==> void
+  Line 53) beginLine ==> int
+  Line 53) beginColumn ==> int
+  Line 53) endLine ==> int
+  Line 53) endColumn ==> int
+  Line 53) modifiers ==> int
+  Line 53) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 53) id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 54) setType(type) ==> void
+  Line 55) setVarArgs(isVarArgs) ==> void
+  Line 60) v.visit(this, arg) ==> R
+  Line 65) v.visit(this, arg) ==> void
+  Line 69) type ==> com.github.javaparser.ast.type.Type
+  Line 73) isVarArgs ==> boolean
+  Line 77) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 78) setAsParentNodeOf(this.type) ==> void
+  Line 82) this.isVarArgs = isVarArgs ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_TypeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_TypeDeclaration.txt
new file mode 100644
index 0000000..98afdae
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_TypeDeclaration.txt
@@ -0,0 +1,31 @@
+
+[ Class com.github.javaparser.ast.body.TypeDeclaration ]
+  superclass: com.github.javaparser.ast.body.BodyDeclaration
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.body.AnnotableNode
+  Line 45) setName(name) ==> void
+  Line 46) setModifiers(modifiers) ==> void
+  Line 52) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 53) setName(name) ==> void
+  Line 54) setModifiers(modifiers) ==> void
+  Line 55) setMembers(members) ==> void
+  Line 62) beginLine ==> int
+  Line 62) beginColumn ==> int
+  Line 62) endLine ==> int
+  Line 62) endColumn ==> int
+  Line 62) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 63) setName(name) ==> void
+  Line 64) setModifiers(modifiers) ==> void
+  Line 65) setMembers(members) ==> void
+  Line 69) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 79) modifiers ==> int
+  Line 83) name.getName() ==> java.lang.String
+  Line 87) this.members = members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 88) setAsParentNodeOf(this.members) ==> void
+  Line 92) this.modifiers = modifiers ==> int
+  Line 96) this.name = new NameExpr(name) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 100) this.name = nameExpr ==> com.github.javaparser.ast.expr.NameExpr
+  Line 104) name ==> com.github.javaparser.ast.expr.NameExpr
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_VariableDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_VariableDeclarator.txt
new file mode 100644
index 0000000..19f272a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_VariableDeclarator.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.body.VariableDeclarator ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 42) setId(id) ==> void
+  Line 46) setId(id) ==> void
+  Line 47) setInit(init) ==> void
+  Line 51) beginLine ==> int
+  Line 51) beginColumn ==> int
+  Line 51) endLine ==> int
+  Line 51) endColumn ==> int
+  Line 52) setId(id) ==> void
+  Line 53) setInit(init) ==> void
+  Line 58) v.visit(this, arg) ==> R
+  Line 63) v.visit(this, arg) ==> void
+  Line 67) id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 71) init ==> com.github.javaparser.ast.expr.Expression
+  Line 75) this.id = id ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 76) setAsParentNodeOf(this.id) ==> void
+  Line 80) this.init = init ==> com.github.javaparser.ast.expr.Expression
+  Line 81) setAsParentNodeOf(this.init) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_VariableDeclaratorId.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_VariableDeclaratorId.txt
new file mode 100644
index 0000000..1a41406
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_VariableDeclaratorId.txt
@@ -0,0 +1,19 @@
+
+[ Class com.github.javaparser.ast.body.VariableDeclaratorId ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  Line 42) setName(name) ==> void
+  Line 46) beginLine ==> int
+  Line 46) beginColumn ==> int
+  Line 46) endLine ==> int
+  Line 46) endColumn ==> int
+  Line 47) setName(name) ==> void
+  Line 48) setArrayCount(arrayCount) ==> void
+  Line 53) v.visit(this, arg) ==> R
+  Line 58) v.visit(this, arg) ==> void
+  Line 62) arrayCount ==> int
+  Line 66) name ==> java.lang.String
+  Line 70) this.arrayCount = arrayCount ==> int
+  Line 74) this.name = name ==> java.lang.String
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_WithDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_WithDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_body_WithDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_BlockComment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_BlockComment.txt
new file mode 100644
index 0000000..22c9f0d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_BlockComment.txt
@@ -0,0 +1,14 @@
+
+[ Class com.github.javaparser.ast.comments.BlockComment ]
+  superclass: com.github.javaparser.ast.comments.Comment
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 42) content ==> java.lang.String
+  Line 46) beginLine ==> int
+  Line 46) beginColumn ==> int
+  Line 46) endLine ==> int
+  Line 46) endColumn ==> int
+  Line 46) content ==> java.lang.String
+  Line 51) v.visit(this, arg) ==> R
+  Line 56) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_Comment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_Comment.txt
new file mode 100644
index 0000000..1fcb0bc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_Comment.txt
@@ -0,0 +1,26 @@
+
+[ Class com.github.javaparser.ast.comments.Comment ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 43) this.content = content ==> java.lang.String
+  Line 47) beginLine ==> int
+  Line 47) beginColumn ==> int
+  Line 47) endLine ==> int
+  Line 47) endColumn ==> int
+  Line 48) this.content = content ==> java.lang.String
+  Line 57) content ==> java.lang.String
+  Line 67) this.content = content ==> java.lang.String
+  Line 72) false ==> boolean
+  Line 77) isLineComment() ==> boolean
+  Line 79) (LineComment) this ==> com.github.javaparser.ast.comments.LineComment
+  Line 81) new UnsupportedOperationException("Not a line comment") ==> java.lang.UnsupportedOperationException
+  Line 87) this.commentedNode ==> com.github.javaparser.ast.Node
+  Line 92) commentedNode == null ==> boolean
+  Line 94) this.commentedNode = commentedNode ==> com.github.javaparser.ast.Node
+  Line 97) commentedNode == this ==> boolean
+  Line 99) new IllegalArgumentException() ==> java.lang.IllegalArgumentException
+  Line 101) commentedNode instanceof Comment ==> boolean
+  Line 103) new IllegalArgumentException() ==> java.lang.IllegalArgumentException
+  Line 105) this.commentedNode = commentedNode ==> com.github.javaparser.ast.Node
+  Line 110) this.commentedNode == null ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_CommentsCollection.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_CommentsCollection.txt
new file mode 100644
index 0000000..bc85aee
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_CommentsCollection.txt
@@ -0,0 +1,39 @@
+
+[ Class com.github.javaparser.ast.comments.CommentsCollection ]
+  superclass: java.lang.Object
+  Line 31) new LinkedList<LineComment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.LineComment>
+  Line 32) new LinkedList<BlockComment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.BlockComment>
+  Line 33) new LinkedList<JavadocComment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.JavadocComment>
+  Line 36) lineComments ==> java.util.List<com.github.javaparser.ast.comments.LineComment>
+  Line 40) blockComments ==> java.util.List<com.github.javaparser.ast.comments.BlockComment>
+  Line 44) javadocComments ==> java.util.List<com.github.javaparser.ast.comments.JavadocComment>
+  Line 48) this.lineComments.add(lineComment) ==> boolean
+  Line 52) this.blockComments.add(blockComment) ==> boolean
+  Line 56) this.javadocComments.add(javadocComment) ==> boolean
+  Line 60) Comment c ==> com.github.javaparser.ast.comments.Comment
+  Line 60) getAll() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 63) c.getBeginLine() == comment.getBeginLine() && c.getBeginColumn() == comment.getBeginColumn() && c.getEndLine() == comment.getEndLine() && Math.abs(c.getEndColumn() - comment.getEndColumn()) < 2 ==> boolean
+  Line 67) true ==> boolean
+  Line 70) false ==> boolean
+  Line 74) List<Comment> comments = new LinkedList<Comment>() ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 74) new LinkedList<Comment>() ==> java.util.LinkedList<com.github.javaparser.ast.comments.Comment>
+  Line 75) comments.addAll(lineComments) ==> boolean
+  Line 76) comments.addAll(blockComments) ==> boolean
+  Line 77) comments.addAll(javadocComments) ==> boolean
+  Line 78) comments ==> java.util.List<com.github.javaparser.ast.comments.Comment>
+  Line 82) lineComments.size() + blockComments.size() + javadocComments.size() ==> int
+  Line 86) CommentsCollection result = new CommentsCollection() ==> com.github.javaparser.ast.comments.CommentsCollection
+  Line 86) new CommentsCollection() ==> com.github.javaparser.ast.comments.CommentsCollection
+  Line 87) LineComment comment ==> com.github.javaparser.ast.comments.LineComment
+  Line 87) lineComments ==> java.util.List<com.github.javaparser.ast.comments.LineComment>
+  Line 88) !other.contains(comment) ==> boolean
+  Line 89) result.lineComments.add(comment) ==> boolean
+  Line 92) BlockComment comment ==> com.github.javaparser.ast.comments.BlockComment
+  Line 92) blockComments ==> java.util.List<com.github.javaparser.ast.comments.BlockComment>
+  Line 93) !other.contains(comment) ==> boolean
+  Line 94) result.blockComments.add(comment) ==> boolean
+  Line 97) JavadocComment comment ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 97) javadocComments ==> java.util.List<com.github.javaparser.ast.comments.JavadocComment>
+  Line 98) !other.contains(comment) ==> boolean
+  Line 99) result.javadocComments.add(comment) ==> boolean
+  Line 102) result ==> com.github.javaparser.ast.comments.CommentsCollection
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_CommentsParser.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_CommentsParser.txt
new file mode 100644
index 0000000..13dd5e7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_CommentsParser.txt
@@ -0,0 +1,104 @@
+
+[ Class com.github.javaparser.ast.comments.CommentsParser ]
+  superclass: java.lang.Object
+  Line 41) 4 ==> int
+  Line 44) InputStream in = new ByteArrayInputStream(source.getBytes(Charset.defaultCharset())) ==> java.io.InputStream
+  Line 44) new ByteArrayInputStream(source.getBytes(Charset.defaultCharset())) ==> java.io.ByteArrayInputStream
+  Line 45) parse(in, Charset.defaultCharset().name()) ==> com.github.javaparser.ast.comments.CommentsCollection
+  Line 49) boolean lastWasASlashR = false ==> boolean
+  Line 49) false ==> boolean
+  Line 50) BufferedReader br = new BufferedReader(new InputStreamReader(in, charsetName)) ==> java.io.BufferedReader
+  Line 50) new BufferedReader(new InputStreamReader(in, charsetName)) ==> java.io.BufferedReader
+  Line 51) CommentsCollection comments = new CommentsCollection() ==> com.github.javaparser.ast.comments.CommentsCollection
+  Line 51) new CommentsCollection() ==> com.github.javaparser.ast.comments.CommentsCollection
+  Line 52) int r ==> int
+  Line 54) Deque prevTwoChars = new LinkedList<Character>(Arrays.asList('z', 'z')) ==> java.util.Deque
+  Line 54) new LinkedList<Character>(Arrays.asList('z', 'z')) ==> java.util.LinkedList<java.lang.Character>
+  Line 56) State state = State.CODE ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 56) State.CODE ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 57) LineComment currentLineComment = null ==> com.github.javaparser.ast.comments.LineComment
+  Line 57) null ==> null
+  Line 58) BlockComment currentBlockComment = null ==> com.github.javaparser.ast.comments.BlockComment
+  Line 58) null ==> null
+  Line 59) StringBuffer currentContent = null ==> java.lang.StringBuffer
+  Line 59) null ==> null
+  Line 61) int currLine = 1 ==> int
+  Line 61) 1 ==> int
+  Line 62) int currCol = 1 ==> int
+  Line 62) 1 ==> int
+  Line 64) (r = br.read()) != -1 ==> boolean
+  Line 65) char c = (char) r ==> char
+  Line 65) (char) r ==> char
+  Line 66) c == '\r' ==> boolean
+  Line 67) lastWasASlashR = true ==> boolean
+  Line 68) c == '\n' && lastWasASlashR ==> boolean
+  Line 69) lastWasASlashR = false ==> boolean
+  Line 72) lastWasASlashR = false ==> boolean
+  Line 74) state ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 75) CODE ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 76) prevTwoChars.peekLast().equals('/') && c == '/' ==> boolean
+  Line 77) currentLineComment = new LineComment() ==> com.github.javaparser.ast.comments.LineComment
+  Line 78) currentLineComment.setBeginLine(currLine) ==> void
+  Line 79) currentLineComment.setBeginColumn(currCol - 1) ==> void
+  Line 80) state = State.IN_LINE_COMMENT ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 81) currentContent = new StringBuffer() ==> java.lang.StringBuffer
+  Line 82) prevTwoChars.peekLast().equals('/') && c == '*' ==> boolean
+  Line 83) currentBlockComment = new BlockComment() ==> com.github.javaparser.ast.comments.BlockComment
+  Line 84) currentBlockComment.setBeginLine(currLine) ==> void
+  Line 85) currentBlockComment.setBeginColumn(currCol - 1) ==> void
+  Line 86) state = State.IN_BLOCK_COMMENT ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 87) currentContent = new StringBuffer() ==> java.lang.StringBuffer
+  Line 88) c == '"' ==> boolean
+  Line 89) state = State.IN_STRING ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 90) c == '\'' ==> boolean
+  Line 91) state = State.IN_CHAR ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 96) IN_LINE_COMMENT ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 97) c == '\n' || c == '\r' ==> boolean
+  Line 98) currentLineComment.setContent(currentContent.toString()) ==> void
+  Line 99) currentLineComment.setEndLine(currLine) ==> void
+  Line 100) currentLineComment.setEndColumn(currCol) ==> void
+  Line 101) comments.addComment(currentLineComment) ==> void
+  Line 102) state = State.CODE ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 104) currentContent.append(c) ==> java.lang.StringBuffer
+  Line 107) IN_BLOCK_COMMENT ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 108) prevTwoChars.peekLast().equals('*') && c == '/' && !prevTwoChars.peekFirst().equals('/') ==> boolean
+  Line 111) String content = currentContent.deleteCharAt(currentContent.toString().length() - 1).toString() ==> java.lang.String
+  Line 111) currentContent.deleteCharAt(currentContent.toString().length() - 1).toString() ==> java.lang.String
+  Line 113) content.startsWith("*") ==> boolean
+  Line 114) JavadocComment javadocComment = new JavadocComment() ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 114) new JavadocComment() ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 115) javadocComment.setContent(content.substring(1)) ==> void
+  Line 116) javadocComment.setBeginLine(currentBlockComment.getBeginLine()) ==> void
+  Line 117) javadocComment.setBeginColumn(currentBlockComment.getBeginColumn()) ==> void
+  Line 118) javadocComment.setEndLine(currLine) ==> void
+  Line 119) javadocComment.setEndColumn(currCol + 1) ==> void
+  Line 120) comments.addComment(javadocComment) ==> void
+  Line 122) currentBlockComment.setContent(content) ==> void
+  Line 123) currentBlockComment.setEndLine(currLine) ==> void
+  Line 124) currentBlockComment.setEndColumn(currCol + 1) ==> void
+  Line 125) comments.addComment(currentBlockComment) ==> void
+  Line 127) state = State.CODE ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 129) currentContent.append(c == '\r' ? '\n' : c) ==> java.lang.StringBuffer
+  Line 132) IN_STRING ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 133) !prevTwoChars.peekLast().equals('\\') && c == '"' ==> boolean
+  Line 134) state = State.CODE ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 137) IN_CHAR ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 138) !prevTwoChars.peekLast().equals('\\') && c == '\'' ==> boolean
+  Line 139) state = State.CODE ==> com.github.javaparser.ast.comments.CommentsParser.State
+  Line 143) new RuntimeException("Unexpected") ==> java.lang.RuntimeException
+  Line 145) c ==> char
+  Line 146) '\n' ==> char
+  Line 147) '\r' ==> char
+  Line 148) currLine += 1 ==> int
+  Line 149) currCol = 1 ==> int
+  Line 151) '\t' ==> char
+  Line 152) currCol += COLUMNS_PER_TAB ==> int
+  Line 155) currCol += 1 ==> int
+  Line 157) prevTwoChars.remove() ==> java.lang.Object
+  Line 158) prevTwoChars.add(c) ==> boolean
+  Line 161) state == State.IN_LINE_COMMENT ==> boolean
+  Line 162) currentLineComment.setContent(currentContent.toString()) ==> void
+  Line 163) currentLineComment.setEndLine(currLine) ==> void
+  Line 164) currentLineComment.setEndColumn(currCol) ==> void
+  Line 165) comments.addComment(currentLineComment) ==> void
+  Line 168) comments ==> com.github.javaparser.ast.comments.CommentsCollection
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_JavadocComment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_JavadocComment.txt
new file mode 100644
index 0000000..25570d5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_JavadocComment.txt
@@ -0,0 +1,14 @@
+
+[ Class com.github.javaparser.ast.comments.JavadocComment ]
+  superclass: com.github.javaparser.ast.comments.Comment
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 36) content ==> java.lang.String
+  Line 40) beginLine ==> int
+  Line 40) beginColumn ==> int
+  Line 40) endLine ==> int
+  Line 40) endColumn ==> int
+  Line 40) content ==> java.lang.String
+  Line 45) v.visit(this, arg) ==> R
+  Line 50) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_LineComment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_LineComment.txt
new file mode 100644
index 0000000..7ccc9fd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_comments_LineComment.txt
@@ -0,0 +1,15 @@
+
+[ Class com.github.javaparser.ast.comments.LineComment ]
+  superclass: com.github.javaparser.ast.comments.Comment
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) content ==> java.lang.String
+  Line 45) beginLine ==> int
+  Line 45) beginColumn ==> int
+  Line 45) endLine ==> int
+  Line 45) endColumn ==> int
+  Line 45) content ==> java.lang.String
+  Line 50) v.visit(this, arg) ==> R
+  Line 55) v.visit(this, arg) ==> void
+  Line 60) true ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_AnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_AnnotationExpr.txt
new file mode 100644
index 0000000..deff09a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_AnnotationExpr.txt
@@ -0,0 +1,13 @@
+
+[ Class com.github.javaparser.ast.expr.AnnotationExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 35) beginLine ==> int
+  Line 35) beginColumn ==> int
+  Line 35) endLine ==> int
+  Line 35) endColumn ==> int
+  Line 39) name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 43) this.name = name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 44) setAsParentNodeOf(name) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayAccessExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayAccessExpr.txt
new file mode 100644
index 0000000..255994c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayAccessExpr.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.expr.ArrayAccessExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) setName(name) ==> void
+  Line 41) setIndex(index) ==> void
+  Line 45) beginLine ==> int
+  Line 45) beginColumn ==> int
+  Line 45) endLine ==> int
+  Line 45) endColumn ==> int
+  Line 46) setName(name) ==> void
+  Line 47) setIndex(index) ==> void
+  Line 52) v.visit(this, arg) ==> R
+  Line 57) v.visit(this, arg) ==> void
+  Line 61) index ==> com.github.javaparser.ast.expr.Expression
+  Line 65) name ==> com.github.javaparser.ast.expr.Expression
+  Line 69) this.index = index ==> com.github.javaparser.ast.expr.Expression
+  Line 70) setAsParentNodeOf(this.index) ==> void
+  Line 74) this.name = name ==> com.github.javaparser.ast.expr.Expression
+  Line 75) setAsParentNodeOf(this.name) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayCreationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayCreationExpr.txt
new file mode 100644
index 0000000..f3a78f9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayCreationExpr.txt
@@ -0,0 +1,45 @@
+
+[ Class com.github.javaparser.ast.expr.ArrayCreationExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 49) setType(type) ==> void
+  Line 50) setArrayCount(arrayCount) ==> void
+  Line 51) setInitializer(initializer) ==> void
+  Line 52) setDimensions(null) ==> void
+  Line 56) beginLine ==> int
+  Line 56) beginColumn ==> int
+  Line 56) endLine ==> int
+  Line 56) endColumn ==> int
+  Line 57) setType(type) ==> void
+  Line 58) setArrayCount(arrayCount) ==> void
+  Line 59) setInitializer(initializer) ==> void
+  Line 60) setDimensions(null) ==> void
+  Line 64) setType(type) ==> void
+  Line 65) setArrayCount(arrayCount) ==> void
+  Line 66) setDimensions(dimensions) ==> void
+  Line 67) setInitializer(null) ==> void
+  Line 71) beginLine ==> int
+  Line 71) beginColumn ==> int
+  Line 71) endLine ==> int
+  Line 71) endColumn ==> int
+  Line 72) setType(type) ==> void
+  Line 73) setArrayCount(arrayCount) ==> void
+  Line 74) setDimensions(dimensions) ==> void
+  Line 75) setInitializer(null) ==> void
+  Line 80) v.visit(this, arg) ==> R
+  Line 85) v.visit(this, arg) ==> void
+  Line 89) arrayCount ==> int
+  Line 93) dimensions ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 97) initializer ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 101) type ==> com.github.javaparser.ast.type.Type
+  Line 105) this.arrayCount = arrayCount ==> int
+  Line 109) this.dimensions = dimensions ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 110) setAsParentNodeOf(this.dimensions) ==> void
+  Line 114) this.initializer = initializer ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 115) setAsParentNodeOf(this.initializer) ==> void
+  Line 119) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 120) setAsParentNodeOf(this.type) ==> void
+  Line 124) arraysAnnotations ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 129) this.arraysAnnotations = arraysAnnotations ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayInitializerExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayInitializerExpr.txt
new file mode 100644
index 0000000..b098ba1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ArrayInitializerExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.ArrayInitializerExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) setValues(values) ==> void
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 45) setValues(values) ==> void
+  Line 50) v.visit(this, arg) ==> R
+  Line 55) v.visit(this, arg) ==> void
+  Line 59) values ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 63) this.values = values ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 64) setAsParentNodeOf(this.values) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_AssignExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_AssignExpr.txt
new file mode 100644
index 0000000..0cf9ae0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_AssignExpr.txt
@@ -0,0 +1,26 @@
+
+[ Class com.github.javaparser.ast.expr.AssignExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 57) setTarget(target) ==> void
+  Line 58) setValue(value) ==> void
+  Line 59) setOperator(op) ==> void
+  Line 63) beginLine ==> int
+  Line 63) beginColumn ==> int
+  Line 63) endLine ==> int
+  Line 63) endColumn ==> int
+  Line 64) setTarget(target) ==> void
+  Line 65) setValue(value) ==> void
+  Line 66) setOperator(op) ==> void
+  Line 71) v.visit(this, arg) ==> R
+  Line 76) v.visit(this, arg) ==> void
+  Line 80) op ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 84) target ==> com.github.javaparser.ast.expr.Expression
+  Line 88) value ==> com.github.javaparser.ast.expr.Expression
+  Line 92) this.op = op ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 96) this.target = target ==> com.github.javaparser.ast.expr.Expression
+  Line 97) setAsParentNodeOf(this.target) ==> void
+  Line 101) this.value = value ==> com.github.javaparser.ast.expr.Expression
+  Line 102) setAsParentNodeOf(this.value) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_BinaryExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_BinaryExpr.txt
new file mode 100644
index 0000000..1e519b8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_BinaryExpr.txt
@@ -0,0 +1,26 @@
+
+[ Class com.github.javaparser.ast.expr.BinaryExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 64) setLeft(left) ==> void
+  Line 65) setRight(right) ==> void
+  Line 66) setOperator(op) ==> void
+  Line 70) beginLine ==> int
+  Line 70) beginColumn ==> int
+  Line 70) endLine ==> int
+  Line 70) endColumn ==> int
+  Line 71) setLeft(left) ==> void
+  Line 72) setRight(right) ==> void
+  Line 73) setOperator(op) ==> void
+  Line 78) v.visit(this, arg) ==> R
+  Line 83) v.visit(this, arg) ==> void
+  Line 87) left ==> com.github.javaparser.ast.expr.Expression
+  Line 91) op ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 95) right ==> com.github.javaparser.ast.expr.Expression
+  Line 99) this.left = left ==> com.github.javaparser.ast.expr.Expression
+  Line 100) setAsParentNodeOf(this.left) ==> void
+  Line 104) this.op = op ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 108) this.right = right ==> com.github.javaparser.ast.expr.Expression
+  Line 109) setAsParentNodeOf(this.right) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_BooleanLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_BooleanLiteralExpr.txt
new file mode 100644
index 0000000..4191f82
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_BooleanLiteralExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.BooleanLiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) setValue(value) ==> void
+  Line 42) beginLine ==> int
+  Line 42) beginColumn ==> int
+  Line 42) endLine ==> int
+  Line 42) endColumn ==> int
+  Line 43) setValue(value) ==> void
+  Line 48) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) value ==> boolean
+  Line 61) this.value = value ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_CastExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_CastExpr.txt
new file mode 100644
index 0000000..b97510a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_CastExpr.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.expr.CastExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) setType(type) ==> void
+  Line 42) setExpr(expr) ==> void
+  Line 46) beginLine ==> int
+  Line 46) beginColumn ==> int
+  Line 46) endLine ==> int
+  Line 46) endColumn ==> int
+  Line 47) setType(type) ==> void
+  Line 48) setExpr(expr) ==> void
+  Line 53) v.visit(this, arg) ==> R
+  Line 58) v.visit(this, arg) ==> void
+  Line 62) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 66) type ==> com.github.javaparser.ast.type.Type
+  Line 70) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 71) setAsParentNodeOf(this.expr) ==> void
+  Line 75) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 76) setAsParentNodeOf(this.type) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_CharLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_CharLiteralExpr.txt
new file mode 100644
index 0000000..6c2ca85
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_CharLiteralExpr.txt
@@ -0,0 +1,16 @@
+
+[ Class com.github.javaparser.ast.expr.CharLiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.StringLiteralExpr
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 36) value ==> java.lang.String
+  Line 40) beginLine ==> int
+  Line 40) beginColumn ==> int
+  Line 40) endLine ==> int
+  Line 40) endColumn ==> int
+  Line 40) value ==> java.lang.String
+  Line 45) v.visit(this, arg) ==> R
+  Line 50) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ClassExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ClassExpr.txt
new file mode 100644
index 0000000..f536637
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ClassExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.ClassExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 39) setType(type) ==> void
+  Line 43) beginLine ==> int
+  Line 43) beginColumn ==> int
+  Line 43) endLine ==> int
+  Line 43) endColumn ==> int
+  Line 44) setType(type) ==> void
+  Line 49) v.visit(this, arg) ==> R
+  Line 54) v.visit(this, arg) ==> void
+  Line 58) type ==> com.github.javaparser.ast.type.Type
+  Line 62) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 63) setAsParentNodeOf(this.type) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ConditionalExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ConditionalExpr.txt
new file mode 100644
index 0000000..ea92c67
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ConditionalExpr.txt
@@ -0,0 +1,27 @@
+
+[ Class com.github.javaparser.ast.expr.ConditionalExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 42) setCondition(condition) ==> void
+  Line 43) setThenExpr(thenExpr) ==> void
+  Line 44) setElseExpr(elseExpr) ==> void
+  Line 48) beginLine ==> int
+  Line 48) beginColumn ==> int
+  Line 48) endLine ==> int
+  Line 48) endColumn ==> int
+  Line 49) setCondition(condition) ==> void
+  Line 50) setThenExpr(thenExpr) ==> void
+  Line 51) setElseExpr(elseExpr) ==> void
+  Line 56) v.visit(this, arg) ==> R
+  Line 61) v.visit(this, arg) ==> void
+  Line 65) condition ==> com.github.javaparser.ast.expr.Expression
+  Line 69) elseExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 73) thenExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 77) this.condition = condition ==> com.github.javaparser.ast.expr.Expression
+  Line 78) setAsParentNodeOf(this.condition) ==> void
+  Line 82) this.elseExpr = elseExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 83) setAsParentNodeOf(this.elseExpr) ==> void
+  Line 87) this.thenExpr = thenExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 88) setAsParentNodeOf(this.thenExpr) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_DoubleLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_DoubleLiteralExpr.txt
new file mode 100644
index 0000000..16d9a86
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_DoubleLiteralExpr.txt
@@ -0,0 +1,16 @@
+
+[ Class com.github.javaparser.ast.expr.DoubleLiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.StringLiteralExpr
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 36) value ==> java.lang.String
+  Line 41) beginLine ==> int
+  Line 41) beginColumn ==> int
+  Line 41) endLine ==> int
+  Line 41) endColumn ==> int
+  Line 41) value ==> java.lang.String
+  Line 45) v.visit(this, arg) ==> R
+  Line 49) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_EnclosedExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_EnclosedExpr.txt
new file mode 100644
index 0000000..c0507d8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_EnclosedExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.EnclosedExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) setInner(inner) ==> void
+  Line 43) beginLine ==> int
+  Line 43) beginColumn ==> int
+  Line 43) endLine ==> int
+  Line 43) endColumn ==> int
+  Line 44) setInner(inner) ==> void
+  Line 48) v.visit(this, arg) ==> R
+  Line 52) v.visit(this, arg) ==> void
+  Line 56) inner ==> com.github.javaparser.ast.expr.Expression
+  Line 60) this.inner = inner ==> com.github.javaparser.ast.expr.Expression
+  Line 61) setAsParentNodeOf(this.inner) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_Expression.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_Expression.txt
new file mode 100644
index 0000000..b912274
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_Expression.txt
@@ -0,0 +1,9 @@
+
+[ Class com.github.javaparser.ast.expr.Expression ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 35) beginLine ==> int
+  Line 35) beginColumn ==> int
+  Line 35) endLine ==> int
+  Line 35) endColumn ==> int
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_FieldAccessExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_FieldAccessExpr.txt
new file mode 100644
index 0000000..38a138b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_FieldAccessExpr.txt
@@ -0,0 +1,27 @@
+
+[ Class com.github.javaparser.ast.expr.FieldAccessExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 45) setScope(scope) ==> void
+  Line 46) setField(field) ==> void
+  Line 51) beginLine ==> int
+  Line 51) beginColumn ==> int
+  Line 51) endLine ==> int
+  Line 51) endColumn ==> int
+  Line 52) setScope(scope) ==> void
+  Line 53) setTypeArgs(typeArgs) ==> void
+  Line 54) setField(field) ==> void
+  Line 58) v.visit(this, arg) ==> R
+  Line 62) v.visit(this, arg) ==> void
+  Line 66) field.getName() ==> java.lang.String
+  Line 70) field ==> com.github.javaparser.ast.expr.NameExpr
+  Line 74) scope ==> com.github.javaparser.ast.expr.Expression
+  Line 78) typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 82) this.field = new NameExpr(field) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 86) this.field = field ==> com.github.javaparser.ast.expr.NameExpr
+  Line 90) this.scope = scope ==> com.github.javaparser.ast.expr.Expression
+  Line 91) setAsParentNodeOf(this.scope) ==> void
+  Line 95) this.typeArgs = typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 96) setAsParentNodeOf(this.typeArgs) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_InstanceOfExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_InstanceOfExpr.txt
new file mode 100644
index 0000000..0e858f1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_InstanceOfExpr.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.expr.InstanceOfExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) setExpr(expr) ==> void
+  Line 42) setType(type) ==> void
+  Line 47) beginLine ==> int
+  Line 47) beginColumn ==> int
+  Line 47) endLine ==> int
+  Line 47) endColumn ==> int
+  Line 48) setExpr(expr) ==> void
+  Line 49) setType(type) ==> void
+  Line 53) v.visit(this, arg) ==> R
+  Line 57) v.visit(this, arg) ==> void
+  Line 61) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 65) type ==> com.github.javaparser.ast.type.Type
+  Line 69) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 70) setAsParentNodeOf(this.expr) ==> void
+  Line 74) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 75) setAsParentNodeOf(this.type) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_IntegerLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_IntegerLiteralExpr.txt
new file mode 100644
index 0000000..011fdd5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_IntegerLiteralExpr.txt
@@ -0,0 +1,21 @@
+
+[ Class com.github.javaparser.ast.expr.IntegerLiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.StringLiteralExpr
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 32) "2147483648" ==> java.lang.String
+  Line 34) "-" + UNSIGNED_MIN_VALUE ==> java.lang.String
+  Line 40) value ==> java.lang.String
+  Line 45) beginLine ==> int
+  Line 45) beginColumn ==> int
+  Line 45) endLine ==> int
+  Line 45) endColumn ==> int
+  Line 45) value ==> java.lang.String
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) //
+value != null && //
+value.length() == 10 && value.equals(UNSIGNED_MIN_VALUE) ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_IntegerLiteralMinValueExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_IntegerLiteralMinValueExpr.txt
new file mode 100644
index 0000000..420e880
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_IntegerLiteralMinValueExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr ]
+  superclass: com.github.javaparser.ast.expr.IntegerLiteralExpr
+  superclass: com.github.javaparser.ast.expr.StringLiteralExpr
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 33) MIN_VALUE ==> java.lang.String
+  Line 37) beginLine ==> int
+  Line 37) beginColumn ==> int
+  Line 37) endLine ==> int
+  Line 37) endColumn ==> int
+  Line 37) MIN_VALUE ==> java.lang.String
+  Line 41) v.visit(this, arg) ==> R
+  Line 45) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LambdaExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LambdaExpr.txt
new file mode 100644
index 0000000..86d476c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LambdaExpr.txt
@@ -0,0 +1,23 @@
+
+[ Class com.github.javaparser.ast.expr.LambdaExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 52) beginLine ==> int
+  Line 52) beginColumn ==> int
+  Line 52) endLine ==> int
+  Line 52) endColumn ==> int
+  Line 53) setParameters(parameters) ==> void
+  Line 54) setBody(body) ==> void
+  Line 55) setParametersEnclosed(parametersEnclosed) ==> void
+  Line 59) parameters ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 63) this.parameters = parameters ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 64) setAsParentNodeOf(this.parameters) ==> void
+  Line 68) body ==> com.github.javaparser.ast.stmt.Statement
+  Line 72) this.body = body ==> com.github.javaparser.ast.stmt.Statement
+  Line 73) setAsParentNodeOf(this.body) ==> void
+  Line 78) v.visit(this, arg) ==> R
+  Line 83) v.visit(this, arg) ==> void
+  Line 87) parametersEnclosed ==> boolean
+  Line 91) this.parametersEnclosed = parametersEnclosed ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LiteralExpr.txt
new file mode 100644
index 0000000..ca57a20
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LiteralExpr.txt
@@ -0,0 +1,10 @@
+
+[ Class com.github.javaparser.ast.expr.LiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 33) beginLine ==> int
+  Line 33) beginColumn ==> int
+  Line 33) endLine ==> int
+  Line 33) endColumn ==> int
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LongLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LongLiteralExpr.txt
new file mode 100644
index 0000000..8382c1a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LongLiteralExpr.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.expr.LongLiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.StringLiteralExpr
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 32) "9223372036854775808" ==> java.lang.String
+  Line 34) "-" + UNSIGNED_MIN_VALUE + "L" ==> java.lang.String
+  Line 40) value ==> java.lang.String
+  Line 45) beginLine ==> int
+  Line 45) beginColumn ==> int
+  Line 45) endLine ==> int
+  Line 45) endColumn ==> int
+  Line 45) value ==> java.lang.String
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) //
+value != null && //
+value.length() == 20 && //
+value.startsWith(UNSIGNED_MIN_VALUE) && (value.charAt(19) == 'L' || value.charAt(19) == 'l') ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LongLiteralMinValueExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LongLiteralMinValueExpr.txt
new file mode 100644
index 0000000..5c6cf8e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_LongLiteralMinValueExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.LongLiteralMinValueExpr ]
+  superclass: com.github.javaparser.ast.expr.LongLiteralExpr
+  superclass: com.github.javaparser.ast.expr.StringLiteralExpr
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 33) MIN_VALUE ==> java.lang.String
+  Line 37) beginLine ==> int
+  Line 37) beginColumn ==> int
+  Line 37) endLine ==> int
+  Line 37) endColumn ==> int
+  Line 37) MIN_VALUE ==> java.lang.String
+  Line 41) v.visit(this, arg) ==> R
+  Line 45) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MarkerAnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MarkerAnnotationExpr.txt
new file mode 100644
index 0000000..17af7f8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MarkerAnnotationExpr.txt
@@ -0,0 +1,15 @@
+
+[ Class com.github.javaparser.ast.expr.MarkerAnnotationExpr ]
+  superclass: com.github.javaparser.ast.expr.AnnotationExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 36) setName(name) ==> void
+  Line 41) beginLine ==> int
+  Line 41) beginColumn ==> int
+  Line 41) endLine ==> int
+  Line 41) endColumn ==> int
+  Line 42) setName(name) ==> void
+  Line 46) v.visit(this, arg) ==> R
+  Line 50) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MemberValuePair.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MemberValuePair.txt
new file mode 100644
index 0000000..42b0154
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MemberValuePair.txt
@@ -0,0 +1,21 @@
+
+[ Class com.github.javaparser.ast.expr.MemberValuePair ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  Line 42) setName(name) ==> void
+  Line 43) setValue(value) ==> void
+  Line 48) beginLine ==> int
+  Line 48) beginColumn ==> int
+  Line 48) endLine ==> int
+  Line 48) endColumn ==> int
+  Line 49) setName(name) ==> void
+  Line 50) setValue(value) ==> void
+  Line 54) v.visit(this, arg) ==> R
+  Line 58) v.visit(this, arg) ==> void
+  Line 62) name ==> java.lang.String
+  Line 66) value ==> com.github.javaparser.ast.expr.Expression
+  Line 70) this.name = name ==> java.lang.String
+  Line 74) this.value = value ==> com.github.javaparser.ast.expr.Expression
+  Line 75) setAsParentNodeOf(this.value) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MethodCallExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MethodCallExpr.txt
new file mode 100644
index 0000000..18cc572
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MethodCallExpr.txt
@@ -0,0 +1,34 @@
+
+[ Class com.github.javaparser.ast.expr.MethodCallExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 47) setScope(scope) ==> void
+  Line 48) setName(name) ==> void
+  Line 52) setScope(scope) ==> void
+  Line 53) setName(name) ==> void
+  Line 54) setArgs(args) ==> void
+  Line 59) beginLine ==> int
+  Line 59) beginColumn ==> int
+  Line 59) endLine ==> int
+  Line 59) endColumn ==> int
+  Line 60) setScope(scope) ==> void
+  Line 61) setTypeArgs(typeArgs) ==> void
+  Line 62) setName(name) ==> void
+  Line 63) setArgs(args) ==> void
+  Line 67) v.visit(this, arg) ==> R
+  Line 71) v.visit(this, arg) ==> void
+  Line 75) args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 79) name.getName() ==> java.lang.String
+  Line 83) name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 87) scope ==> com.github.javaparser.ast.expr.Expression
+  Line 91) typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 95) this.args = args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 96) setAsParentNodeOf(this.args) ==> void
+  Line 100) this.name = new NameExpr(name) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 104) this.name = name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 108) this.scope = scope ==> com.github.javaparser.ast.expr.Expression
+  Line 109) setAsParentNodeOf(this.scope) ==> void
+  Line 113) this.typeArgs = typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 114) setAsParentNodeOf(this.typeArgs) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MethodReferenceExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MethodReferenceExpr.txt
new file mode 100644
index 0000000..4b1c7ca
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_MethodReferenceExpr.txt
@@ -0,0 +1,23 @@
+
+[ Class com.github.javaparser.ast.expr.MethodReferenceExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 55) beginLine ==> int
+  Line 55) beginColumn ==> int
+  Line 55) endLine ==> int
+  Line 55) endColumn ==> int
+  Line 56) setIdentifier(identifier) ==> void
+  Line 57) setScope(scope) ==> void
+  Line 58) setTypeParameters(typeParameters) ==> void
+  Line 64) v.visit(this, arg) ==> R
+  Line 69) v.visit(this, arg) ==> void
+  Line 73) scope ==> com.github.javaparser.ast.expr.Expression
+  Line 77) this.scope = scope ==> com.github.javaparser.ast.expr.Expression
+  Line 78) setAsParentNodeOf(this.scope) ==> void
+  Line 82) typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 86) this.typeParameters = typeParameters ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 87) setAsParentNodeOf(this.typeParameters) ==> void
+  Line 91) identifier ==> java.lang.String
+  Line 95) this.identifier = identifier ==> java.lang.String
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NameExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NameExpr.txt
new file mode 100644
index 0000000..044868f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NameExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.NameExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.NamedNode
+  interface: java.lang.Cloneable
+  Line 39) this.name = name ==> java.lang.String
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 45) this.name = name ==> java.lang.String
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) name ==> java.lang.String
+  Line 61) this.name = name ==> java.lang.String
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NormalAnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NormalAnnotationExpr.txt
new file mode 100644
index 0000000..a655d2f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NormalAnnotationExpr.txt
@@ -0,0 +1,20 @@
+
+[ Class com.github.javaparser.ast.expr.NormalAnnotationExpr ]
+  superclass: com.github.javaparser.ast.expr.AnnotationExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) setName(name) ==> void
+  Line 41) setPairs(pairs) ==> void
+  Line 46) beginLine ==> int
+  Line 46) beginColumn ==> int
+  Line 46) endLine ==> int
+  Line 46) endColumn ==> int
+  Line 47) setName(name) ==> void
+  Line 48) setPairs(pairs) ==> void
+  Line 52) v.visit(this, arg) ==> R
+  Line 56) v.visit(this, arg) ==> void
+  Line 60) pairs ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 64) this.pairs = pairs ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 65) setAsParentNodeOf(this.pairs) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NullLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NullLiteralExpr.txt
new file mode 100644
index 0000000..71b08bd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_NullLiteralExpr.txt
@@ -0,0 +1,13 @@
+
+[ Class com.github.javaparser.ast.expr.NullLiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 36) beginLine ==> int
+  Line 36) beginColumn ==> int
+  Line 36) endLine ==> int
+  Line 36) endColumn ==> int
+  Line 40) v.visit(this, arg) ==> R
+  Line 44) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ObjectCreationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ObjectCreationExpr.txt
new file mode 100644
index 0000000..af22ee2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ObjectCreationExpr.txt
@@ -0,0 +1,35 @@
+
+[ Class com.github.javaparser.ast.expr.ObjectCreationExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 51) setScope(scope) ==> void
+  Line 52) setType(type) ==> void
+  Line 53) setArgs(args) ==> void
+  Line 59) beginLine ==> int
+  Line 59) beginColumn ==> int
+  Line 59) endLine ==> int
+  Line 59) endColumn ==> int
+  Line 60) setScope(scope) ==> void
+  Line 61) setType(type) ==> void
+  Line 62) setTypeArgs(typeArgs) ==> void
+  Line 63) setArgs(args) ==> void
+  Line 64) setAnonymousClassBody(anonymousBody) ==> void
+  Line 68) v.visit(this, arg) ==> R
+  Line 72) v.visit(this, arg) ==> void
+  Line 76) anonymousClassBody ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 80) args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 84) scope ==> com.github.javaparser.ast.expr.Expression
+  Line 88) type ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 92) typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 96) this.anonymousClassBody = anonymousClassBody ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 97) setAsParentNodeOf(this.anonymousClassBody) ==> void
+  Line 101) this.args = args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 102) setAsParentNodeOf(this.args) ==> void
+  Line 106) this.scope = scope ==> com.github.javaparser.ast.expr.Expression
+  Line 107) setAsParentNodeOf(this.scope) ==> void
+  Line 111) this.type = type ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 112) setAsParentNodeOf(this.type) ==> void
+  Line 116) this.typeArgs = typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 117) setAsParentNodeOf(this.typeArgs) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_QualifiedNameExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_QualifiedNameExpr.txt
new file mode 100644
index 0000000..3734479
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_QualifiedNameExpr.txt
@@ -0,0 +1,21 @@
+
+[ Class com.github.javaparser.ast.expr.QualifiedNameExpr ]
+  superclass: com.github.javaparser.ast.expr.NameExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  interface: com.github.javaparser.ast.NamedNode
+  Line 38) name ==> java.lang.String
+  Line 39) setQualifier(scope) ==> void
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 44) name ==> java.lang.String
+  Line 45) setQualifier(scope) ==> void
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) qualifier ==> com.github.javaparser.ast.expr.NameExpr
+  Line 61) this.qualifier = qualifier ==> com.github.javaparser.ast.expr.NameExpr
+  Line 62) setAsParentNodeOf(this.qualifier) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_SingleMemberAnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_SingleMemberAnnotationExpr.txt
new file mode 100644
index 0000000..70a6150
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_SingleMemberAnnotationExpr.txt
@@ -0,0 +1,20 @@
+
+[ Class com.github.javaparser.ast.expr.SingleMemberAnnotationExpr ]
+  superclass: com.github.javaparser.ast.expr.AnnotationExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) setName(name) ==> void
+  Line 39) setMemberValue(memberValue) ==> void
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 45) setName(name) ==> void
+  Line 46) setMemberValue(memberValue) ==> void
+  Line 50) v.visit(this, arg) ==> R
+  Line 54) v.visit(this, arg) ==> void
+  Line 58) memberValue ==> com.github.javaparser.ast.expr.Expression
+  Line 62) this.memberValue = memberValue ==> com.github.javaparser.ast.expr.Expression
+  Line 63) setAsParentNodeOf(this.memberValue) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_StringLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_StringLiteralExpr.txt
new file mode 100644
index 0000000..d4f333f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_StringLiteralExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.StringLiteralExpr ]
+  superclass: com.github.javaparser.ast.expr.LiteralExpr
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) this.value = value ==> java.lang.String
+  Line 43) beginLine ==> int
+  Line 43) beginColumn ==> int
+  Line 43) endLine ==> int
+  Line 43) endColumn ==> int
+  Line 44) this.value = value ==> java.lang.String
+  Line 48) v.visit(this, arg) ==> R
+  Line 52) v.visit(this, arg) ==> void
+  Line 56) value ==> java.lang.String
+  Line 60) this.value = value ==> java.lang.String
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_SuperExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_SuperExpr.txt
new file mode 100644
index 0000000..ce9f1db
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_SuperExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.SuperExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) setClassExpr(classExpr) ==> void
+  Line 43) beginLine ==> int
+  Line 43) beginColumn ==> int
+  Line 43) endLine ==> int
+  Line 43) endColumn ==> int
+  Line 44) setClassExpr(classExpr) ==> void
+  Line 48) v.visit(this, arg) ==> R
+  Line 52) v.visit(this, arg) ==> void
+  Line 56) classExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 60) this.classExpr = classExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 61) setAsParentNodeOf(this.classExpr) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ThisExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ThisExpr.txt
new file mode 100644
index 0000000..08e3f8e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_ThisExpr.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.expr.ThisExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) setClassExpr(classExpr) ==> void
+  Line 43) beginLine ==> int
+  Line 43) beginColumn ==> int
+  Line 43) endLine ==> int
+  Line 43) endColumn ==> int
+  Line 44) setClassExpr(classExpr) ==> void
+  Line 48) v.visit(this, arg) ==> R
+  Line 52) v.visit(this, arg) ==> void
+  Line 56) classExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 60) this.classExpr = classExpr ==> com.github.javaparser.ast.expr.Expression
+  Line 61) setAsParentNodeOf(this.classExpr) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_TypeExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_TypeExpr.txt
new file mode 100644
index 0000000..caab44b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_TypeExpr.txt
@@ -0,0 +1,16 @@
+
+[ Class com.github.javaparser.ast.expr.TypeExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) beginLine ==> int
+  Line 40) beginColumn ==> int
+  Line 40) endLine ==> int
+  Line 40) endColumn ==> int
+  Line 41) setType(type) ==> void
+  Line 46) v.visit(this, arg) ==> R
+  Line 51) v.visit(this, arg) ==> void
+  Line 55) type ==> com.github.javaparser.ast.type.Type
+  Line 59) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 60) setAsParentNodeOf(this.type) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_UnaryExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_UnaryExpr.txt
new file mode 100644
index 0000000..d046e32
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_UnaryExpr.txt
@@ -0,0 +1,21 @@
+
+[ Class com.github.javaparser.ast.expr.UnaryExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 51) setExpr(expr) ==> void
+  Line 52) setOperator(op) ==> void
+  Line 57) beginLine ==> int
+  Line 57) beginColumn ==> int
+  Line 57) endLine ==> int
+  Line 57) endColumn ==> int
+  Line 58) setExpr(expr) ==> void
+  Line 59) setOperator(op) ==> void
+  Line 63) v.visit(this, arg) ==> R
+  Line 67) v.visit(this, arg) ==> void
+  Line 71) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 75) op ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 79) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 80) setAsParentNodeOf(this.expr) ==> void
+  Line 84) this.op = op ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_VariableDeclarationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_VariableDeclarationExpr.txt
new file mode 100644
index 0000000..c3e276c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_expr_VariableDeclarationExpr.txt
@@ -0,0 +1,32 @@
+
+[ Class com.github.javaparser.ast.expr.VariableDeclarationExpr ]
+  superclass: com.github.javaparser.ast.expr.Expression
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 49) setType(type) ==> void
+  Line 50) setVars(vars) ==> void
+  Line 54) setModifiers(modifiers) ==> void
+  Line 55) setType(type) ==> void
+  Line 56) setVars(vars) ==> void
+  Line 62) beginLine ==> int
+  Line 62) beginColumn ==> int
+  Line 62) endLine ==> int
+  Line 62) endColumn ==> int
+  Line 63) setModifiers(modifiers) ==> void
+  Line 64) setAnnotations(annotations) ==> void
+  Line 65) setType(type) ==> void
+  Line 66) setVars(vars) ==> void
+  Line 70) v.visit(this, arg) ==> R
+  Line 74) v.visit(this, arg) ==> void
+  Line 78) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 88) modifiers ==> int
+  Line 92) type ==> com.github.javaparser.ast.type.Type
+  Line 96) vars ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 100) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 101) setAsParentNodeOf(this.annotations) ==> void
+  Line 105) this.modifiers = modifiers ==> int
+  Line 109) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 110) setAsParentNodeOf(this.type) ==> void
+  Line 114) this.vars = vars ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 115) setAsParentNodeOf(this.vars) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_internal_Utils.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_internal_Utils.txt
new file mode 100644
index 0000000..4aac73a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_internal_Utils.txt
@@ -0,0 +1,5 @@
+
+[ Class com.github.javaparser.ast.internal.Utils ]
+  superclass: java.lang.Object
+  Line 35) list == null ? Collections.<T>emptyList() : list ==> java.util.List<T>
+  Line 39) collection == null || collection.isEmpty() ==> boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_AssertStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_AssertStmt.txt
new file mode 100644
index 0000000..535fc91
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_AssertStmt.txt
@@ -0,0 +1,23 @@
+
+[ Class com.github.javaparser.ast.stmt.AssertStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) setCheck(check) ==> void
+  Line 45) setCheck(check) ==> void
+  Line 46) setMessage(msg) ==> void
+  Line 51) beginLine ==> int
+  Line 51) beginColumn ==> int
+  Line 51) endLine ==> int
+  Line 51) endColumn ==> int
+  Line 53) setCheck(check) ==> void
+  Line 54) setMessage(msg) ==> void
+  Line 59) v.visit(this, arg) ==> R
+  Line 63) v.visit(this, arg) ==> void
+  Line 67) check ==> com.github.javaparser.ast.expr.Expression
+  Line 71) msg ==> com.github.javaparser.ast.expr.Expression
+  Line 75) this.check = check ==> com.github.javaparser.ast.expr.Expression
+  Line 76) setAsParentNodeOf(this.check) ==> void
+  Line 80) this.msg = msg ==> com.github.javaparser.ast.expr.Expression
+  Line 81) setAsParentNodeOf(this.msg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_BlockStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_BlockStmt.txt
new file mode 100644
index 0000000..cef3a6a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_BlockStmt.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.stmt.BlockStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) setStmts(stmts) ==> void
+  Line 45) beginLine ==> int
+  Line 45) beginColumn ==> int
+  Line 45) endLine ==> int
+  Line 45) endColumn ==> int
+  Line 46) setStmts(stmts) ==> void
+  Line 51) v.visit(this, arg) ==> R
+  Line 56) v.visit(this, arg) ==> void
+  Line 60) stmts ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 64) this.stmts = stmts ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 65) setAsParentNodeOf(this.stmts) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_BreakStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_BreakStmt.txt
new file mode 100644
index 0000000..54c0f1d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_BreakStmt.txt
@@ -0,0 +1,16 @@
+
+[ Class com.github.javaparser.ast.stmt.BreakStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) this.id = id ==> java.lang.String
+  Line 42) beginLine ==> int
+  Line 42) beginColumn ==> int
+  Line 42) endLine ==> int
+  Line 42) endColumn ==> int
+  Line 43) this.id = id ==> java.lang.String
+  Line 47) v.visit(this, arg) ==> R
+  Line 51) v.visit(this, arg) ==> void
+  Line 55) id ==> java.lang.String
+  Line 59) this.id = id ==> java.lang.String
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_CatchClause.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_CatchClause.txt
new file mode 100644
index 0000000..726ac19
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_CatchClause.txt
@@ -0,0 +1,23 @@
+
+[ Class com.github.javaparser.ast.stmt.CatchClause ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 47) setExcept(except) ==> void
+  Line 48) setCatchBlock(catchBlock) ==> void
+  Line 52) new MultiTypeParameter(exceptModifier, exceptAnnotations, exceptTypes, exceptId) ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 52) catchBlock ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 58) beginLine ==> int
+  Line 58) beginColumn ==> int
+  Line 58) endLine ==> int
+  Line 58) endColumn ==> int
+  Line 59) setExcept(new MultiTypeParameter(beginLine, beginColumn, endLine, endColumn, exceptModifier, exceptAnnotations, exceptTypes, exceptId)) ==> void
+  Line 60) setCatchBlock(catchBlock) ==> void
+  Line 64) v.visit(this, arg) ==> R
+  Line 68) v.visit(this, arg) ==> void
+  Line 72) catchBlock ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 76) except ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 80) this.catchBlock = catchBlock ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 81) setAsParentNodeOf(this.catchBlock) ==> void
+  Line 85) this.except = except ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 86) setAsParentNodeOf(this.except) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ContinueStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ContinueStmt.txt
new file mode 100644
index 0000000..52d5d72
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ContinueStmt.txt
@@ -0,0 +1,16 @@
+
+[ Class com.github.javaparser.ast.stmt.ContinueStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 38) this.id = id ==> java.lang.String
+  Line 43) beginLine ==> int
+  Line 43) beginColumn ==> int
+  Line 43) endLine ==> int
+  Line 43) endColumn ==> int
+  Line 44) this.id = id ==> java.lang.String
+  Line 48) v.visit(this, arg) ==> R
+  Line 52) v.visit(this, arg) ==> void
+  Line 56) id ==> java.lang.String
+  Line 60) this.id = id ==> java.lang.String
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_DoStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_DoStmt.txt
new file mode 100644
index 0000000..3515429
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_DoStmt.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.stmt.DoStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) setBody(body) ==> void
+  Line 42) setCondition(condition) ==> void
+  Line 47) beginLine ==> int
+  Line 47) beginColumn ==> int
+  Line 47) endLine ==> int
+  Line 47) endColumn ==> int
+  Line 48) setBody(body) ==> void
+  Line 49) setCondition(condition) ==> void
+  Line 53) v.visit(this, arg) ==> R
+  Line 57) v.visit(this, arg) ==> void
+  Line 61) body ==> com.github.javaparser.ast.stmt.Statement
+  Line 65) condition ==> com.github.javaparser.ast.expr.Expression
+  Line 69) this.body = body ==> com.github.javaparser.ast.stmt.Statement
+  Line 70) setAsParentNodeOf(this.body) ==> void
+  Line 74) this.condition = condition ==> com.github.javaparser.ast.expr.Expression
+  Line 75) setAsParentNodeOf(this.condition) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_EmptyStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_EmptyStmt.txt
new file mode 100644
index 0000000..5a4aa9e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_EmptyStmt.txt
@@ -0,0 +1,12 @@
+
+[ Class com.github.javaparser.ast.stmt.EmptyStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 36) beginLine ==> int
+  Line 36) beginColumn ==> int
+  Line 36) endLine ==> int
+  Line 36) endColumn ==> int
+  Line 40) v.visit(this, arg) ==> R
+  Line 44) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ExplicitConstructorInvocationStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ExplicitConstructorInvocationStmt.txt
new file mode 100644
index 0000000..18a0578
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ExplicitConstructorInvocationStmt.txt
@@ -0,0 +1,30 @@
+
+[ Class com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 49) setThis(isThis) ==> void
+  Line 50) setExpr(expr) ==> void
+  Line 51) setArgs(args) ==> void
+  Line 58) beginLine ==> int
+  Line 58) beginColumn ==> int
+  Line 58) endLine ==> int
+  Line 58) endColumn ==> int
+  Line 59) setTypeArgs(typeArgs) ==> void
+  Line 60) setThis(isThis) ==> void
+  Line 61) setExpr(expr) ==> void
+  Line 62) setArgs(args) ==> void
+  Line 67) v.visit(this, arg) ==> R
+  Line 72) v.visit(this, arg) ==> void
+  Line 76) args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 80) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 84) typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 88) isThis ==> boolean
+  Line 92) this.args = args ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 93) setAsParentNodeOf(this.args) ==> void
+  Line 97) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 98) setAsParentNodeOf(this.expr) ==> void
+  Line 102) this.isThis = isThis ==> boolean
+  Line 106) this.typeArgs = typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 107) setAsParentNodeOf(this.typeArgs) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ExpressionStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ExpressionStmt.txt
new file mode 100644
index 0000000..f625704
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ExpressionStmt.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.stmt.ExpressionStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 39) setExpression(expr) ==> void
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 45) setExpression(expr) ==> void
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 61) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 62) setAsParentNodeOf(this.expr) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ForStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ForStmt.txt
new file mode 100644
index 0000000..06da7f2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ForStmt.txt
@@ -0,0 +1,32 @@
+
+[ Class com.github.javaparser.ast.stmt.ForStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 48) setCompare(compare) ==> void
+  Line 49) setInit(init) ==> void
+  Line 50) setUpdate(update) ==> void
+  Line 51) setBody(body) ==> void
+  Line 58) beginLine ==> int
+  Line 58) beginColumn ==> int
+  Line 58) endLine ==> int
+  Line 58) endColumn ==> int
+  Line 59) setCompare(compare) ==> void
+  Line 60) setInit(init) ==> void
+  Line 61) setUpdate(update) ==> void
+  Line 62) setBody(body) ==> void
+  Line 67) v.visit(this, arg) ==> R
+  Line 72) v.visit(this, arg) ==> void
+  Line 76) body ==> com.github.javaparser.ast.stmt.Statement
+  Line 80) compare ==> com.github.javaparser.ast.expr.Expression
+  Line 84) init ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 88) update ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 92) this.body = body ==> com.github.javaparser.ast.stmt.Statement
+  Line 93) setAsParentNodeOf(this.body) ==> void
+  Line 97) this.compare = compare ==> com.github.javaparser.ast.expr.Expression
+  Line 98) setAsParentNodeOf(this.compare) ==> void
+  Line 102) this.init = init ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 103) setAsParentNodeOf(this.init) ==> void
+  Line 107) this.update = update ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 108) setAsParentNodeOf(this.update) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ForeachStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ForeachStmt.txt
new file mode 100644
index 0000000..6bd60fd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ForeachStmt.txt
@@ -0,0 +1,27 @@
+
+[ Class com.github.javaparser.ast.stmt.ForeachStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 45) setVariable(var) ==> void
+  Line 46) setIterable(iterable) ==> void
+  Line 47) setBody(body) ==> void
+  Line 54) beginLine ==> int
+  Line 54) beginColumn ==> int
+  Line 54) endLine ==> int
+  Line 54) endColumn ==> int
+  Line 55) setVariable(var) ==> void
+  Line 56) setIterable(iterable) ==> void
+  Line 57) setBody(body) ==> void
+  Line 62) v.visit(this, arg) ==> R
+  Line 67) v.visit(this, arg) ==> void
+  Line 71) body ==> com.github.javaparser.ast.stmt.Statement
+  Line 75) iterable ==> com.github.javaparser.ast.expr.Expression
+  Line 79) var ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 83) this.body = body ==> com.github.javaparser.ast.stmt.Statement
+  Line 84) setAsParentNodeOf(this.body) ==> void
+  Line 88) this.iterable = iterable ==> com.github.javaparser.ast.expr.Expression
+  Line 89) setAsParentNodeOf(this.iterable) ==> void
+  Line 93) this.var = var ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 94) setAsParentNodeOf(this.var) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_IfStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_IfStmt.txt
new file mode 100644
index 0000000..49f2b1a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_IfStmt.txt
@@ -0,0 +1,27 @@
+
+[ Class com.github.javaparser.ast.stmt.IfStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 43) setCondition(condition) ==> void
+  Line 44) setThenStmt(thenStmt) ==> void
+  Line 45) setElseStmt(elseStmt) ==> void
+  Line 50) beginLine ==> int
+  Line 50) beginColumn ==> int
+  Line 50) endLine ==> int
+  Line 50) endColumn ==> int
+  Line 51) setCondition(condition) ==> void
+  Line 52) setThenStmt(thenStmt) ==> void
+  Line 53) setElseStmt(elseStmt) ==> void
+  Line 57) v.visit(this, arg) ==> R
+  Line 61) v.visit(this, arg) ==> void
+  Line 65) condition ==> com.github.javaparser.ast.expr.Expression
+  Line 69) elseStmt ==> com.github.javaparser.ast.stmt.Statement
+  Line 73) thenStmt ==> com.github.javaparser.ast.stmt.Statement
+  Line 77) this.condition = condition ==> com.github.javaparser.ast.expr.Expression
+  Line 78) setAsParentNodeOf(this.condition) ==> void
+  Line 82) this.elseStmt = elseStmt ==> com.github.javaparser.ast.stmt.Statement
+  Line 83) setAsParentNodeOf(this.elseStmt) ==> void
+  Line 87) this.thenStmt = thenStmt ==> com.github.javaparser.ast.stmt.Statement
+  Line 88) setAsParentNodeOf(this.thenStmt) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_LabeledStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_LabeledStmt.txt
new file mode 100644
index 0000000..43762a8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_LabeledStmt.txt
@@ -0,0 +1,21 @@
+
+[ Class com.github.javaparser.ast.stmt.LabeledStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) setLabel(label) ==> void
+  Line 41) setStmt(stmt) ==> void
+  Line 46) beginLine ==> int
+  Line 46) beginColumn ==> int
+  Line 46) endLine ==> int
+  Line 46) endColumn ==> int
+  Line 47) setLabel(label) ==> void
+  Line 48) setStmt(stmt) ==> void
+  Line 52) v.visit(this, arg) ==> R
+  Line 56) v.visit(this, arg) ==> void
+  Line 60) label ==> java.lang.String
+  Line 64) stmt ==> com.github.javaparser.ast.stmt.Statement
+  Line 68) this.label = label ==> java.lang.String
+  Line 72) this.stmt = stmt ==> com.github.javaparser.ast.stmt.Statement
+  Line 73) setAsParentNodeOf(this.stmt) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ReturnStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ReturnStmt.txt
new file mode 100644
index 0000000..736d3be
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ReturnStmt.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.stmt.ReturnStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 39) setExpr(expr) ==> void
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 45) setExpr(expr) ==> void
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 61) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 62) setAsParentNodeOf(this.expr) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_Statement.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_Statement.txt
new file mode 100644
index 0000000..374de72
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_Statement.txt
@@ -0,0 +1,9 @@
+
+[ Class com.github.javaparser.ast.stmt.Statement ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 35) beginLine ==> int
+  Line 35) beginColumn ==> int
+  Line 35) endLine ==> int
+  Line 35) endColumn ==> int
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SwitchEntryStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SwitchEntryStmt.txt
new file mode 100644
index 0000000..690b6cb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SwitchEntryStmt.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.stmt.SwitchEntryStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 43) setLabel(label) ==> void
+  Line 44) setStmts(stmts) ==> void
+  Line 50) beginLine ==> int
+  Line 50) beginColumn ==> int
+  Line 50) endLine ==> int
+  Line 50) endColumn ==> int
+  Line 51) setLabel(label) ==> void
+  Line 52) setStmts(stmts) ==> void
+  Line 57) v.visit(this, arg) ==> R
+  Line 62) v.visit(this, arg) ==> void
+  Line 66) label ==> com.github.javaparser.ast.expr.Expression
+  Line 70) stmts ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 74) this.label = label ==> com.github.javaparser.ast.expr.Expression
+  Line 75) setAsParentNodeOf(this.label) ==> void
+  Line 79) this.stmts = stmts ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 80) setAsParentNodeOf(this.stmts) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SwitchStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SwitchStmt.txt
new file mode 100644
index 0000000..63d6275
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SwitchStmt.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.stmt.SwitchStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 44) setSelector(selector) ==> void
+  Line 45) setEntries(entries) ==> void
+  Line 51) beginLine ==> int
+  Line 51) beginColumn ==> int
+  Line 51) endLine ==> int
+  Line 51) endColumn ==> int
+  Line 52) setSelector(selector) ==> void
+  Line 53) setEntries(entries) ==> void
+  Line 58) v.visit(this, arg) ==> R
+  Line 63) v.visit(this, arg) ==> void
+  Line 67) entries ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 71) selector ==> com.github.javaparser.ast.expr.Expression
+  Line 75) this.entries = entries ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 76) setAsParentNodeOf(this.entries) ==> void
+  Line 80) this.selector = selector ==> com.github.javaparser.ast.expr.Expression
+  Line 81) setAsParentNodeOf(this.selector) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SynchronizedStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SynchronizedStmt.txt
new file mode 100644
index 0000000..7446d2e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_SynchronizedStmt.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.stmt.SynchronizedStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) setExpr(expr) ==> void
+  Line 42) setBlock(block) ==> void
+  Line 48) beginLine ==> int
+  Line 48) beginColumn ==> int
+  Line 48) endLine ==> int
+  Line 48) endColumn ==> int
+  Line 49) setExpr(expr) ==> void
+  Line 50) setBlock(block) ==> void
+  Line 55) v.visit(this, arg) ==> R
+  Line 60) v.visit(this, arg) ==> void
+  Line 64) block ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 68) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 72) this.block = block ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 73) setAsParentNodeOf(this.block) ==> void
+  Line 77) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 78) setAsParentNodeOf(this.expr) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ThrowStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ThrowStmt.txt
new file mode 100644
index 0000000..33d57dc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_ThrowStmt.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.stmt.ThrowStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 39) setExpr(expr) ==> void
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 45) setExpr(expr) ==> void
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) expr ==> com.github.javaparser.ast.expr.Expression
+  Line 61) this.expr = expr ==> com.github.javaparser.ast.expr.Expression
+  Line 62) setAsParentNodeOf(this.expr) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_TryStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_TryStmt.txt
new file mode 100644
index 0000000..1e652ed
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_TryStmt.txt
@@ -0,0 +1,31 @@
+
+[ Class com.github.javaparser.ast.stmt.TryStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 48) setTryBlock(tryBlock) ==> void
+  Line 49) setCatchs(catchs) ==> void
+  Line 50) setFinallyBlock(finallyBlock) ==> void
+  Line 56) beginLine ==> int
+  Line 56) beginColumn ==> int
+  Line 56) endLine ==> int
+  Line 56) endColumn ==> int
+  Line 57) setResources(resources) ==> void
+  Line 58) setTryBlock(tryBlock) ==> void
+  Line 59) setCatchs(catchs) ==> void
+  Line 60) setFinallyBlock(finallyBlock) ==> void
+  Line 65) v.visit(this, arg) ==> R
+  Line 70) v.visit(this, arg) ==> void
+  Line 74) catchs ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 78) finallyBlock ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 82) tryBlock ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 86) resources ==> java.util.List<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 90) this.catchs = catchs ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 91) setAsParentNodeOf(this.catchs) ==> void
+  Line 95) this.finallyBlock = finallyBlock ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 96) setAsParentNodeOf(this.finallyBlock) ==> void
+  Line 100) this.tryBlock = tryBlock ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 101) setAsParentNodeOf(this.tryBlock) ==> void
+  Line 105) this.resources = resources ==> java.util.List<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 106) setAsParentNodeOf(this.resources) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_TypeDeclarationStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_TypeDeclarationStmt.txt
new file mode 100644
index 0000000..f301fb0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_TypeDeclarationStmt.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.stmt.TypeDeclarationStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 39) setTypeDeclaration(typeDecl) ==> void
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 45) setTypeDeclaration(typeDecl) ==> void
+  Line 49) v.visit(this, arg) ==> R
+  Line 53) v.visit(this, arg) ==> void
+  Line 57) typeDecl ==> com.github.javaparser.ast.body.TypeDeclaration
+  Line 61) this.typeDecl = typeDecl ==> com.github.javaparser.ast.body.TypeDeclaration
+  Line 62) setAsParentNodeOf(this.typeDecl) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_WhileStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_WhileStmt.txt
new file mode 100644
index 0000000..0444034
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_stmt_WhileStmt.txt
@@ -0,0 +1,22 @@
+
+[ Class com.github.javaparser.ast.stmt.WhileStmt ]
+  superclass: com.github.javaparser.ast.stmt.Statement
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) setCondition(condition) ==> void
+  Line 42) setBody(body) ==> void
+  Line 47) beginLine ==> int
+  Line 47) beginColumn ==> int
+  Line 47) endLine ==> int
+  Line 47) endColumn ==> int
+  Line 48) setCondition(condition) ==> void
+  Line 49) setBody(body) ==> void
+  Line 53) v.visit(this, arg) ==> R
+  Line 57) v.visit(this, arg) ==> void
+  Line 61) body ==> com.github.javaparser.ast.stmt.Statement
+  Line 65) condition ==> com.github.javaparser.ast.expr.Expression
+  Line 69) this.body = body ==> com.github.javaparser.ast.stmt.Statement
+  Line 70) setAsParentNodeOf(this.body) ==> void
+  Line 74) this.condition = condition ==> com.github.javaparser.ast.expr.Expression
+  Line 75) setAsParentNodeOf(this.condition) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_ClassOrInterfaceType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_ClassOrInterfaceType.txt
new file mode 100644
index 0000000..2ab2e64
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_ClassOrInterfaceType.txt
@@ -0,0 +1,30 @@
+
+[ Class com.github.javaparser.ast.type.ClassOrInterfaceType ]
+  superclass: com.github.javaparser.ast.type.Type
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 44) setName(name) ==> void
+  Line 48) setScope(scope) ==> void
+  Line 49) setName(name) ==> void
+  Line 54) beginLine ==> int
+  Line 54) beginColumn ==> int
+  Line 54) endLine ==> int
+  Line 54) endColumn ==> int
+  Line 55) setScope(scope) ==> void
+  Line 56) setName(name) ==> void
+  Line 57) setTypeArgs(typeArgs) ==> void
+  Line 62) v.visit(this, arg) ==> R
+  Line 67) v.visit(this, arg) ==> void
+  Line 71) name ==> java.lang.String
+  Line 75) scope ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 79) typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 83) PrimitiveType.unboxMap.containsKey(name) ==> boolean
+  Line 87) !isBoxedType() ==> boolean
+  Line 87) new UnsupportedOperationException(name + " isn't a boxed type.") ==> java.lang.UnsupportedOperationException
+  Line 88) new PrimitiveType(PrimitiveType.unboxMap.get(name)) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 92) this.name = name ==> java.lang.String
+  Line 96) this.scope = scope ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 97) setAsParentNodeOf(this.scope) ==> void
+  Line 101) this.typeArgs = typeArgs ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 102) setAsParentNodeOf(this.typeArgs) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_PrimitiveType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_PrimitiveType.txt
new file mode 100644
index 0000000..3d89a99
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_PrimitiveType.txt
@@ -0,0 +1,23 @@
+
+[ Class com.github.javaparser.ast.type.PrimitiveType ]
+  superclass: com.github.javaparser.ast.type.Type
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 47) new ClassOrInterfaceType(nameOfBoxedType) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 51) this.nameOfBoxedType = nameOfBoxedType ==> java.lang.String
+  Line 55) new HashMap<String, Primitive>() ==> java.util.HashMap<java.lang.String, com.github.javaparser.ast.type.PrimitiveType.Primitive>
+  Line 57) Primitive unboxedType ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 57) Primitive.values() ==> com.github.javaparser.ast.type.PrimitiveType.Primitive[]
+  Line 58) unboxMap.put(unboxedType.nameOfBoxedType, unboxedType) ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 68) this.type = type ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 73) beginLine ==> int
+  Line 73) beginColumn ==> int
+  Line 73) endLine ==> int
+  Line 73) endColumn ==> int
+  Line 74) this.type = type ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 78) v.visit(this, arg) ==> R
+  Line 82) v.visit(this, arg) ==> void
+  Line 86) type ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 90) type.toBoxedType() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 94) this.type = type ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_ReferenceType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_ReferenceType.txt
new file mode 100644
index 0000000..57b9197
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_ReferenceType.txt
@@ -0,0 +1,32 @@
+
+[ Class com.github.javaparser.ast.type.ReferenceType ]
+  superclass: com.github.javaparser.ast.type.Type
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 45) setType(type) ==> void
+  Line 49) setType(type) ==> void
+  Line 50) setArrayCount(arrayCount) ==> void
+  Line 55) beginLine ==> int
+  Line 55) beginColumn ==> int
+  Line 55) endLine ==> int
+  Line 55) endColumn ==> int
+  Line 56) setType(type) ==> void
+  Line 57) setArrayCount(arrayCount) ==> void
+  Line 64) beginLine ==> int
+  Line 64) beginColumn ==> int
+  Line 64) endLine ==> int
+  Line 64) endColumn ==> int
+  Line 64) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 65) setType(type) ==> void
+  Line 66) setArrayCount(arrayCount) ==> void
+  Line 67) this.arraysAnnotations = arraysAnnotations ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 71) v.visit(this, arg) ==> R
+  Line 75) v.visit(this, arg) ==> void
+  Line 79) arrayCount ==> int
+  Line 83) type ==> com.github.javaparser.ast.type.Type
+  Line 87) this.arrayCount = arrayCount ==> int
+  Line 91) this.type = type ==> com.github.javaparser.ast.type.Type
+  Line 92) setAsParentNodeOf(this.type) ==> void
+  Line 116) arraysAnnotations ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 123) this.arraysAnnotations = arraysAnnotations ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_Type.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_Type.txt
new file mode 100644
index 0000000..047008c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_Type.txt
@@ -0,0 +1,17 @@
+
+[ Class com.github.javaparser.ast.type.Type ]
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) this.annotations = annotation ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 44) beginLine ==> int
+  Line 44) beginColumn ==> int
+  Line 44) endLine ==> int
+  Line 44) endColumn ==> int
+  Line 48) beginLine ==> int
+  Line 48) beginColumn ==> int
+  Line 48) endLine ==> int
+  Line 48) endColumn ==> int
+  Line 49) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 53) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 57) this.annotations = annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_UnknownType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_UnknownType.txt
new file mode 100644
index 0000000..adf1344
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_UnknownType.txt
@@ -0,0 +1,8 @@
+
+[ Class com.github.javaparser.ast.type.UnknownType ]
+  superclass: com.github.javaparser.ast.type.Type
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 41) v.visit(this, arg) ==> R
+  Line 46) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_VoidType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_VoidType.txt
new file mode 100644
index 0000000..f59d930
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_VoidType.txt
@@ -0,0 +1,12 @@
+
+[ Class com.github.javaparser.ast.type.VoidType ]
+  superclass: com.github.javaparser.ast.type.Type
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 36) beginLine ==> int
+  Line 36) beginColumn ==> int
+  Line 36) endLine ==> int
+  Line 36) endColumn ==> int
+  Line 40) v.visit(this, arg) ==> R
+  Line 44) v.visit(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_WildcardType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_WildcardType.txt
new file mode 100644
index 0000000..03636f8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_type_WildcardType.txt
@@ -0,0 +1,23 @@
+
+[ Class com.github.javaparser.ast.type.WildcardType ]
+  superclass: com.github.javaparser.ast.type.Type
+  superclass: com.github.javaparser.ast.Node
+  superclass: java.lang.Object
+  interface: java.lang.Cloneable
+  Line 40) setExtends(ext) ==> void
+  Line 44) setExtends(ext) ==> void
+  Line 45) setSuper(sup) ==> void
+  Line 50) beginLine ==> int
+  Line 50) beginColumn ==> int
+  Line 50) endLine ==> int
+  Line 50) endColumn ==> int
+  Line 51) setExtends(ext) ==> void
+  Line 52) setSuper(sup) ==> void
+  Line 56) v.visit(this, arg) ==> R
+  Line 60) v.visit(this, arg) ==> void
+  Line 64) ext ==> com.github.javaparser.ast.type.ReferenceType
+  Line 68) sup ==> com.github.javaparser.ast.type.ReferenceType
+  Line 72) this.ext = ext ==> com.github.javaparser.ast.type.ReferenceType
+  Line 73) setAsParentNodeOf(this.ext) ==> void
+  Line 77) this.sup = sup ==> com.github.javaparser.ast.type.ReferenceType
+  Line 78) setAsParentNodeOf(this.sup) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_CloneVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_CloneVisitor.txt
new file mode 100644
index 0000000..f5bd81b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_CloneVisitor.txt
@@ -0,0 +1,819 @@
+
+[ Class com.github.javaparser.ast.visitor.CloneVisitor ]
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.visitor.GenericVisitor
+  Line 62) PackageDeclaration package_ = cloneNodes(_n.getPackage(), _arg) ==> com.github.javaparser.ast.PackageDeclaration
+  Line 62) cloneNodes(_n.getPackage(), _arg) ==> com.github.javaparser.ast.PackageDeclaration
+  Line 63) List<ImportDeclaration> imports = visit(_n.getImports(), _arg) ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 63) visit(_n.getImports(), _arg) ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 64) List<TypeDeclaration> types = visit(_n.getTypes(), _arg) ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 64) visit(_n.getTypes(), _arg) ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 66) new CompilationUnit(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), package_, imports, types) ==> com.github.javaparser.ast.CompilationUnit
+  Line 74) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 74) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 75) NameExpr name = cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 75) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 76) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 76) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 78) PackageDeclaration r = new PackageDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), annotations, name) ==> com.github.javaparser.ast.PackageDeclaration
+  Line 78) new PackageDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), annotations, name) ==> com.github.javaparser.ast.PackageDeclaration
+  Line 82) r.setComment(comment) ==> void
+  Line 83) r ==> com.github.javaparser.ast.PackageDeclaration
+  Line 88) NameExpr name = cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 88) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 89) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 89) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 91) ImportDeclaration r = new ImportDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, _n.isStatic(), _n.isAsterisk()) ==> com.github.javaparser.ast.ImportDeclaration
+  Line 91) new ImportDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, _n.isStatic(), _n.isAsterisk()) ==> com.github.javaparser.ast.ImportDeclaration
+  Line 95) r.setComment(comment) ==> void
+  Line 96) r ==> com.github.javaparser.ast.ImportDeclaration
+  Line 101) List<ClassOrInterfaceType> typeBound = visit(_n.getTypeBound(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 101) visit(_n.getTypeBound(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 103) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 103) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 104) TypeParameter r = new TypeParameter(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName(), typeBound, annotations) ==> com.github.javaparser.ast.TypeParameter
+  Line 104) new TypeParameter(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName(), typeBound, annotations) ==> com.github.javaparser.ast.TypeParameter
+  Line 108) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 108) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 109) r.setComment(comment) ==> void
+  Line 110) r ==> com.github.javaparser.ast.TypeParameter
+  Line 115) new LineComment(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getContent()) ==> com.github.javaparser.ast.comments.LineComment
+  Line 120) new BlockComment(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getContent()) ==> com.github.javaparser.ast.comments.BlockComment
+  Line 125) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 125) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 126) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 126) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 127) List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 127) visit(_n.getTypeParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 128) List<ClassOrInterfaceType> extendsList = visit(_n.getExtends(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 128) visit(_n.getExtends(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 129) List<ClassOrInterfaceType> implementsList = visit(_n.getImplements(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 129) visit(_n.getImplements(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 130) List<BodyDeclaration> members = visit(_n.getMembers(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 130) visit(_n.getMembers(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 131) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 131) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 133) ClassOrInterfaceDeclaration r = new ClassOrInterfaceDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, _n.isInterface(), _n.getName(), typeParameters, extendsList, implementsList, members) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 133) new ClassOrInterfaceDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, _n.isInterface(), _n.getName(), typeParameters, extendsList, implementsList, members) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 137) r.setComment(comment) ==> void
+  Line 138) r ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 143) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 143) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 144) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 144) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 145) List<ClassOrInterfaceType> implementsList = visit(_n.getImplements(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 145) visit(_n.getImplements(), _arg) ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 146) List<EnumConstantDeclaration> entries = visit(_n.getEntries(), _arg) ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 146) visit(_n.getEntries(), _arg) ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 147) List<BodyDeclaration> members = visit(_n.getMembers(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 147) visit(_n.getMembers(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 148) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 148) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 150) EnumDeclaration r = new EnumDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, _n.getName(), implementsList, entries, members) ==> com.github.javaparser.ast.body.EnumDeclaration
+  Line 150) new EnumDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, _n.getName(), implementsList, entries, members) ==> com.github.javaparser.ast.body.EnumDeclaration
+  Line 154) r.setComment(comment) ==> void
+  Line 155) r ==> com.github.javaparser.ast.body.EnumDeclaration
+  Line 160) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 160) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 161) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 161) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 163) EmptyTypeDeclaration r = new EmptyTypeDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.body.EmptyTypeDeclaration
+  Line 163) new EmptyTypeDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.body.EmptyTypeDeclaration
+  Line 166) r.setComment(comment) ==> void
+  Line 167) r ==> com.github.javaparser.ast.body.EmptyTypeDeclaration
+  Line 172) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 172) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 173) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 173) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 174) List<Expression> args = visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 174) visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 175) List<BodyDeclaration> classBody = visit(_n.getClassBody(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 175) visit(_n.getClassBody(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 176) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 176) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 178) EnumConstantDeclaration r = new EnumConstantDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), annotations, _n.getName(), args, classBody) ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 178) new EnumConstantDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), annotations, _n.getName(), args, classBody) ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 182) r.setComment(comment) ==> void
+  Line 183) r ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 188) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 188) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 189) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 189) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 190) List<BodyDeclaration> members = visit(_n.getMembers(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 190) visit(_n.getMembers(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 191) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 191) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 193) AnnotationDeclaration r = new AnnotationDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, _n.getName(), members) ==> com.github.javaparser.ast.body.AnnotationDeclaration
+  Line 193) new AnnotationDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, _n.getName(), members) ==> com.github.javaparser.ast.body.AnnotationDeclaration
+  Line 197) r.setComment(comment) ==> void
+  Line 198) r ==> com.github.javaparser.ast.body.AnnotationDeclaration
+  Line 203) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 203) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 204) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 204) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 205) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 205) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 206) Expression defaultValue = cloneNodes(_n.getDefaultValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 206) cloneNodes(_n.getDefaultValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 207) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 207) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 209) AnnotationMemberDeclaration r = new AnnotationMemberDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, _n.getName(), defaultValue) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration
+  Line 209) new AnnotationMemberDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, _n.getName(), defaultValue) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration
+  Line 213) r.setComment(comment) ==> void
+  Line 214) r ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration
+  Line 219) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 219) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 220) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 220) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 221) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 221) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 222) List<VariableDeclarator> variables = visit(_n.getVariables(), _arg) ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 222) visit(_n.getVariables(), _arg) ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 223) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 223) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 225) FieldDeclaration r = new FieldDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, variables) ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 225) new FieldDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, variables) ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 229) r.setComment(comment) ==> void
+  Line 230) r ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 235) VariableDeclaratorId id = cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 235) cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 236) Expression init = cloneNodes(_n.getInit(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 236) cloneNodes(_n.getInit(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 237) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 237) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 239) VariableDeclarator r = new VariableDeclarator(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), id, init) ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 239) new VariableDeclarator(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), id, init) ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 243) r.setComment(comment) ==> void
+  Line 244) r ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 249) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 249) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 251) VariableDeclaratorId r = new VariableDeclaratorId(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName(), _n.getArrayCount()) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 251) new VariableDeclaratorId(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName(), _n.getArrayCount()) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 255) r.setComment(comment) ==> void
+  Line 256) r ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 261) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 261) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 262) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 262) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 263) List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 263) visit(_n.getTypeParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 264) List<Parameter> parameters = visit(_n.getParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 264) visit(_n.getParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 265) List<NameExpr> throws_ = visit(_n.getThrows(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 265) visit(_n.getThrows(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 266) BlockStmt block = cloneNodes(_n.getBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 266) cloneNodes(_n.getBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 267) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 267) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 269) ConstructorDeclaration r = new ConstructorDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, typeParameters, _n.getName(), parameters, throws_, block) ==> com.github.javaparser.ast.body.ConstructorDeclaration
+  Line 269) new ConstructorDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, typeParameters, _n.getName(), parameters, throws_, block) ==> com.github.javaparser.ast.body.ConstructorDeclaration
+  Line 273) r.setComment(comment) ==> void
+  Line 274) r ==> com.github.javaparser.ast.body.ConstructorDeclaration
+  Line 279) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 279) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 280) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 280) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 281) List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 281) visit(_n.getTypeParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 282) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 282) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 283) List<Parameter> parameters = visit(_n.getParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 283) visit(_n.getParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 284) List<NameExpr> throws_ = visit(_n.getThrows(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 284) visit(_n.getThrows(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 285) BlockStmt block = cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 285) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 286) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 286) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 288) MethodDeclaration r = new MethodDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, typeParameters, type_, _n.getName(), parameters, _n.getArrayCount(), throws_, block) ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 288) new MethodDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, typeParameters, type_, _n.getName(), parameters, _n.getArrayCount(), throws_, block) ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 292) r.setComment(comment) ==> void
+  Line 293) r ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 298) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 298) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 299) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 299) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 300) VariableDeclaratorId id = cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 300) cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 301) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 301) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 303) Parameter r = new Parameter(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, _n.isVarArgs(), id) ==> com.github.javaparser.ast.body.Parameter
+  Line 303) new Parameter(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, _n.isVarArgs(), id) ==> com.github.javaparser.ast.body.Parameter
+  Line 307) r.setComment(comment) ==> void
+  Line 308) r ==> com.github.javaparser.ast.body.Parameter
+  Line 313) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 313) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 314) List<Type> types = visit(_n.getTypes(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 314) visit(_n.getTypes(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 315) VariableDeclaratorId id = cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 315) cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 316) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 316) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 318) MultiTypeParameter r = new MultiTypeParameter(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, types, id) ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 318) new MultiTypeParameter(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, types, id) ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 322) r.setComment(comment) ==> void
+  Line 323) r ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 328) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 328) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 329) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 329) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 331) EmptyMemberDeclaration r = new EmptyMemberDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.body.EmptyMemberDeclaration
+  Line 331) new EmptyMemberDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.body.EmptyMemberDeclaration
+  Line 334) r.setComment(comment) ==> void
+  Line 335) r ==> com.github.javaparser.ast.body.EmptyMemberDeclaration
+  Line 340) JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 340) cloneNodes(_n.getJavaDoc(), _arg) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 341) BlockStmt block = cloneNodes(_n.getBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 341) cloneNodes(_n.getBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 342) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 342) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 344) InitializerDeclaration r = new InitializerDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.isStatic(), block) ==> com.github.javaparser.ast.body.InitializerDeclaration
+  Line 344) new InitializerDeclaration(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.isStatic(), block) ==> com.github.javaparser.ast.body.InitializerDeclaration
+  Line 348) r.setComment(comment) ==> void
+  Line 349) r ==> com.github.javaparser.ast.body.InitializerDeclaration
+  Line 354) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 354) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 355) JavadocComment r = new JavadocComment(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getContent()) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 355) new JavadocComment(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getContent()) ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 359) r.setComment(comment) ==> void
+  Line 360) r ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 365) ClassOrInterfaceType scope = cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 365) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 366) List<Type> typeArgs = visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 366) visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 367) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 367) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 369) ClassOrInterfaceType r = new ClassOrInterfaceType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, _n.getName(), typeArgs) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 369) new ClassOrInterfaceType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, _n.getName(), typeArgs) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 373) r.setComment(comment) ==> void
+  Line 374) r ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 379) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 379) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 381) PrimitiveType r = new PrimitiveType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getType()) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 381) new PrimitiveType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getType()) ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 385) r.setComment(comment) ==> void
+  Line 386) r ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 391) List<AnnotationExpr> ann = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 391) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 392) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 392) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 393) List<List<AnnotationExpr>> arraysAnnotations = _n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 393) _n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 394) List<List<AnnotationExpr>> _arraysAnnotations = null ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 394) null ==> null
+  Line 395) arraysAnnotations != null ==> boolean
+  Line 396) _arraysAnnotations = new LinkedList<List<AnnotationExpr>>() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 397) List<AnnotationExpr> aux ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 397) arraysAnnotations ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 398) _arraysAnnotations.add(visit(aux, _arg)) ==> boolean
+  Line 402) ReferenceType r = new ReferenceType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_, _n.getArrayCount(), ann, _arraysAnnotations) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 402) new ReferenceType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_, _n.getArrayCount(), ann, _arraysAnnotations) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 405) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 405) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 406) r.setComment(comment) ==> void
+  Line 407) r ==> com.github.javaparser.ast.type.ReferenceType
+  Line 412) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 412) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 414) VoidType r = new VoidType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.type.VoidType
+  Line 414) new VoidType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.type.VoidType
+  Line 415) r.setComment(comment) ==> void
+  Line 416) r ==> com.github.javaparser.ast.type.VoidType
+  Line 421) ReferenceType ext = cloneNodes(_n.getExtends(), _arg) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 421) cloneNodes(_n.getExtends(), _arg) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 422) ReferenceType sup = cloneNodes(_n.getSuper(), _arg) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 422) cloneNodes(_n.getSuper(), _arg) ==> com.github.javaparser.ast.type.ReferenceType
+  Line 423) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 423) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 425) WildcardType r = new WildcardType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), ext, sup) ==> com.github.javaparser.ast.type.WildcardType
+  Line 425) new WildcardType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), ext, sup) ==> com.github.javaparser.ast.type.WildcardType
+  Line 429) r.setComment(comment) ==> void
+  Line 430) r ==> com.github.javaparser.ast.type.WildcardType
+  Line 435) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 435) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 437) UnknownType r = new UnknownType() ==> com.github.javaparser.ast.type.UnknownType
+  Line 437) new UnknownType() ==> com.github.javaparser.ast.type.UnknownType
+  Line 438) r.setComment(comment) ==> void
+  Line 439) r ==> com.github.javaparser.ast.type.UnknownType
+  Line 444) Expression name = cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 444) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 445) Expression index = cloneNodes(_n.getIndex(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 445) cloneNodes(_n.getIndex(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 446) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 446) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 448) ArrayAccessExpr r = new ArrayAccessExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, index) ==> com.github.javaparser.ast.expr.ArrayAccessExpr
+  Line 448) new ArrayAccessExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, index) ==> com.github.javaparser.ast.expr.ArrayAccessExpr
+  Line 452) r.setComment(comment) ==> void
+  Line 453) r ==> com.github.javaparser.ast.expr.ArrayAccessExpr
+  Line 458) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 458) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 459) List<Expression> dimensions = visit(_n.getDimensions(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 459) visit(_n.getDimensions(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 460) ArrayCreationExpr r = new ArrayCreationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_, dimensions, _n.getArrayCount()) ==> com.github.javaparser.ast.expr.ArrayCreationExpr
+  Line 460) new ArrayCreationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_, dimensions, _n.getArrayCount()) ==> com.github.javaparser.ast.expr.ArrayCreationExpr
+  Line 463) _n.getInitializer() != null ==> boolean
+  Line 465) r.setInitializer(cloneNodes(_n.getInitializer(), _arg)) ==> void
+  Line 467) List<List<AnnotationExpr>> arraysAnnotations = _n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 467) _n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 468) List<List<AnnotationExpr>> _arraysAnnotations = null ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 468) null ==> null
+  Line 469) arraysAnnotations != null ==> boolean
+  Line 470) _arraysAnnotations = new LinkedList<List<AnnotationExpr>>() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 471) List<AnnotationExpr> aux ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 471) arraysAnnotations ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 472) _arraysAnnotations.add(visit(aux, _arg)) ==> boolean
+  Line 475) r.setArraysAnnotations(_arraysAnnotations) ==> void
+  Line 476) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 476) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 477) r.setComment(comment) ==> void
+  Line 478) r ==> com.github.javaparser.ast.expr.ArrayCreationExpr
+  Line 483) List<Expression> values = visit(_n.getValues(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 483) visit(_n.getValues(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 484) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 484) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 486) ArrayInitializerExpr r = new ArrayInitializerExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), values) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 486) new ArrayInitializerExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), values) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 490) r.setComment(comment) ==> void
+  Line 491) r ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 496) Expression target = cloneNodes(_n.getTarget(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 496) cloneNodes(_n.getTarget(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 497) Expression value = cloneNodes(_n.getValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 497) cloneNodes(_n.getValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 498) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 498) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 500) AssignExpr r = new AssignExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), target, value, _n.getOperator()) ==> com.github.javaparser.ast.expr.AssignExpr
+  Line 500) new AssignExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), target, value, _n.getOperator()) ==> com.github.javaparser.ast.expr.AssignExpr
+  Line 503) r.setComment(comment) ==> void
+  Line 504) r ==> com.github.javaparser.ast.expr.AssignExpr
+  Line 509) Expression left = cloneNodes(_n.getLeft(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 509) cloneNodes(_n.getLeft(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 510) Expression right = cloneNodes(_n.getRight(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 510) cloneNodes(_n.getRight(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 511) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 511) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 513) BinaryExpr r = new BinaryExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), left, right, _n.getOperator()) ==> com.github.javaparser.ast.expr.BinaryExpr
+  Line 513) new BinaryExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), left, right, _n.getOperator()) ==> com.github.javaparser.ast.expr.BinaryExpr
+  Line 517) r.setComment(comment) ==> void
+  Line 518) r ==> com.github.javaparser.ast.expr.BinaryExpr
+  Line 523) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 523) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 524) Expression expr = cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 524) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 525) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 525) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 527) CastExpr r = new CastExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_, expr) ==> com.github.javaparser.ast.expr.CastExpr
+  Line 527) new CastExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_, expr) ==> com.github.javaparser.ast.expr.CastExpr
+  Line 531) r.setComment(comment) ==> void
+  Line 532) r ==> com.github.javaparser.ast.expr.CastExpr
+  Line 537) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 537) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 538) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 538) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 540) ClassExpr r = new ClassExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_) ==> com.github.javaparser.ast.expr.ClassExpr
+  Line 540) new ClassExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_) ==> com.github.javaparser.ast.expr.ClassExpr
+  Line 544) r.setComment(comment) ==> void
+  Line 545) r ==> com.github.javaparser.ast.expr.ClassExpr
+  Line 550) Expression condition = cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 550) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 551) Expression thenExpr = cloneNodes(_n.getThenExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 551) cloneNodes(_n.getThenExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 552) Expression elseExpr = cloneNodes(_n.getElseExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 552) cloneNodes(_n.getElseExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 553) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 553) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 555) ConditionalExpr r = new ConditionalExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), condition, thenExpr, elseExpr) ==> com.github.javaparser.ast.expr.ConditionalExpr
+  Line 555) new ConditionalExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), condition, thenExpr, elseExpr) ==> com.github.javaparser.ast.expr.ConditionalExpr
+  Line 559) r.setComment(comment) ==> void
+  Line 560) r ==> com.github.javaparser.ast.expr.ConditionalExpr
+  Line 565) Expression inner = cloneNodes(_n.getInner(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 565) cloneNodes(_n.getInner(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 566) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 566) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 568) EnclosedExpr r = new EnclosedExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), inner) ==> com.github.javaparser.ast.expr.EnclosedExpr
+  Line 568) new EnclosedExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), inner) ==> com.github.javaparser.ast.expr.EnclosedExpr
+  Line 572) r.setComment(comment) ==> void
+  Line 573) r ==> com.github.javaparser.ast.expr.EnclosedExpr
+  Line 578) Expression scope = cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 578) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 579) List<Type> typeArgs = visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 579) visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 580) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 580) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 582) FieldAccessExpr r = new FieldAccessExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, typeArgs, _n.getField()) ==> com.github.javaparser.ast.expr.FieldAccessExpr
+  Line 582) new FieldAccessExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, typeArgs, _n.getField()) ==> com.github.javaparser.ast.expr.FieldAccessExpr
+  Line 586) r.setComment(comment) ==> void
+  Line 587) r ==> com.github.javaparser.ast.expr.FieldAccessExpr
+  Line 592) Expression expr = cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 592) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 593) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 593) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 594) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 594) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 596) InstanceOfExpr r = new InstanceOfExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr, type_) ==> com.github.javaparser.ast.expr.InstanceOfExpr
+  Line 596) new InstanceOfExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr, type_) ==> com.github.javaparser.ast.expr.InstanceOfExpr
+  Line 600) r.setComment(comment) ==> void
+  Line 601) r ==> com.github.javaparser.ast.expr.InstanceOfExpr
+  Line 606) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 606) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 607) StringLiteralExpr r = new StringLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.StringLiteralExpr
+  Line 607) new StringLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.StringLiteralExpr
+  Line 611) r.setComment(comment) ==> void
+  Line 612) r ==> com.github.javaparser.ast.expr.StringLiteralExpr
+  Line 617) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 617) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 619) IntegerLiteralExpr r = new IntegerLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.IntegerLiteralExpr
+  Line 619) new IntegerLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.IntegerLiteralExpr
+  Line 623) r.setComment(comment) ==> void
+  Line 624) r ==> com.github.javaparser.ast.expr.IntegerLiteralExpr
+  Line 629) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 629) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 631) LongLiteralExpr r = new LongLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.LongLiteralExpr
+  Line 631) new LongLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.LongLiteralExpr
+  Line 635) r.setComment(comment) ==> void
+  Line 636) r ==> com.github.javaparser.ast.expr.LongLiteralExpr
+  Line 641) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 641) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 643) IntegerLiteralMinValueExpr r = new IntegerLiteralMinValueExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr
+  Line 643) new IntegerLiteralMinValueExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr
+  Line 644) r.setComment(comment) ==> void
+  Line 645) r ==> com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr
+  Line 650) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 650) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 652) LongLiteralMinValueExpr r = new LongLiteralMinValueExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.expr.LongLiteralMinValueExpr
+  Line 652) new LongLiteralMinValueExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.expr.LongLiteralMinValueExpr
+  Line 653) r.setComment(comment) ==> void
+  Line 654) r ==> com.github.javaparser.ast.expr.LongLiteralMinValueExpr
+  Line 659) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 659) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 661) CharLiteralExpr r = new CharLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.CharLiteralExpr
+  Line 661) new CharLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.CharLiteralExpr
+  Line 665) r.setComment(comment) ==> void
+  Line 666) r ==> com.github.javaparser.ast.expr.CharLiteralExpr
+  Line 671) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 671) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 673) DoubleLiteralExpr r = new DoubleLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.DoubleLiteralExpr
+  Line 673) new DoubleLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.DoubleLiteralExpr
+  Line 677) r.setComment(comment) ==> void
+  Line 678) r ==> com.github.javaparser.ast.expr.DoubleLiteralExpr
+  Line 683) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 683) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 685) BooleanLiteralExpr r = new BooleanLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.BooleanLiteralExpr
+  Line 685) new BooleanLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getValue()) ==> com.github.javaparser.ast.expr.BooleanLiteralExpr
+  Line 689) r.setComment(comment) ==> void
+  Line 690) r ==> com.github.javaparser.ast.expr.BooleanLiteralExpr
+  Line 695) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 695) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 697) NullLiteralExpr r = new NullLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.expr.NullLiteralExpr
+  Line 697) new NullLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.expr.NullLiteralExpr
+  Line 698) r.setComment(comment) ==> void
+  Line 699) r ==> com.github.javaparser.ast.expr.NullLiteralExpr
+  Line 704) Expression scope = cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 704) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 705) List<Type> typeArgs = visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 705) visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 706) List<Expression> args = visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 706) visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 707) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 707) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 709) MethodCallExpr r = new MethodCallExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, typeArgs, _n.getName(), args) ==> com.github.javaparser.ast.expr.MethodCallExpr
+  Line 709) new MethodCallExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, typeArgs, _n.getName(), args) ==> com.github.javaparser.ast.expr.MethodCallExpr
+  Line 713) r.setComment(comment) ==> void
+  Line 714) r ==> com.github.javaparser.ast.expr.MethodCallExpr
+  Line 719) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 719) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 721) NameExpr r = new NameExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName()) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 721) new NameExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName()) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 725) r.setComment(comment) ==> void
+  Line 726) r ==> com.github.javaparser.ast.expr.NameExpr
+  Line 731) Expression scope = cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 731) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 732) ClassOrInterfaceType type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 732) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 733) List<Type> typeArgs = visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 733) visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 734) List<Expression> args = visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 734) visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 735) List<BodyDeclaration> anonymousBody = visit(_n.getAnonymousClassBody(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 735) visit(_n.getAnonymousClassBody(), _arg) ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 736) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 736) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 738) ObjectCreationExpr r = new ObjectCreationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, type_, typeArgs, args, anonymousBody) ==> com.github.javaparser.ast.expr.ObjectCreationExpr
+  Line 738) new ObjectCreationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, type_, typeArgs, args, anonymousBody) ==> com.github.javaparser.ast.expr.ObjectCreationExpr
+  Line 742) r.setComment(comment) ==> void
+  Line 743) r ==> com.github.javaparser.ast.expr.ObjectCreationExpr
+  Line 748) NameExpr scope = cloneNodes(_n.getQualifier(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 748) cloneNodes(_n.getQualifier(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 749) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 749) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 751) QualifiedNameExpr r = new QualifiedNameExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, _n.getName()) ==> com.github.javaparser.ast.expr.QualifiedNameExpr
+  Line 751) new QualifiedNameExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, _n.getName()) ==> com.github.javaparser.ast.expr.QualifiedNameExpr
+  Line 755) r.setComment(comment) ==> void
+  Line 756) r ==> com.github.javaparser.ast.expr.QualifiedNameExpr
+  Line 761) Expression classExpr = cloneNodes(_n.getClassExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 761) cloneNodes(_n.getClassExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 762) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 762) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 764) ThisExpr r = new ThisExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), classExpr) ==> com.github.javaparser.ast.expr.ThisExpr
+  Line 764) new ThisExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), classExpr) ==> com.github.javaparser.ast.expr.ThisExpr
+  Line 768) r.setComment(comment) ==> void
+  Line 769) r ==> com.github.javaparser.ast.expr.ThisExpr
+  Line 774) Expression classExpr = cloneNodes(_n.getClassExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 774) cloneNodes(_n.getClassExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 775) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 775) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 777) SuperExpr r = new SuperExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), classExpr) ==> com.github.javaparser.ast.expr.SuperExpr
+  Line 777) new SuperExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), classExpr) ==> com.github.javaparser.ast.expr.SuperExpr
+  Line 781) r.setComment(comment) ==> void
+  Line 782) r ==> com.github.javaparser.ast.expr.SuperExpr
+  Line 787) Expression expr = cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 787) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 788) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 788) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 790) UnaryExpr r = new UnaryExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr, _n.getOperator()) ==> com.github.javaparser.ast.expr.UnaryExpr
+  Line 790) new UnaryExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr, _n.getOperator()) ==> com.github.javaparser.ast.expr.UnaryExpr
+  Line 794) r.setComment(comment) ==> void
+  Line 795) r ==> com.github.javaparser.ast.expr.UnaryExpr
+  Line 800) List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 800) visit(_n.getAnnotations(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 801) Type type_ = cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 801) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.type.Type
+  Line 802) List<VariableDeclarator> vars = visit(_n.getVars(), _arg) ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 802) visit(_n.getVars(), _arg) ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 803) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 803) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 805) VariableDeclarationExpr r = new VariableDeclarationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, vars) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 805) new VariableDeclarationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getModifiers(), annotations, type_, vars) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 809) r.setComment(comment) ==> void
+  Line 810) r ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 815) NameExpr name = cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 815) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 816) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 816) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 818) MarkerAnnotationExpr r = new MarkerAnnotationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name) ==> com.github.javaparser.ast.expr.MarkerAnnotationExpr
+  Line 818) new MarkerAnnotationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name) ==> com.github.javaparser.ast.expr.MarkerAnnotationExpr
+  Line 822) r.setComment(comment) ==> void
+  Line 823) r ==> com.github.javaparser.ast.expr.MarkerAnnotationExpr
+  Line 828) NameExpr name = cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 828) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 829) Expression memberValue = cloneNodes(_n.getMemberValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 829) cloneNodes(_n.getMemberValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 830) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 830) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 832) SingleMemberAnnotationExpr r = new SingleMemberAnnotationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, memberValue) ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+  Line 832) new SingleMemberAnnotationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, memberValue) ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+  Line 836) r.setComment(comment) ==> void
+  Line 837) r ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+  Line 842) NameExpr name = cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 842) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 843) List<MemberValuePair> pairs = visit(_n.getPairs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 843) visit(_n.getPairs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 844) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 844) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 846) NormalAnnotationExpr r = new NormalAnnotationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, pairs) ==> com.github.javaparser.ast.expr.NormalAnnotationExpr
+  Line 846) new NormalAnnotationExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), name, pairs) ==> com.github.javaparser.ast.expr.NormalAnnotationExpr
+  Line 850) r.setComment(comment) ==> void
+  Line 851) r ==> com.github.javaparser.ast.expr.NormalAnnotationExpr
+  Line 856) Expression value = cloneNodes(_n.getValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 856) cloneNodes(_n.getValue(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 857) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 857) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 859) MemberValuePair r = new MemberValuePair(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName(), value) ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 859) new MemberValuePair(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getName(), value) ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 863) r.setComment(comment) ==> void
+  Line 864) r ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 869) List<Type> typeArgs = visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 869) visit(_n.getTypeArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 870) Expression expr = cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 870) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 871) List<Expression> args = visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 871) visit(_n.getArgs(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 872) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 872) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 874) ExplicitConstructorInvocationStmt r = new ExplicitConstructorInvocationStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), typeArgs, _n.isThis(), expr, args) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+  Line 874) new ExplicitConstructorInvocationStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), typeArgs, _n.isThis(), expr, args) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+  Line 878) r.setComment(comment) ==> void
+  Line 879) r ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+  Line 884) TypeDeclaration typeDecl = cloneNodes(_n.getTypeDeclaration(), _arg) ==> com.github.javaparser.ast.body.TypeDeclaration
+  Line 884) cloneNodes(_n.getTypeDeclaration(), _arg) ==> com.github.javaparser.ast.body.TypeDeclaration
+  Line 885) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 885) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 887) TypeDeclarationStmt r = new TypeDeclarationStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), typeDecl) ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt
+  Line 887) new TypeDeclarationStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), typeDecl) ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt
+  Line 891) r.setComment(comment) ==> void
+  Line 892) r ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt
+  Line 897) Expression check = cloneNodes(_n.getCheck(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 897) cloneNodes(_n.getCheck(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 898) Expression message = cloneNodes(_n.getMessage(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 898) cloneNodes(_n.getMessage(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 899) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 899) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 901) AssertStmt r = new AssertStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), check, message) ==> com.github.javaparser.ast.stmt.AssertStmt
+  Line 901) new AssertStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), check, message) ==> com.github.javaparser.ast.stmt.AssertStmt
+  Line 905) r.setComment(comment) ==> void
+  Line 906) r ==> com.github.javaparser.ast.stmt.AssertStmt
+  Line 911) List<Statement> stmts = visit(_n.getStmts(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 911) visit(_n.getStmts(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 912) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 912) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 914) BlockStmt r = new BlockStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), stmts) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 914) new BlockStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), stmts) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 918) r.setComment(comment) ==> void
+  Line 919) r ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 924) Statement stmt = cloneNodes(_n.getStmt(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 924) cloneNodes(_n.getStmt(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 925) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 925) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 927) LabeledStmt r = new LabeledStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getLabel(), stmt) ==> com.github.javaparser.ast.stmt.LabeledStmt
+  Line 927) new LabeledStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getLabel(), stmt) ==> com.github.javaparser.ast.stmt.LabeledStmt
+  Line 931) r.setComment(comment) ==> void
+  Line 932) r ==> com.github.javaparser.ast.stmt.LabeledStmt
+  Line 937) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 937) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 939) EmptyStmt r = new EmptyStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.stmt.EmptyStmt
+  Line 939) new EmptyStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()) ==> com.github.javaparser.ast.stmt.EmptyStmt
+  Line 940) r.setComment(comment) ==> void
+  Line 941) r ==> com.github.javaparser.ast.stmt.EmptyStmt
+  Line 946) Expression expr = cloneNodes(_n.getExpression(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 946) cloneNodes(_n.getExpression(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 947) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 947) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 949) ExpressionStmt r = new ExpressionStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr) ==> com.github.javaparser.ast.stmt.ExpressionStmt
+  Line 949) new ExpressionStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr) ==> com.github.javaparser.ast.stmt.ExpressionStmt
+  Line 953) r.setComment(comment) ==> void
+  Line 954) r ==> com.github.javaparser.ast.stmt.ExpressionStmt
+  Line 959) Expression selector = cloneNodes(_n.getSelector(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 959) cloneNodes(_n.getSelector(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 960) List<SwitchEntryStmt> entries = visit(_n.getEntries(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 960) visit(_n.getEntries(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 961) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 961) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 963) SwitchStmt r = new SwitchStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), selector, entries) ==> com.github.javaparser.ast.stmt.SwitchStmt
+  Line 963) new SwitchStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), selector, entries) ==> com.github.javaparser.ast.stmt.SwitchStmt
+  Line 967) r.setComment(comment) ==> void
+  Line 968) r ==> com.github.javaparser.ast.stmt.SwitchStmt
+  Line 973) Expression label = cloneNodes(_n.getLabel(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 973) cloneNodes(_n.getLabel(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 974) List<Statement> stmts = visit(_n.getStmts(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 974) visit(_n.getStmts(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 975) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 975) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 977) SwitchEntryStmt r = new SwitchEntryStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), label, stmts) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 977) new SwitchEntryStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), label, stmts) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 981) r.setComment(comment) ==> void
+  Line 982) r ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 987) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 987) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 989) BreakStmt r = new BreakStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getId()) ==> com.github.javaparser.ast.stmt.BreakStmt
+  Line 989) new BreakStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getId()) ==> com.github.javaparser.ast.stmt.BreakStmt
+  Line 993) r.setComment(comment) ==> void
+  Line 994) r ==> com.github.javaparser.ast.stmt.BreakStmt
+  Line 999) Expression expr = cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 999) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1000) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1000) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1002) ReturnStmt r = new ReturnStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr) ==> com.github.javaparser.ast.stmt.ReturnStmt
+  Line 1002) new ReturnStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr) ==> com.github.javaparser.ast.stmt.ReturnStmt
+  Line 1006) r.setComment(comment) ==> void
+  Line 1007) r ==> com.github.javaparser.ast.stmt.ReturnStmt
+  Line 1012) Expression condition = cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1012) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1013) Statement thenStmt = cloneNodes(_n.getThenStmt(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1013) cloneNodes(_n.getThenStmt(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1014) Statement elseStmt = cloneNodes(_n.getElseStmt(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1014) cloneNodes(_n.getElseStmt(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1015) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1015) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1017) IfStmt r = new IfStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), condition, thenStmt, elseStmt) ==> com.github.javaparser.ast.stmt.IfStmt
+  Line 1017) new IfStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), condition, thenStmt, elseStmt) ==> com.github.javaparser.ast.stmt.IfStmt
+  Line 1021) r.setComment(comment) ==> void
+  Line 1022) r ==> com.github.javaparser.ast.stmt.IfStmt
+  Line 1027) Expression condition = cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1027) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1028) Statement body = cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1028) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1029) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1029) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1031) WhileStmt r = new WhileStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), condition, body) ==> com.github.javaparser.ast.stmt.WhileStmt
+  Line 1031) new WhileStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), condition, body) ==> com.github.javaparser.ast.stmt.WhileStmt
+  Line 1035) r.setComment(comment) ==> void
+  Line 1036) r ==> com.github.javaparser.ast.stmt.WhileStmt
+  Line 1041) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1041) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1043) ContinueStmt r = new ContinueStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getId()) ==> com.github.javaparser.ast.stmt.ContinueStmt
+  Line 1043) new ContinueStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getId()) ==> com.github.javaparser.ast.stmt.ContinueStmt
+  Line 1047) r.setComment(comment) ==> void
+  Line 1048) r ==> com.github.javaparser.ast.stmt.ContinueStmt
+  Line 1053) Statement body = cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1053) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1054) Expression condition = cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1054) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1055) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1055) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1057) DoStmt r = new DoStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), body, condition) ==> com.github.javaparser.ast.stmt.DoStmt
+  Line 1057) new DoStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), body, condition) ==> com.github.javaparser.ast.stmt.DoStmt
+  Line 1061) r.setComment(comment) ==> void
+  Line 1062) r ==> com.github.javaparser.ast.stmt.DoStmt
+  Line 1067) VariableDeclarationExpr var = cloneNodes(_n.getVariable(), _arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 1067) cloneNodes(_n.getVariable(), _arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 1068) Expression iterable = cloneNodes(_n.getIterable(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1068) cloneNodes(_n.getIterable(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1069) Statement body = cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1069) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1070) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1070) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1072) ForeachStmt r = new ForeachStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), var, iterable, body) ==> com.github.javaparser.ast.stmt.ForeachStmt
+  Line 1072) new ForeachStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), var, iterable, body) ==> com.github.javaparser.ast.stmt.ForeachStmt
+  Line 1076) r.setComment(comment) ==> void
+  Line 1077) r ==> com.github.javaparser.ast.stmt.ForeachStmt
+  Line 1082) List<Expression> init = visit(_n.getInit(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 1082) visit(_n.getInit(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 1083) Expression compare = cloneNodes(_n.getCompare(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1083) cloneNodes(_n.getCompare(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1084) List<Expression> update = visit(_n.getUpdate(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 1084) visit(_n.getUpdate(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 1085) Statement body = cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1085) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1086) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1086) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1088) ForStmt r = new ForStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), init, compare, update, body) ==> com.github.javaparser.ast.stmt.ForStmt
+  Line 1088) new ForStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), init, compare, update, body) ==> com.github.javaparser.ast.stmt.ForStmt
+  Line 1092) r.setComment(comment) ==> void
+  Line 1093) r ==> com.github.javaparser.ast.stmt.ForStmt
+  Line 1098) Expression expr = cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1098) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1099) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1099) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1101) ThrowStmt r = new ThrowStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr) ==> com.github.javaparser.ast.stmt.ThrowStmt
+  Line 1101) new ThrowStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr) ==> com.github.javaparser.ast.stmt.ThrowStmt
+  Line 1105) r.setComment(comment) ==> void
+  Line 1106) r ==> com.github.javaparser.ast.stmt.ThrowStmt
+  Line 1111) Expression expr = cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1111) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1112) BlockStmt block = cloneNodes(_n.getBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1112) cloneNodes(_n.getBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1113) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1113) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1115) SynchronizedStmt r = new SynchronizedStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr, block) ==> com.github.javaparser.ast.stmt.SynchronizedStmt
+  Line 1115) new SynchronizedStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), expr, block) ==> com.github.javaparser.ast.stmt.SynchronizedStmt
+  Line 1119) r.setComment(comment) ==> void
+  Line 1120) r ==> com.github.javaparser.ast.stmt.SynchronizedStmt
+  Line 1125) List<VariableDeclarationExpr> resources = visit(_n.getResources(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 1125) visit(_n.getResources(), _arg) ==> java.util.List<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 1126) BlockStmt tryBlock = cloneNodes(_n.getTryBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1126) cloneNodes(_n.getTryBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1127) List<CatchClause> catchs = visit(_n.getCatchs(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 1127) visit(_n.getCatchs(), _arg) ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 1128) BlockStmt finallyBlock = cloneNodes(_n.getFinallyBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1128) cloneNodes(_n.getFinallyBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1129) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1129) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1131) TryStmt r = new TryStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), resources, tryBlock, catchs, finallyBlock) ==> com.github.javaparser.ast.stmt.TryStmt
+  Line 1131) new TryStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), resources, tryBlock, catchs, finallyBlock) ==> com.github.javaparser.ast.stmt.TryStmt
+  Line 1135) r.setComment(comment) ==> void
+  Line 1136) r ==> com.github.javaparser.ast.stmt.TryStmt
+  Line 1141) MultiTypeParameter except = cloneNodes(_n.getExcept(), _arg) ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 1141) cloneNodes(_n.getExcept(), _arg) ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 1142) BlockStmt catchBlock = cloneNodes(_n.getCatchBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1142) cloneNodes(_n.getCatchBlock(), _arg) ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1143) Comment comment = cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1143) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.comments.Comment
+  Line 1145) CatchClause r = new CatchClause(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), except.getModifiers(), except.getAnnotations(), except.getTypes(), except.getId(), catchBlock) ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 1145) new CatchClause(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), except.getModifiers(), except.getAnnotations(), except.getTypes(), except.getId(), catchBlock) ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 1149) r.setComment(comment) ==> void
+  Line 1150) r ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 1156) List<Parameter> lambdaParameters = visit(_n.getParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 1156) visit(_n.getParameters(), _arg) ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 1158) Statement body = cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1158) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.stmt.Statement
+  Line 1160) LambdaExpr r = new LambdaExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), lambdaParameters, body, _n.isParametersEnclosed()) ==> com.github.javaparser.ast.expr.LambdaExpr
+  Line 1160) new LambdaExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), lambdaParameters, body, _n.isParametersEnclosed()) ==> com.github.javaparser.ast.expr.LambdaExpr
+  Line 1164) r ==> com.github.javaparser.ast.expr.LambdaExpr
+  Line 1170) List<TypeParameter> typeParams = visit(_n.getTypeParameters(), arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 1170) visit(_n.getTypeParameters(), arg) ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 1171) Expression scope = cloneNodes(_n.getScope(), arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1171) cloneNodes(_n.getScope(), arg) ==> com.github.javaparser.ast.expr.Expression
+  Line 1173) MethodReferenceExpr r = new MethodReferenceExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, typeParams, _n.getIdentifier()) ==> com.github.javaparser.ast.expr.MethodReferenceExpr
+  Line 1173) new MethodReferenceExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope, typeParams, _n.getIdentifier()) ==> com.github.javaparser.ast.expr.MethodReferenceExpr
+  Line 1176) r ==> com.github.javaparser.ast.expr.MethodReferenceExpr
+  Line 1182) Type t = cloneNodes(n.getType(), arg) ==> com.github.javaparser.ast.type.Type
+  Line 1182) cloneNodes(n.getType(), arg) ==> com.github.javaparser.ast.type.Type
+  Line 1184) TypeExpr r = new TypeExpr(n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(), t) ==> com.github.javaparser.ast.expr.TypeExpr
+  Line 1184) new TypeExpr(n.getBeginLine(), n.getBeginColumn(), n.getEndLine(), n.getEndColumn(), t) ==> com.github.javaparser.ast.expr.TypeExpr
+  Line 1187) r ==> com.github.javaparser.ast.expr.TypeExpr
+  Line 1191) _nodes == null ==> boolean
+  Line 1192) null ==> null
+  Line 1193) List<T> r = new ArrayList<T>(_nodes.size()) ==> java.util.List<T>
+  Line 1193) new ArrayList<T>(_nodes.size()) ==> java.util.ArrayList<T>
+  Line 1194) T n ==> T
+  Line 1194) _nodes ==> java.util.List<T>
+  Line 1195) T rN = cloneNodes(n, _arg) ==> T
+  Line 1195) cloneNodes(n, _arg) ==> T
+  Line 1196) rN != null ==> boolean
+  Line 1197) r.add(rN) ==> boolean
+  Line 1199) r ==> java.util.List<T>
+  Line 1203) _node == null ==> boolean
+  Line 1204) null ==> null
+  Line 1205) Node r = _node.accept(this, _arg) ==> com.github.javaparser.ast.Node
+  Line 1205) _node.accept(this, _arg) ==> com.github.javaparser.ast.Node
+  Line 1206) r == null ==> boolean
+  Line 1207) null ==> null
+  Line 1208) (T) r ==> T
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_DumpVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_DumpVisitor.txt
new file mode 100644
index 0000000..2484524
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_DumpVisitor.txt
@@ -0,0 +1,1076 @@
+
+[ Class com.github.javaparser.ast.visitor.DumpVisitor ]
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.visitor.VoidVisitor
+  Line 93) true ==> boolean
+  Line 97) this.printComments = printComments ==> boolean
+
+[ Class com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter ]
+  superclass: java.lang.Object
+  Line 102) 0 ==> int
+  Line 104) false ==> boolean
+  Line 106) new StringBuilder() ==> java.lang.StringBuilder
+  Line 109) level++ ==> int
+  Line 113) level-- ==> int
+  Line 117) int i = 0 ==> int
+  Line 117) 0 ==> int
+  Line 117) i < level ==> boolean
+  Line 117) i++ ==> int
+  Line 118) buf.append("    ") ==> java.lang.StringBuilder
+  Line 123) !indented ==> boolean
+  Line 124) makeIndent() ==> void
+  Line 125) indented = true ==> boolean
+  Line 127) buf.append(arg) ==> java.lang.StringBuilder
+  Line 131) print(arg) ==> void
+  Line 132) printLn() ==> void
+  Line 136) buf.append(System.getProperty("line.separator")) ==> java.lang.StringBuilder
+  Line 137) indented = false ==> boolean
+  Line 141) buf.toString() ==> java.lang.String
+  Line 145) getSource() ==> java.lang.String
+  Line 149) new SourcePrinter() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter
+  Line 152) printer.getSource() ==> java.lang.String
+  Line 156) ModifierSet.isPrivate(modifiers) ==> boolean
+  Line 157) printer.print("private ") ==> void
+  Line 159) ModifierSet.isProtected(modifiers) ==> boolean
+  Line 160) printer.print("protected ") ==> void
+  Line 162) ModifierSet.isPublic(modifiers) ==> boolean
+  Line 163) printer.print("public ") ==> void
+  Line 165) ModifierSet.isAbstract(modifiers) ==> boolean
+  Line 166) printer.print("abstract ") ==> void
+  Line 168) ModifierSet.isStatic(modifiers) ==> boolean
+  Line 169) printer.print("static ") ==> void
+  Line 171) ModifierSet.isFinal(modifiers) ==> boolean
+  Line 172) printer.print("final ") ==> void
+  Line 174) ModifierSet.isNative(modifiers) ==> boolean
+  Line 175) printer.print("native ") ==> void
+  Line 177) ModifierSet.isStrictfp(modifiers) ==> boolean
+  Line 178) printer.print("strictfp ") ==> void
+  Line 180) ModifierSet.isSynchronized(modifiers) ==> boolean
+  Line 181) printer.print("synchronized ") ==> void
+  Line 183) ModifierSet.isTransient(modifiers) ==> boolean
+  Line 184) printer.print("transient ") ==> void
+  Line 186) ModifierSet.isVolatile(modifiers) ==> boolean
+  Line 187) printer.print("volatile ") ==> void
+  Line 192) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 192) members ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 193) printer.printLn() ==> void
+  Line 194) member.accept(this, arg) ==> void
+  Line 195) printer.printLn() ==> void
+  Line 200) !isNullOrEmpty(annotations) ==> boolean
+  Line 201) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 201) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 202) a.accept(this, arg) ==> void
+  Line 203) printer.printLn() ==> void
+  Line 209) !isNullOrEmpty(annotations) ==> boolean
+  Line 210) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 210) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 211) a.accept(this, arg) ==> void
+  Line 212) printer.print(" ") ==> void
+  Line 218) !isNullOrEmpty(args) ==> boolean
+  Line 219) printer.print("<") ==> void
+  Line 220) final Iterator<Type> i = args.iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 220) args.iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 220) i.hasNext() ==> boolean
+  Line 221) final Type t = i.next() ==> com.github.javaparser.ast.type.Type
+  Line 221) i.next() ==> com.github.javaparser.ast.type.Type
+  Line 222) t.accept(this, arg) ==> void
+  Line 223) i.hasNext() ==> boolean
+  Line 224) printer.print(", ") ==> void
+  Line 227) printer.print(">") ==> void
+  Line 232) !isNullOrEmpty(args) ==> boolean
+  Line 233) printer.print("<") ==> void
+  Line 234) final Iterator<TypeParameter> i = args.iterator() ==> java.util.Iterator<com.github.javaparser.ast.TypeParameter>
+  Line 234) args.iterator() ==> java.util.Iterator<com.github.javaparser.ast.TypeParameter>
+  Line 234) i.hasNext() ==> boolean
+  Line 235) final TypeParameter t = i.next() ==> com.github.javaparser.ast.TypeParameter
+  Line 235) i.next() ==> com.github.javaparser.ast.TypeParameter
+  Line 236) t.accept(this, arg) ==> void
+  Line 237) i.hasNext() ==> boolean
+  Line 238) printer.print(", ") ==> void
+  Line 241) printer.print(">") ==> void
+  Line 246) printer.print("(") ==> void
+  Line 247) !isNullOrEmpty(args) ==> boolean
+  Line 248) final Iterator<Expression> i = args.iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 248) args.iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 248) i.hasNext() ==> boolean
+  Line 249) final Expression e = i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 249) i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 250) e.accept(this, arg) ==> void
+  Line 251) i.hasNext() ==> boolean
+  Line 252) printer.print(", ") ==> void
+  Line 256) printer.print(")") ==> void
+  Line 260) javadoc != null ==> boolean
+  Line 261) javadoc.accept(this, arg) ==> void
+  Line 266) javacomment != null ==> boolean
+  Line 267) javacomment.accept(this, arg) ==> void
+  Line 272) printJavaComment(n.getComment(), arg) ==> void
+  Line 274) n.getPackage() != null ==> boolean
+  Line 275) n.getPackage().accept(this, arg) ==> void
+  Line 278) n.getImports() != null ==> boolean
+  Line 279) final ImportDeclaration i ==> com.github.javaparser.ast.ImportDeclaration
+  Line 279) n.getImports() ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 280) i.accept(this, arg) ==> void
+  Line 282) printer.printLn() ==> void
+  Line 285) n.getTypes() != null ==> boolean
+  Line 286) final Iterator<TypeDeclaration> i = n.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 286) n.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 286) i.hasNext() ==> boolean
+  Line 287) i.next().accept(this, arg) ==> void
+  Line 288) printer.printLn() ==> void
+  Line 289) i.hasNext() ==> boolean
+  Line 290) printer.printLn() ==> void
+  Line 295) printOrphanCommentsEnding(n) ==> void
+  Line 299) printJavaComment(n.getComment(), arg) ==> void
+  Line 300) printAnnotations(n.getAnnotations(), arg) ==> void
+  Line 301) printer.print("package ") ==> void
+  Line 302) n.getName().accept(this, arg) ==> void
+  Line 303) printer.printLn(";") ==> void
+  Line 304) printer.printLn() ==> void
+  Line 306) printOrphanCommentsEnding(n) ==> void
+  Line 310) printJavaComment(n.getComment(), arg) ==> void
+  Line 311) printer.print(n.getName()) ==> void
+  Line 313) printOrphanCommentsEnding(n) ==> void
+  Line 317) printJavaComment(n.getComment(), arg) ==> void
+  Line 318) n.getQualifier().accept(this, arg) ==> void
+  Line 319) printer.print(".") ==> void
+  Line 320) printer.print(n.getName()) ==> void
+  Line 322) printOrphanCommentsEnding(n) ==> void
+  Line 326) printJavaComment(n.getComment(), arg) ==> void
+  Line 327) printer.print("import ") ==> void
+  Line 328) n.isStatic() ==> boolean
+  Line 329) printer.print("static ") ==> void
+  Line 331) n.getName().accept(this, arg) ==> void
+  Line 332) n.isAsterisk() ==> boolean
+  Line 333) printer.print(".*") ==> void
+  Line 335) printer.printLn(";") ==> void
+  Line 337) printOrphanCommentsEnding(n) ==> void
+  Line 341) printJavaComment(n.getComment(), arg) ==> void
+  Line 342) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 343) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 344) printModifiers(n.getModifiers()) ==> void
+  Line 346) n.isInterface() ==> boolean
+  Line 347) printer.print("interface ") ==> void
+  Line 349) printer.print("class ") ==> void
+  Line 352) printer.print(n.getName()) ==> void
+  Line 354) printTypeParameters(n.getTypeParameters(), arg) ==> void
+  Line 356) !isNullOrEmpty(n.getExtends()) ==> boolean
+  Line 357) printer.print(" extends ") ==> void
+  Line 358) final Iterator<ClassOrInterfaceType> i = n.getExtends().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 358) n.getExtends().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 358) i.hasNext() ==> boolean
+  Line 359) final ClassOrInterfaceType c = i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 359) i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 360) c.accept(this, arg) ==> void
+  Line 361) i.hasNext() ==> boolean
+  Line 362) printer.print(", ") ==> void
+  Line 367) !isNullOrEmpty(n.getImplements()) ==> boolean
+  Line 368) printer.print(" implements ") ==> void
+  Line 369) final Iterator<ClassOrInterfaceType> i = n.getImplements().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 369) n.getImplements().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 369) i.hasNext() ==> boolean
+  Line 370) final ClassOrInterfaceType c = i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 370) i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 371) c.accept(this, arg) ==> void
+  Line 372) i.hasNext() ==> boolean
+  Line 373) printer.print(", ") ==> void
+  Line 378) printer.printLn(" {") ==> void
+  Line 379) printer.indent() ==> void
+  Line 380) !isNullOrEmpty(n.getMembers()) ==> boolean
+  Line 381) printMembers(n.getMembers(), arg) ==> void
+  Line 384) printOrphanCommentsEnding(n) ==> void
+  Line 386) printer.unindent() ==> void
+  Line 387) printer.print("}") ==> void
+  Line 391) printJavaComment(n.getComment(), arg) ==> void
+  Line 392) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 393) printer.print(";") ==> void
+  Line 395) printOrphanCommentsEnding(n) ==> void
+  Line 399) printer.print("/**") ==> void
+  Line 400) printer.print(n.getContent()) ==> void
+  Line 401) printer.printLn("*/") ==> void
+  Line 405) printJavaComment(n.getComment(), arg) ==> void
+  Line 407) n.getAnnotations() != null ==> boolean
+  Line 408) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 408) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 409) ae.accept(this, arg) ==> void
+  Line 410) printer.print(" ") ==> void
+  Line 414) n.getScope() != null ==> boolean
+  Line 415) n.getScope().accept(this, arg) ==> void
+  Line 416) printer.print(".") ==> void
+  Line 418) printer.print(n.getName()) ==> void
+  Line 419) printTypeArgs(n.getTypeArgs(), arg) ==> void
+  Line 423) printJavaComment(n.getComment(), arg) ==> void
+  Line 424) n.getAnnotations() != null ==> boolean
+  Line 425) AnnotationExpr ann ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 425) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 426) ann.accept(this, arg) ==> void
+  Line 427) printer.print(" ") ==> void
+  Line 430) printer.print(n.getName()) ==> void
+  Line 431) n.getTypeBound() != null ==> boolean
+  Line 432) printer.print(" extends ") ==> void
+  Line 433) final Iterator<ClassOrInterfaceType> i = n.getTypeBound().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 433) n.getTypeBound().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 433) i.hasNext() ==> boolean
+  Line 434) final ClassOrInterfaceType c = i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 434) i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 435) c.accept(this, arg) ==> void
+  Line 436) i.hasNext() ==> boolean
+  Line 437) printer.print(" & ") ==> void
+  Line 444) printJavaComment(n.getComment(), arg) ==> void
+  Line 445) n.getAnnotations() != null ==> boolean
+  Line 446) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 446) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 447) ae.accept(this, arg) ==> void
+  Line 448) printer.print(" ") ==> void
+  Line 451) n.getType() ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 452) Boolean ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 453) printer.print("boolean") ==> void
+  Line 455) Byte ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 456) printer.print("byte") ==> void
+  Line 458) Char ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 459) printer.print("char") ==> void
+  Line 461) Double ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 462) printer.print("double") ==> void
+  Line 464) Float ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 465) printer.print("float") ==> void
+  Line 467) Int ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 468) printer.print("int") ==> void
+  Line 470) Long ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 471) printer.print("long") ==> void
+  Line 473) Short ==> com.github.javaparser.ast.type.PrimitiveType.Primitive
+  Line 474) printer.print("short") ==> void
+  Line 480) printJavaComment(n.getComment(), arg) ==> void
+  Line 481) n.getAnnotations() != null ==> boolean
+  Line 482) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 482) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 483) ae.accept(this, arg) ==> void
+  Line 484) printer.print(" ") ==> void
+  Line 487) n.getType().accept(this, arg) ==> void
+  Line 488) List<List<AnnotationExpr>> arraysAnnotations = n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 488) n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 489) int i = 0 ==> int
+  Line 489) 0 ==> int
+  Line 489) i < n.getArrayCount() ==> boolean
+  Line 489) i++ ==> int
+  Line 490) arraysAnnotations != null && i < arraysAnnotations.size() ==> boolean
+  Line 491) List<AnnotationExpr> annotations = arraysAnnotations.get(i) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 491) arraysAnnotations.get(i) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 492) annotations != null ==> boolean
+  Line 493) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 493) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 494) printer.print(" ") ==> void
+  Line 495) ae.accept(this, arg) ==> void
+  Line 500) printer.print("[]") ==> void
+  Line 505) printJavaComment(n.getComment(), arg) ==> void
+  Line 506) n.getAnnotations() != null ==> boolean
+  Line 507) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 507) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 508) printer.print(" ") ==> void
+  Line 509) ae.accept(this, arg) ==> void
+  Line 512) printer.print("?") ==> void
+  Line 513) n.getExtends() != null ==> boolean
+  Line 514) printer.print(" extends ") ==> void
+  Line 515) n.getExtends().accept(this, arg) ==> void
+  Line 517) n.getSuper() != null ==> boolean
+  Line 518) printer.print(" super ") ==> void
+  Line 519) n.getSuper().accept(this, arg) ==> void
+  Line 528) printOrphanCommentsBeforeThisChildNode(n) ==> void
+  Line 530) printJavaComment(n.getComment(), arg) ==> void
+  Line 531) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 532) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 533) printModifiers(n.getModifiers()) ==> void
+  Line 534) n.getType().accept(this, arg) ==> void
+  Line 536) printer.print(" ") ==> void
+  Line 537) final Iterator<VariableDeclarator> i = n.getVariables().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 537) n.getVariables().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 537) i.hasNext() ==> boolean
+  Line 538) final VariableDeclarator var = i.next() ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 538) i.next() ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 539) var.accept(this, arg) ==> void
+  Line 540) i.hasNext() ==> boolean
+  Line 541) printer.print(", ") ==> void
+  Line 545) printer.print(";") ==> void
+  Line 549) printJavaComment(n.getComment(), arg) ==> void
+  Line 550) n.getId().accept(this, arg) ==> void
+  Line 551) n.getInit() != null ==> boolean
+  Line 552) printer.print(" = ") ==> void
+  Line 553) n.getInit().accept(this, arg) ==> void
+  Line 558) printJavaComment(n.getComment(), arg) ==> void
+  Line 559) printer.print(n.getName()) ==> void
+  Line 560) int i = 0 ==> int
+  Line 560) 0 ==> int
+  Line 560) i < n.getArrayCount() ==> boolean
+  Line 560) i++ ==> int
+  Line 561) printer.print("[]") ==> void
+  Line 566) printJavaComment(n.getComment(), arg) ==> void
+  Line 567) printer.print("{") ==> void
+  Line 568) n.getValues() != null ==> boolean
+  Line 569) printer.print(" ") ==> void
+  Line 570) final Iterator<Expression> i = n.getValues().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 570) n.getValues().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 570) i.hasNext() ==> boolean
+  Line 571) final Expression expr = i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 571) i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 572) expr.accept(this, arg) ==> void
+  Line 573) i.hasNext() ==> boolean
+  Line 574) printer.print(", ") ==> void
+  Line 577) printer.print(" ") ==> void
+  Line 579) printer.print("}") ==> void
+  Line 583) printJavaComment(n.getComment(), arg) ==> void
+  Line 584) printer.print("void") ==> void
+  Line 588) printJavaComment(n.getComment(), arg) ==> void
+  Line 589) n.getName().accept(this, arg) ==> void
+  Line 590) printer.print("[") ==> void
+  Line 591) n.getIndex().accept(this, arg) ==> void
+  Line 592) printer.print("]") ==> void
+  Line 596) printJavaComment(n.getComment(), arg) ==> void
+  Line 597) printer.print("new ") ==> void
+  Line 598) n.getType().accept(this, arg) ==> void
+  Line 599) List<List<AnnotationExpr>> arraysAnnotations = n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 599) n.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 600) n.getDimensions() != null ==> boolean
+  Line 601) int j = 0 ==> int
+  Line 601) 0 ==> int
+  Line 602) final Expression dim ==> com.github.javaparser.ast.expr.Expression
+  Line 602) n.getDimensions() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 604) arraysAnnotations != null && j < arraysAnnotations.size() ==> boolean
+  Line 605) List<AnnotationExpr> annotations = arraysAnnotations.get(j) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 605) arraysAnnotations.get(j) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 606) annotations != null ==> boolean
+  Line 607) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 607) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 608) printer.print(" ") ==> void
+  Line 609) ae.accept(this, arg) ==> void
+  Line 613) printer.print("[") ==> void
+  Line 614) dim.accept(this, arg) ==> void
+  Line 615) printer.print("]") ==> void
+  Line 616) j++ ==> int
+  Line 618) int i = 0 ==> int
+  Line 618) 0 ==> int
+  Line 618) i < n.getArrayCount() ==> boolean
+  Line 618) i++ ==> int
+  Line 619) arraysAnnotations != null && i < arraysAnnotations.size() ==> boolean
+  Line 621) List<AnnotationExpr> annotations = arraysAnnotations.get(i) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 621) arraysAnnotations.get(i) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 622) annotations != null ==> boolean
+  Line 623) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 623) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 624) printer.print(" ") ==> void
+  Line 625) ae.accept(this, arg) ==> void
+  Line 630) printer.print("[]") ==> void
+  Line 634) int i = 0 ==> int
+  Line 634) 0 ==> int
+  Line 634) i < n.getArrayCount() ==> boolean
+  Line 634) i++ ==> int
+  Line 635) arraysAnnotations != null && i < arraysAnnotations.size() ==> boolean
+  Line 636) List<AnnotationExpr> annotations = arraysAnnotations.get(i) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 636) arraysAnnotations.get(i) ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 637) annotations != null ==> boolean
+  Line 638) AnnotationExpr ae ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 638) annotations ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 639) ae.accept(this, arg) ==> void
+  Line 640) printer.print(" ") ==> void
+  Line 644) printer.print("[]") ==> void
+  Line 646) printer.print(" ") ==> void
+  Line 647) n.getInitializer().accept(this, arg) ==> void
+  Line 652) printJavaComment(n.getComment(), arg) ==> void
+  Line 653) n.getTarget().accept(this, arg) ==> void
+  Line 654) printer.print(" ") ==> void
+  Line 655) n.getOperator() ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 656) assign ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 657) printer.print("=") ==> void
+  Line 659) and ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 660) printer.print("&=") ==> void
+  Line 662) or ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 663) printer.print("|=") ==> void
+  Line 665) xor ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 666) printer.print("^=") ==> void
+  Line 668) plus ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 669) printer.print("+=") ==> void
+  Line 671) minus ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 672) printer.print("-=") ==> void
+  Line 674) rem ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 675) printer.print("%=") ==> void
+  Line 677) slash ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 678) printer.print("/=") ==> void
+  Line 680) star ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 681) printer.print("*=") ==> void
+  Line 683) lShift ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 684) printer.print("<<=") ==> void
+  Line 686) rSignedShift ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 687) printer.print(">>=") ==> void
+  Line 689) rUnsignedShift ==> com.github.javaparser.ast.expr.AssignExpr.Operator
+  Line 690) printer.print(">>>=") ==> void
+  Line 693) printer.print(" ") ==> void
+  Line 694) n.getValue().accept(this, arg) ==> void
+  Line 698) printJavaComment(n.getComment(), arg) ==> void
+  Line 699) n.getLeft().accept(this, arg) ==> void
+  Line 700) printer.print(" ") ==> void
+  Line 701) n.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 702) or ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 703) printer.print("||") ==> void
+  Line 705) and ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 706) printer.print("&&") ==> void
+  Line 708) binOr ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 709) printer.print("|") ==> void
+  Line 711) binAnd ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 712) printer.print("&") ==> void
+  Line 714) xor ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 715) printer.print("^") ==> void
+  Line 717) equals ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 718) printer.print("==") ==> void
+  Line 720) notEquals ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 721) printer.print("!=") ==> void
+  Line 723) less ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 724) printer.print("<") ==> void
+  Line 726) greater ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 727) printer.print(">") ==> void
+  Line 729) lessEquals ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 730) printer.print("<=") ==> void
+  Line 732) greaterEquals ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 733) printer.print(">=") ==> void
+  Line 735) lShift ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 736) printer.print("<<") ==> void
+  Line 738) rSignedShift ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 739) printer.print(">>") ==> void
+  Line 741) rUnsignedShift ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 742) printer.print(">>>") ==> void
+  Line 744) plus ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 745) printer.print("+") ==> void
+  Line 747) minus ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 748) printer.print("-") ==> void
+  Line 750) times ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 751) printer.print("*") ==> void
+  Line 753) divide ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 754) printer.print("/") ==> void
+  Line 756) remainder ==> com.github.javaparser.ast.expr.BinaryExpr.Operator
+  Line 757) printer.print("%") ==> void
+  Line 760) printer.print(" ") ==> void
+  Line 761) n.getRight().accept(this, arg) ==> void
+  Line 765) printJavaComment(n.getComment(), arg) ==> void
+  Line 766) printer.print("(") ==> void
+  Line 767) n.getType().accept(this, arg) ==> void
+  Line 768) printer.print(") ") ==> void
+  Line 769) n.getExpr().accept(this, arg) ==> void
+  Line 773) printJavaComment(n.getComment(), arg) ==> void
+  Line 774) n.getType().accept(this, arg) ==> void
+  Line 775) printer.print(".class") ==> void
+  Line 779) printJavaComment(n.getComment(), arg) ==> void
+  Line 780) n.getCondition().accept(this, arg) ==> void
+  Line 781) printer.print(" ? ") ==> void
+  Line 782) n.getThenExpr().accept(this, arg) ==> void
+  Line 783) printer.print(" : ") ==> void
+  Line 784) n.getElseExpr().accept(this, arg) ==> void
+  Line 788) printJavaComment(n.getComment(), arg) ==> void
+  Line 789) printer.print("(") ==> void
+  Line 790) n.getInner() != null ==> boolean
+  Line 791) n.getInner().accept(this, arg) ==> void
+  Line 793) printer.print(")") ==> void
+  Line 797) printJavaComment(n.getComment(), arg) ==> void
+  Line 798) n.getScope().accept(this, arg) ==> void
+  Line 799) printer.print(".") ==> void
+  Line 800) printer.print(n.getField()) ==> void
+  Line 804) printJavaComment(n.getComment(), arg) ==> void
+  Line 805) n.getExpr().accept(this, arg) ==> void
+  Line 806) printer.print(" instanceof ") ==> void
+  Line 807) n.getType().accept(this, arg) ==> void
+  Line 811) printJavaComment(n.getComment(), arg) ==> void
+  Line 812) printer.print("'") ==> void
+  Line 813) printer.print(n.getValue()) ==> void
+  Line 814) printer.print("'") ==> void
+  Line 818) printJavaComment(n.getComment(), arg) ==> void
+  Line 819) printer.print(n.getValue()) ==> void
+  Line 823) printJavaComment(n.getComment(), arg) ==> void
+  Line 824) printer.print(n.getValue()) ==> void
+  Line 828) printJavaComment(n.getComment(), arg) ==> void
+  Line 829) printer.print(n.getValue()) ==> void
+  Line 833) printJavaComment(n.getComment(), arg) ==> void
+  Line 834) printer.print(n.getValue()) ==> void
+  Line 838) printJavaComment(n.getComment(), arg) ==> void
+  Line 839) printer.print(n.getValue()) ==> void
+  Line 843) printJavaComment(n.getComment(), arg) ==> void
+  Line 844) printer.print("\"") ==> void
+  Line 845) printer.print(n.getValue()) ==> void
+  Line 846) printer.print("\"") ==> void
+  Line 850) printJavaComment(n.getComment(), arg) ==> void
+  Line 851) printer.print(String.valueOf(n.getValue())) ==> void
+  Line 855) printJavaComment(n.getComment(), arg) ==> void
+  Line 856) printer.print("null") ==> void
+  Line 860) printJavaComment(n.getComment(), arg) ==> void
+  Line 861) n.getClassExpr() != null ==> boolean
+  Line 862) n.getClassExpr().accept(this, arg) ==> void
+  Line 863) printer.print(".") ==> void
+  Line 865) printer.print("this") ==> void
+  Line 869) printJavaComment(n.getComment(), arg) ==> void
+  Line 870) n.getClassExpr() != null ==> boolean
+  Line 871) n.getClassExpr().accept(this, arg) ==> void
+  Line 872) printer.print(".") ==> void
+  Line 874) printer.print("super") ==> void
+  Line 878) printJavaComment(n.getComment(), arg) ==> void
+  Line 879) n.getScope() != null ==> boolean
+  Line 880) n.getScope().accept(this, arg) ==> void
+  Line 881) printer.print(".") ==> void
+  Line 883) printTypeArgs(n.getTypeArgs(), arg) ==> void
+  Line 884) printer.print(n.getName()) ==> void
+  Line 885) printArguments(n.getArgs(), arg) ==> void
+  Line 889) printJavaComment(n.getComment(), arg) ==> void
+  Line 890) n.getScope() != null ==> boolean
+  Line 891) n.getScope().accept(this, arg) ==> void
+  Line 892) printer.print(".") ==> void
+  Line 895) printer.print("new ") ==> void
+  Line 897) printTypeArgs(n.getTypeArgs(), arg) ==> void
+  Line 898) !isNullOrEmpty(n.getTypeArgs()) ==> boolean
+  Line 899) printer.print(" ") ==> void
+  Line 902) n.getType().accept(this, arg) ==> void
+  Line 904) printArguments(n.getArgs(), arg) ==> void
+  Line 906) n.getAnonymousClassBody() != null ==> boolean
+  Line 907) printer.printLn(" {") ==> void
+  Line 908) printer.indent() ==> void
+  Line 909) printMembers(n.getAnonymousClassBody(), arg) ==> void
+  Line 910) printer.unindent() ==> void
+  Line 911) printer.print("}") ==> void
+  Line 916) printJavaComment(n.getComment(), arg) ==> void
+  Line 917) n.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 918) positive ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 919) printer.print("+") ==> void
+  Line 921) negative ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 922) printer.print("-") ==> void
+  Line 924) inverse ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 925) printer.print("~") ==> void
+  Line 927) not ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 928) printer.print("!") ==> void
+  Line 930) preIncrement ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 931) printer.print("++") ==> void
+  Line 933) preDecrement ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 934) printer.print("--") ==> void
+  Line 939) n.getExpr().accept(this, arg) ==> void
+  Line 941) n.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 942) posIncrement ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 943) printer.print("++") ==> void
+  Line 945) posDecrement ==> com.github.javaparser.ast.expr.UnaryExpr.Operator
+  Line 946) printer.print("--") ==> void
+  Line 953) printJavaComment(n.getComment(), arg) ==> void
+  Line 954) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 955) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 956) printModifiers(n.getModifiers()) ==> void
+  Line 958) printTypeParameters(n.getTypeParameters(), arg) ==> void
+  Line 959) n.getTypeParameters() != null ==> boolean
+  Line 960) printer.print(" ") ==> void
+  Line 962) printer.print(n.getName()) ==> void
+  Line 964) printer.print("(") ==> void
+  Line 965) n.getParameters() != null ==> boolean
+  Line 966) final Iterator<Parameter> i = n.getParameters().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.Parameter>
+  Line 966) n.getParameters().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.Parameter>
+  Line 966) i.hasNext() ==> boolean
+  Line 967) final Parameter p = i.next() ==> com.github.javaparser.ast.body.Parameter
+  Line 967) i.next() ==> com.github.javaparser.ast.body.Parameter
+  Line 968) p.accept(this, arg) ==> void
+  Line 969) i.hasNext() ==> boolean
+  Line 970) printer.print(", ") ==> void
+  Line 974) printer.print(")") ==> void
+  Line 976) !isNullOrEmpty(n.getThrows()) ==> boolean
+  Line 977) printer.print(" throws ") ==> void
+  Line 978) final Iterator<NameExpr> i = n.getThrows().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.NameExpr>
+  Line 978) n.getThrows().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.NameExpr>
+  Line 978) i.hasNext() ==> boolean
+  Line 979) final NameExpr name = i.next() ==> com.github.javaparser.ast.expr.NameExpr
+  Line 979) i.next() ==> com.github.javaparser.ast.expr.NameExpr
+  Line 980) name.accept(this, arg) ==> void
+  Line 981) i.hasNext() ==> boolean
+  Line 982) printer.print(", ") ==> void
+  Line 986) printer.print(" ") ==> void
+  Line 987) n.getBlock().accept(this, arg) ==> void
+  Line 991) printOrphanCommentsBeforeThisChildNode(n) ==> void
+  Line 993) printJavaComment(n.getComment(), arg) ==> void
+  Line 994) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 995) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 996) printModifiers(n.getModifiers()) ==> void
+  Line 997) n.isDefault() ==> boolean
+  Line 998) printer.print("default ") ==> void
+  Line 1000) printTypeParameters(n.getTypeParameters(), arg) ==> void
+  Line 1001) n.getTypeParameters() != null ==> boolean
+  Line 1002) printer.print(" ") ==> void
+  Line 1005) n.getType().accept(this, arg) ==> void
+  Line 1006) printer.print(" ") ==> void
+  Line 1007) printer.print(n.getName()) ==> void
+  Line 1009) printer.print("(") ==> void
+  Line 1010) n.getParameters() != null ==> boolean
+  Line 1011) final Iterator<Parameter> i = n.getParameters().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.Parameter>
+  Line 1011) n.getParameters().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.Parameter>
+  Line 1011) i.hasNext() ==> boolean
+  Line 1012) final Parameter p = i.next() ==> com.github.javaparser.ast.body.Parameter
+  Line 1012) i.next() ==> com.github.javaparser.ast.body.Parameter
+  Line 1013) p.accept(this, arg) ==> void
+  Line 1014) i.hasNext() ==> boolean
+  Line 1015) printer.print(", ") ==> void
+  Line 1019) printer.print(")") ==> void
+  Line 1021) int i = 0 ==> int
+  Line 1021) 0 ==> int
+  Line 1021) i < n.getArrayCount() ==> boolean
+  Line 1021) i++ ==> int
+  Line 1022) printer.print("[]") ==> void
+  Line 1025) !isNullOrEmpty(n.getThrows()) ==> boolean
+  Line 1026) printer.print(" throws ") ==> void
+  Line 1027) final Iterator<NameExpr> i = n.getThrows().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.NameExpr>
+  Line 1027) n.getThrows().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.NameExpr>
+  Line 1027) i.hasNext() ==> boolean
+  Line 1028) final NameExpr name = i.next() ==> com.github.javaparser.ast.expr.NameExpr
+  Line 1028) i.next() ==> com.github.javaparser.ast.expr.NameExpr
+  Line 1029) name.accept(this, arg) ==> void
+  Line 1030) i.hasNext() ==> boolean
+  Line 1031) printer.print(", ") ==> void
+  Line 1035) n.getBody() == null ==> boolean
+  Line 1036) printer.print(";") ==> void
+  Line 1038) printer.print(" ") ==> void
+  Line 1039) n.getBody().accept(this, arg) ==> void
+  Line 1044) printJavaComment(n.getComment(), arg) ==> void
+  Line 1045) printAnnotations(n.getAnnotations(), arg) ==> void
+  Line 1046) printModifiers(n.getModifiers()) ==> void
+  Line 1047) n.getType() != null ==> boolean
+  Line 1048) n.getType().accept(this, arg) ==> void
+  Line 1050) n.isVarArgs() ==> boolean
+  Line 1051) printer.print("...") ==> void
+  Line 1053) printer.print(" ") ==> void
+  Line 1054) n.getId().accept(this, arg) ==> void
+  Line 1058) printAnnotations(n.getAnnotations(), arg) ==> void
+  Line 1059) printModifiers(n.getModifiers()) ==> void
+  Line 1061) Iterator<Type> types = n.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 1061) n.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 1062) types.next().accept(this, arg) ==> void
+  Line 1063) types.hasNext() ==> boolean
+  Line 1064) printer.print(" | ") ==> void
+  Line 1065) types.next().accept(this, arg) ==> void
+  Line 1068) printer.print(" ") ==> void
+  Line 1069) n.getId().accept(this, arg) ==> void
+  Line 1073) printJavaComment(n.getComment(), arg) ==> void
+  Line 1074) n.isThis() ==> boolean
+  Line 1075) printTypeArgs(n.getTypeArgs(), arg) ==> void
+  Line 1076) printer.print("this") ==> void
+  Line 1078) n.getExpr() != null ==> boolean
+  Line 1079) n.getExpr().accept(this, arg) ==> void
+  Line 1080) printer.print(".") ==> void
+  Line 1082) printTypeArgs(n.getTypeArgs(), arg) ==> void
+  Line 1083) printer.print("super") ==> void
+  Line 1085) printArguments(n.getArgs(), arg) ==> void
+  Line 1086) printer.print(";") ==> void
+  Line 1090) printJavaComment(n.getComment(), arg) ==> void
+  Line 1091) printAnnotations(n.getAnnotations(), arg) ==> void
+  Line 1092) printModifiers(n.getModifiers()) ==> void
+  Line 1094) n.getType().accept(this, arg) ==> void
+  Line 1095) printer.print(" ") ==> void
+  Line 1097) final Iterator<VariableDeclarator> i = n.getVars().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 1097) n.getVars().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 1097) i.hasNext() ==> boolean
+  Line 1098) final VariableDeclarator v = i.next() ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 1098) i.next() ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 1099) v.accept(this, arg) ==> void
+  Line 1100) i.hasNext() ==> boolean
+  Line 1101) printer.print(", ") ==> void
+  Line 1107) printJavaComment(n.getComment(), arg) ==> void
+  Line 1108) n.getTypeDeclaration().accept(this, arg) ==> void
+  Line 1112) printJavaComment(n.getComment(), arg) ==> void
+  Line 1113) printer.print("assert ") ==> void
+  Line 1114) n.getCheck().accept(this, arg) ==> void
+  Line 1115) n.getMessage() != null ==> boolean
+  Line 1116) printer.print(" : ") ==> void
+  Line 1117) n.getMessage().accept(this, arg) ==> void
+  Line 1119) printer.print(";") ==> void
+  Line 1123) printOrphanCommentsBeforeThisChildNode(n) ==> void
+  Line 1124) printJavaComment(n.getComment(), arg) ==> void
+  Line 1125) printer.printLn("{") ==> void
+  Line 1126) n.getStmts() != null ==> boolean
+  Line 1127) printer.indent() ==> void
+  Line 1128) final Statement s ==> com.github.javaparser.ast.stmt.Statement
+  Line 1128) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 1129) s.accept(this, arg) ==> void
+  Line 1130) printer.printLn() ==> void
+  Line 1132) printer.unindent() ==> void
+  Line 1134) printOrphanCommentsEnding(n) ==> void
+  Line 1135) printer.print("}") ==> void
+  Line 1140) printJavaComment(n.getComment(), arg) ==> void
+  Line 1141) printer.print(n.getLabel()) ==> void
+  Line 1142) printer.print(": ") ==> void
+  Line 1143) n.getStmt().accept(this, arg) ==> void
+  Line 1147) printJavaComment(n.getComment(), arg) ==> void
+  Line 1148) printer.print(";") ==> void
+  Line 1152) printOrphanCommentsBeforeThisChildNode(n) ==> void
+  Line 1153) printJavaComment(n.getComment(), arg) ==> void
+  Line 1154) n.getExpression().accept(this, arg) ==> void
+  Line 1155) printer.print(";") ==> void
+  Line 1159) printJavaComment(n.getComment(), arg) ==> void
+  Line 1160) printer.print("switch(") ==> void
+  Line 1161) n.getSelector().accept(this, arg) ==> void
+  Line 1162) printer.printLn(") {") ==> void
+  Line 1163) n.getEntries() != null ==> boolean
+  Line 1164) printer.indent() ==> void
+  Line 1165) final SwitchEntryStmt e ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 1165) n.getEntries() ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 1166) e.accept(this, arg) ==> void
+  Line 1168) printer.unindent() ==> void
+  Line 1170) printer.print("}") ==> void
+  Line 1175) printJavaComment(n.getComment(), arg) ==> void
+  Line 1176) n.getLabel() != null ==> boolean
+  Line 1177) printer.print("case ") ==> void
+  Line 1178) n.getLabel().accept(this, arg) ==> void
+  Line 1179) printer.print(":") ==> void
+  Line 1181) printer.print("default:") ==> void
+  Line 1183) printer.printLn() ==> void
+  Line 1184) printer.indent() ==> void
+  Line 1185) n.getStmts() != null ==> boolean
+  Line 1186) final Statement s ==> com.github.javaparser.ast.stmt.Statement
+  Line 1186) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 1187) s.accept(this, arg) ==> void
+  Line 1188) printer.printLn() ==> void
+  Line 1191) printer.unindent() ==> void
+  Line 1195) printJavaComment(n.getComment(), arg) ==> void
+  Line 1196) printer.print("break") ==> void
+  Line 1197) n.getId() != null ==> boolean
+  Line 1198) printer.print(" ") ==> void
+  Line 1199) printer.print(n.getId()) ==> void
+  Line 1201) printer.print(";") ==> void
+  Line 1205) printJavaComment(n.getComment(), arg) ==> void
+  Line 1206) printer.print("return") ==> void
+  Line 1207) n.getExpr() != null ==> boolean
+  Line 1208) printer.print(" ") ==> void
+  Line 1209) n.getExpr().accept(this, arg) ==> void
+  Line 1211) printer.print(";") ==> void
+  Line 1215) printJavaComment(n.getComment(), arg) ==> void
+  Line 1216) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 1217) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 1218) printModifiers(n.getModifiers()) ==> void
+  Line 1220) printer.print("enum ") ==> void
+  Line 1221) printer.print(n.getName()) ==> void
+  Line 1223) n.getImplements() != null ==> boolean
+  Line 1224) printer.print(" implements ") ==> void
+  Line 1225) final Iterator<ClassOrInterfaceType> i = n.getImplements().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 1225) n.getImplements().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 1225) i.hasNext() ==> boolean
+  Line 1226) final ClassOrInterfaceType c = i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 1226) i.next() ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 1227) c.accept(this, arg) ==> void
+  Line 1228) i.hasNext() ==> boolean
+  Line 1229) printer.print(", ") ==> void
+  Line 1234) printer.printLn(" {") ==> void
+  Line 1235) printer.indent() ==> void
+  Line 1236) n.getEntries() != null ==> boolean
+  Line 1237) printer.printLn() ==> void
+  Line 1238) final Iterator<EnumConstantDeclaration> i = n.getEntries().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 1238) n.getEntries().iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 1238) i.hasNext() ==> boolean
+  Line 1239) final EnumConstantDeclaration e = i.next() ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 1239) i.next() ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 1240) e.accept(this, arg) ==> void
+  Line 1241) i.hasNext() ==> boolean
+  Line 1242) printer.print(", ") ==> void
+  Line 1246) n.getMembers() != null ==> boolean
+  Line 1247) printer.printLn(";") ==> void
+  Line 1248) printMembers(n.getMembers(), arg) ==> void
+  Line 1250) n.getEntries() != null ==> boolean
+  Line 1251) printer.printLn() ==> void
+  Line 1254) printer.unindent() ==> void
+  Line 1255) printer.print("}") ==> void
+  Line 1259) printJavaComment(n.getComment(), arg) ==> void
+  Line 1260) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 1261) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 1262) printer.print(n.getName()) ==> void
+  Line 1264) n.getArgs() != null ==> boolean
+  Line 1265) printArguments(n.getArgs(), arg) ==> void
+  Line 1268) n.getClassBody() != null ==> boolean
+  Line 1269) printer.printLn(" {") ==> void
+  Line 1270) printer.indent() ==> void
+  Line 1271) printMembers(n.getClassBody(), arg) ==> void
+  Line 1272) printer.unindent() ==> void
+  Line 1273) printer.printLn("}") ==> void
+  Line 1278) printJavaComment(n.getComment(), arg) ==> void
+  Line 1279) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 1280) printer.print(";") ==> void
+  Line 1284) printJavaComment(n.getComment(), arg) ==> void
+  Line 1285) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 1286) n.isStatic() ==> boolean
+  Line 1287) printer.print("static ") ==> void
+  Line 1289) n.getBlock().accept(this, arg) ==> void
+  Line 1293) printJavaComment(n.getComment(), arg) ==> void
+  Line 1294) printer.print("if (") ==> void
+  Line 1295) n.getCondition().accept(this, arg) ==> void
+  Line 1296) final boolean thenBlock = n.getThenStmt() instanceof BlockStmt ==> boolean
+  Line 1296) n.getThenStmt() instanceof BlockStmt ==> boolean
+  Line 1297) // block statement should start on the same line
+thenBlock ==> boolean
+  Line 1298) printer.print(") ") ==> void
+  Line 1300) printer.printLn(")") ==> void
+  Line 1301) printer.indent() ==> void
+  Line 1303) n.getThenStmt().accept(this, arg) ==> void
+  Line 1304) !thenBlock ==> boolean
+  Line 1305) printer.unindent() ==> void
+  Line 1306) n.getElseStmt() != null ==> boolean
+  Line 1307) thenBlock ==> boolean
+  Line 1308) printer.print(" ") ==> void
+  Line 1310) printer.printLn() ==> void
+  Line 1311) final boolean elseIf = n.getElseStmt() instanceof IfStmt ==> boolean
+  Line 1311) n.getElseStmt() instanceof IfStmt ==> boolean
+  Line 1312) final boolean elseBlock = n.getElseStmt() instanceof BlockStmt ==> boolean
+  Line 1312) n.getElseStmt() instanceof BlockStmt ==> boolean
+  Line 1313) // put chained if and start of block statement on a same level
+elseIf || elseBlock ==> boolean
+  Line 1314) printer.print("else ") ==> void
+  Line 1316) printer.printLn("else") ==> void
+  Line 1317) printer.indent() ==> void
+  Line 1319) n.getElseStmt().accept(this, arg) ==> void
+  Line 1320) !(elseIf || elseBlock) ==> boolean
+  Line 1321) printer.unindent() ==> void
+  Line 1326) printJavaComment(n.getComment(), arg) ==> void
+  Line 1327) printer.print("while (") ==> void
+  Line 1328) n.getCondition().accept(this, arg) ==> void
+  Line 1329) printer.print(") ") ==> void
+  Line 1330) n.getBody().accept(this, arg) ==> void
+  Line 1334) printJavaComment(n.getComment(), arg) ==> void
+  Line 1335) printer.print("continue") ==> void
+  Line 1336) n.getId() != null ==> boolean
+  Line 1337) printer.print(" ") ==> void
+  Line 1338) printer.print(n.getId()) ==> void
+  Line 1340) printer.print(";") ==> void
+  Line 1344) printJavaComment(n.getComment(), arg) ==> void
+  Line 1345) printer.print("do ") ==> void
+  Line 1346) n.getBody().accept(this, arg) ==> void
+  Line 1347) printer.print(" while (") ==> void
+  Line 1348) n.getCondition().accept(this, arg) ==> void
+  Line 1349) printer.print(");") ==> void
+  Line 1353) printJavaComment(n.getComment(), arg) ==> void
+  Line 1354) printer.print("for (") ==> void
+  Line 1355) n.getVariable().accept(this, arg) ==> void
+  Line 1356) printer.print(" : ") ==> void
+  Line 1357) n.getIterable().accept(this, arg) ==> void
+  Line 1358) printer.print(") ") ==> void
+  Line 1359) n.getBody().accept(this, arg) ==> void
+  Line 1363) printJavaComment(n.getComment(), arg) ==> void
+  Line 1364) printer.print("for (") ==> void
+  Line 1365) n.getInit() != null ==> boolean
+  Line 1366) final Iterator<Expression> i = n.getInit().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 1366) n.getInit().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 1366) i.hasNext() ==> boolean
+  Line 1367) final Expression e = i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 1367) i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 1368) e.accept(this, arg) ==> void
+  Line 1369) i.hasNext() ==> boolean
+  Line 1370) printer.print(", ") ==> void
+  Line 1374) printer.print("; ") ==> void
+  Line 1375) n.getCompare() != null ==> boolean
+  Line 1376) n.getCompare().accept(this, arg) ==> void
+  Line 1378) printer.print("; ") ==> void
+  Line 1379) n.getUpdate() != null ==> boolean
+  Line 1380) final Iterator<Expression> i = n.getUpdate().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 1380) n.getUpdate().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.Expression>
+  Line 1380) i.hasNext() ==> boolean
+  Line 1381) final Expression e = i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 1381) i.next() ==> com.github.javaparser.ast.expr.Expression
+  Line 1382) e.accept(this, arg) ==> void
+  Line 1383) i.hasNext() ==> boolean
+  Line 1384) printer.print(", ") ==> void
+  Line 1388) printer.print(") ") ==> void
+  Line 1389) n.getBody().accept(this, arg) ==> void
+  Line 1393) printJavaComment(n.getComment(), arg) ==> void
+  Line 1394) printer.print("throw ") ==> void
+  Line 1395) n.getExpr().accept(this, arg) ==> void
+  Line 1396) printer.print(";") ==> void
+  Line 1400) printJavaComment(n.getComment(), arg) ==> void
+  Line 1401) printer.print("synchronized (") ==> void
+  Line 1402) n.getExpr().accept(this, arg) ==> void
+  Line 1403) printer.print(") ") ==> void
+  Line 1404) n.getBlock().accept(this, arg) ==> void
+  Line 1408) printJavaComment(n.getComment(), arg) ==> void
+  Line 1409) printer.print("try ") ==> void
+  Line 1410) !n.getResources().isEmpty() ==> boolean
+  Line 1411) printer.print("(") ==> void
+  Line 1412) Iterator<VariableDeclarationExpr> resources = n.getResources().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 1412) n.getResources().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 1413) boolean first = true ==> boolean
+  Line 1413) true ==> boolean
+  Line 1414) resources.hasNext() ==> boolean
+  Line 1415) visit(resources.next(), arg) ==> void
+  Line 1416) resources.hasNext() ==> boolean
+  Line 1417) printer.print(";") ==> void
+  Line 1418) printer.printLn() ==> void
+  Line 1419) first ==> boolean
+  Line 1420) printer.indent() ==> void
+  Line 1423) first = false ==> boolean
+  Line 1425) n.getResources().size() > 1 ==> boolean
+  Line 1426) printer.unindent() ==> void
+  Line 1428) printer.print(") ") ==> void
+  Line 1430) n.getTryBlock().accept(this, arg) ==> void
+  Line 1431) n.getCatchs() != null ==> boolean
+  Line 1432) final CatchClause c ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 1432) n.getCatchs() ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 1433) c.accept(this, arg) ==> void
+  Line 1436) n.getFinallyBlock() != null ==> boolean
+  Line 1437) printer.print(" finally ") ==> void
+  Line 1438) n.getFinallyBlock().accept(this, arg) ==> void
+  Line 1443) printJavaComment(n.getComment(), arg) ==> void
+  Line 1444) printer.print(" catch (") ==> void
+  Line 1445) n.getExcept().accept(this, arg) ==> void
+  Line 1446) printer.print(") ") ==> void
+  Line 1447) n.getCatchBlock().accept(this, arg) ==> void
+  Line 1452) printJavaComment(n.getComment(), arg) ==> void
+  Line 1453) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 1454) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 1455) printModifiers(n.getModifiers()) ==> void
+  Line 1457) printer.print("@interface ") ==> void
+  Line 1458) printer.print(n.getName()) ==> void
+  Line 1459) printer.printLn(" {") ==> void
+  Line 1460) printer.indent() ==> void
+  Line 1461) n.getMembers() != null ==> boolean
+  Line 1462) printMembers(n.getMembers(), arg) ==> void
+  Line 1464) printer.unindent() ==> void
+  Line 1465) printer.print("}") ==> void
+  Line 1469) printJavaComment(n.getComment(), arg) ==> void
+  Line 1470) printJavadoc(n.getJavaDoc(), arg) ==> void
+  Line 1471) printMemberAnnotations(n.getAnnotations(), arg) ==> void
+  Line 1472) printModifiers(n.getModifiers()) ==> void
+  Line 1474) n.getType().accept(this, arg) ==> void
+  Line 1475) printer.print(" ") ==> void
+  Line 1476) printer.print(n.getName()) ==> void
+  Line 1477) printer.print("()") ==> void
+  Line 1478) n.getDefaultValue() != null ==> boolean
+  Line 1479) printer.print(" default ") ==> void
+  Line 1480) n.getDefaultValue().accept(this, arg) ==> void
+  Line 1482) printer.print(";") ==> void
+  Line 1486) printJavaComment(n.getComment(), arg) ==> void
+  Line 1487) printer.print("@") ==> void
+  Line 1488) n.getName().accept(this, arg) ==> void
+  Line 1492) printJavaComment(n.getComment(), arg) ==> void
+  Line 1493) printer.print("@") ==> void
+  Line 1494) n.getName().accept(this, arg) ==> void
+  Line 1495) printer.print("(") ==> void
+  Line 1496) n.getMemberValue().accept(this, arg) ==> void
+  Line 1497) printer.print(")") ==> void
+  Line 1501) printJavaComment(n.getComment(), arg) ==> void
+  Line 1502) printer.print("@") ==> void
+  Line 1503) n.getName().accept(this, arg) ==> void
+  Line 1504) printer.print("(") ==> void
+  Line 1505) n.getPairs() != null ==> boolean
+  Line 1506) final Iterator<MemberValuePair> i = n.getPairs().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 1506) n.getPairs().iterator() ==> java.util.Iterator<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 1506) i.hasNext() ==> boolean
+  Line 1507) final MemberValuePair m = i.next() ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 1507) i.next() ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 1508) m.accept(this, arg) ==> void
+  Line 1509) i.hasNext() ==> boolean
+  Line 1510) printer.print(", ") ==> void
+  Line 1514) printer.print(")") ==> void
+  Line 1518) printJavaComment(n.getComment(), arg) ==> void
+  Line 1519) printer.print(n.getName()) ==> void
+  Line 1520) printer.print(" = ") ==> void
+  Line 1521) n.getValue().accept(this, arg) ==> void
+  Line 1525) !this.printComments ==> boolean
+  Line 1528) printer.print("//") ==> void
+  Line 1529) String tmp = n.getContent() ==> java.lang.String
+  Line 1529) n.getContent() ==> java.lang.String
+  Line 1530) tmp = tmp.replace('\r', ' ') ==> java.lang.String
+  Line 1531) tmp = tmp.replace('\n', ' ') ==> java.lang.String
+  Line 1532) printer.printLn(tmp) ==> void
+  Line 1536) !this.printComments ==> boolean
+  Line 1539) printer.print("/*") ==> void
+  Line 1540) printer.print(n.getContent()) ==> void
+  Line 1541) printer.printLn("*/") ==> void
+  Line 1546) printJavaComment(n.getComment(), arg) ==> void
+  Line 1548) List<Parameter> parameters = n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 1548) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 1549) boolean printPar = false ==> boolean
+  Line 1549) false ==> boolean
+  Line 1550) printPar = n.isParametersEnclosed() ==> boolean
+  Line 1552) printPar ==> boolean
+  Line 1553) printer.print("(") ==> void
+  Line 1555) parameters != null ==> boolean
+  Line 1556) Iterator<Parameter> i = parameters.iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.Parameter>
+  Line 1556) parameters.iterator() ==> java.util.Iterator<com.github.javaparser.ast.body.Parameter>
+  Line 1556) i.hasNext() ==> boolean
+  Line 1557) Parameter p = i.next() ==> com.github.javaparser.ast.body.Parameter
+  Line 1557) i.next() ==> com.github.javaparser.ast.body.Parameter
+  Line 1558) p.accept(this, arg) ==> void
+  Line 1559) i.hasNext() ==> boolean
+  Line 1560) printer.print(", ") ==> void
+  Line 1564) printPar ==> boolean
+  Line 1565) printer.print(")") ==> void
+  Line 1568) printer.print(" -> ") ==> void
+  Line 1569) Statement body = n.getBody() ==> com.github.javaparser.ast.stmt.Statement
+  Line 1569) n.getBody() ==> com.github.javaparser.ast.stmt.Statement
+  Line 1570) body instanceof ExpressionStmt ==> boolean
+  Line 1572) ((ExpressionStmt) body).getExpression().accept(this, arg) ==> void
+  Line 1574) body.accept(this, arg) ==> void
+  Line 1581) printJavaComment(n.getComment(), arg) ==> void
+  Line 1582) Expression scope = n.getScope() ==> com.github.javaparser.ast.expr.Expression
+  Line 1582) n.getScope() ==> com.github.javaparser.ast.expr.Expression
+  Line 1583) String identifier = n.getIdentifier() ==> java.lang.String
+  Line 1583) n.getIdentifier() ==> java.lang.String
+  Line 1584) scope != null ==> boolean
+  Line 1585) n.getScope().accept(this, arg) ==> void
+  Line 1588) printer.print("::") ==> void
+  Line 1589) n.getTypeParameters() != null ==> boolean
+  Line 1590) printer.print("<") ==> void
+  Line 1591) Iterator<TypeParameter> i = n.getTypeParameters().iterator() ==> java.util.Iterator<com.github.javaparser.ast.TypeParameter>
+  Line 1591) n.getTypeParameters().iterator() ==> java.util.Iterator<com.github.javaparser.ast.TypeParameter>
+  Line 1591) i.hasNext() ==> boolean
+  Line 1593) TypeParameter p = i.next() ==> com.github.javaparser.ast.TypeParameter
+  Line 1593) i.next() ==> com.github.javaparser.ast.TypeParameter
+  Line 1594) p.accept(this, arg) ==> void
+  Line 1595) i.hasNext() ==> boolean
+  Line 1596) printer.print(", ") ==> void
+  Line 1599) printer.print(">") ==> void
+  Line 1601) identifier != null ==> boolean
+  Line 1602) printer.print(identifier) ==> void
+  Line 1609) printJavaComment(n.getComment(), arg) ==> void
+  Line 1610) n.getType() != null ==> boolean
+  Line 1611) n.getType().accept(this, arg) ==> void
+  Line 1616) node instanceof Comment ==> boolean
+  Line 1618) Node parent = node.getParentNode() ==> com.github.javaparser.ast.Node
+  Line 1618) node.getParentNode() ==> com.github.javaparser.ast.Node
+  Line 1619) parent == null ==> boolean
+  Line 1620) List<Node> everything = new LinkedList<Node>() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 1620) new LinkedList<Node>() ==> java.util.LinkedList<com.github.javaparser.ast.Node>
+  Line 1621) everything.addAll(parent.getChildrenNodes()) ==> boolean
+  Line 1622) sortByBeginPosition(everything) ==> void
+  Line 1623) int positionOfTheChild = -1 ==> int
+  Line 1623) -1 ==> int
+  Line 1624) int i = 0 ==> int
+  Line 1624) 0 ==> int
+  Line 1624) i < everything.size() ==> boolean
+  Line 1624) i++ ==> int
+  Line 1625) everything.get(i) == node ==> boolean
+  Line 1625) positionOfTheChild = i ==> int
+  Line 1627) positionOfTheChild == -1 ==> boolean
+  Line 1627) new RuntimeException("My index not found!!! " + node) ==> java.lang.RuntimeException
+  Line 1628) int positionOfPreviousChild = -1 ==> int
+  Line 1628) -1 ==> int
+  Line 1629) int i = positionOfTheChild - 1 ==> int
+  Line 1629) positionOfTheChild - 1 ==> int
+  Line 1629) i >= 0 && positionOfPreviousChild == -1 ==> boolean
+  Line 1629) i-- ==> int
+  Line 1630) !(everything.get(i) instanceof Comment) ==> boolean
+  Line 1630) positionOfPreviousChild = i ==> int
+  Line 1632) int i = positionOfPreviousChild + 1 ==> int
+  Line 1632) positionOfPreviousChild + 1 ==> int
+  Line 1632) i < positionOfTheChild ==> boolean
+  Line 1632) i++ ==> int
+  Line 1633) Node nodeToPrint = everything.get(i) ==> com.github.javaparser.ast.Node
+  Line 1633) everything.get(i) ==> com.github.javaparser.ast.Node
+  Line 1634) !(nodeToPrint instanceof Comment) ==> boolean
+  Line 1634) new RuntimeException("Expected comment, instead " + nodeToPrint.getClass() + ". Position of previous child: " + positionOfPreviousChild + ", position of child " + positionOfTheChild) ==> java.lang.RuntimeException
+  Line 1635) nodeToPrint.accept(this, null) ==> void
+  Line 1641) List<Node> everything = new LinkedList<Node>() ==> java.util.List<com.github.javaparser.ast.Node>
+  Line 1641) new LinkedList<Node>() ==> java.util.LinkedList<com.github.javaparser.ast.Node>
+  Line 1642) everything.addAll(node.getChildrenNodes()) ==> boolean
+  Line 1643) sortByBeginPosition(everything) ==> void
+  Line 1644) everything.size() == 0 ==> boolean
+  Line 1646) int commentsAtEnd = 0 ==> int
+  Line 1646) 0 ==> int
+  Line 1647) boolean findingComments = true ==> boolean
+  Line 1647) true ==> boolean
+  Line 1648) findingComments && commentsAtEnd < everything.size() ==> boolean
+  Line 1649) Node last = everything.get(everything.size() - 1 - commentsAtEnd) ==> com.github.javaparser.ast.Node
+  Line 1649) everything.get(everything.size() - 1 - commentsAtEnd) ==> com.github.javaparser.ast.Node
+  Line 1650) findingComments = (last instanceof Comment) ==> boolean
+  Line 1651) findingComments ==> boolean
+  Line 1651) commentsAtEnd++ ==> int
+  Line 1653) int i = 0 ==> int
+  Line 1653) 0 ==> int
+  Line 1653) i < commentsAtEnd ==> boolean
+  Line 1653) i++ ==> int
+  Line 1654) everything.get(everything.size() - commentsAtEnd + i).accept(this, null) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_EqualsVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_EqualsVisitor.txt
new file mode 100644
index 0000000..48b17f0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_EqualsVisitor.txt
@@ -0,0 +1,720 @@
+
+[ Class com.github.javaparser.ast.visitor.EqualsVisitor ]
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.visitor.GenericVisitor
+  Line 80) new EqualsVisitor() ==> com.github.javaparser.ast.visitor.EqualsVisitor
+  Line 83) SINGLETON.nodeEquals(n1, n2) ==> boolean
+  Line 95) !nodeEquals(n1.getComment(), n2.getComment()) ==> boolean
+  Line 96) false ==> boolean
+  Line 98) !nodesEquals(n1.getOrphanComments(), n2.getOrphanComments()) ==> boolean
+  Line 99) false ==> boolean
+  Line 101) true ==> boolean
+  Line 105) nodes1 == null ==> boolean
+  Line 106) nodes2 == null ==> boolean
+  Line 107) true ==> boolean
+  Line 109) false ==> boolean
+  Line 110) nodes2 == null ==> boolean
+  Line 111) false ==> boolean
+  Line 113) nodes1.size() != nodes2.size() ==> boolean
+  Line 114) false ==> boolean
+  Line 116) int i = 0 ==> int
+  Line 116) 0 ==> int
+  Line 116) i < nodes1.size() ==> boolean
+  Line 116) i++ ==> int
+  Line 117) !nodeEquals(nodes1.get(i), nodes2.get(i)) ==> boolean
+  Line 118) false ==> boolean
+  Line 121) true ==> boolean
+  Line 125) n1 == n2 ==> boolean
+  Line 126) true ==> boolean
+  Line 128) n1 == null ==> boolean
+  Line 129) n2 == null ==> boolean
+  Line 130) true ==> boolean
+  Line 132) false ==> boolean
+  Line 133) n2 == null ==> boolean
+  Line 134) false ==> boolean
+  Line 136) n1.getClass() != n2.getClass() ==> boolean
+  Line 137) false ==> boolean
+  Line 139) !commonNodeEquality(n1, n2) ==> boolean
+  Line 140) false ==> boolean
+  Line 142) n1.accept(this, n2).booleanValue() ==> boolean
+  Line 146) n1 == n2 ==> boolean
+  Line 147) true ==> boolean
+  Line 149) n1 == null ==> boolean
+  Line 150) n2 == null ==> boolean
+  Line 151) true ==> boolean
+  Line 153) false ==> boolean
+  Line 154) n2 == null ==> boolean
+  Line 155) false ==> boolean
+  Line 157) n1.equals(n2) ==> boolean
+  Line 161) final CompilationUnit n2 = (CompilationUnit) arg ==> com.github.javaparser.ast.CompilationUnit
+  Line 161) (CompilationUnit) arg ==> com.github.javaparser.ast.CompilationUnit
+  Line 163) !nodeEquals(n1.getPackage(), n2.getPackage()) ==> boolean
+  Line 164) Boolean.FALSE ==> java.lang.Boolean
+  Line 167) !nodesEquals(n1.getImports(), n2.getImports()) ==> boolean
+  Line 168) Boolean.FALSE ==> java.lang.Boolean
+  Line 171) !nodesEquals(n1.getTypes(), n2.getTypes()) ==> boolean
+  Line 172) Boolean.FALSE ==> java.lang.Boolean
+  Line 175) !nodesEquals(n1.getComments(), n2.getComments()) ==> boolean
+  Line 176) Boolean.FALSE ==> java.lang.Boolean
+  Line 179) Boolean.TRUE ==> java.lang.Boolean
+  Line 183) final PackageDeclaration n2 = (PackageDeclaration) arg ==> com.github.javaparser.ast.PackageDeclaration
+  Line 183) (PackageDeclaration) arg ==> com.github.javaparser.ast.PackageDeclaration
+  Line 185) !nodeEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 186) Boolean.FALSE ==> java.lang.Boolean
+  Line 189) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 190) Boolean.FALSE ==> java.lang.Boolean
+  Line 193) Boolean.TRUE ==> java.lang.Boolean
+  Line 197) final ImportDeclaration n2 = (ImportDeclaration) arg ==> com.github.javaparser.ast.ImportDeclaration
+  Line 197) (ImportDeclaration) arg ==> com.github.javaparser.ast.ImportDeclaration
+  Line 199) !nodeEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 200) Boolean.FALSE ==> java.lang.Boolean
+  Line 203) Boolean.TRUE ==> java.lang.Boolean
+  Line 207) final TypeParameter n2 = (TypeParameter) arg ==> com.github.javaparser.ast.TypeParameter
+  Line 207) (TypeParameter) arg ==> com.github.javaparser.ast.TypeParameter
+  Line 209) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 210) Boolean.FALSE ==> java.lang.Boolean
+  Line 213) !nodesEquals(n1.getTypeBound(), n2.getTypeBound()) ==> boolean
+  Line 214) Boolean.FALSE ==> java.lang.Boolean
+  Line 216) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 217) Boolean.FALSE ==> java.lang.Boolean
+  Line 219) Boolean.TRUE ==> java.lang.Boolean
+  Line 223) final LineComment n2 = (LineComment) arg ==> com.github.javaparser.ast.comments.LineComment
+  Line 223) (LineComment) arg ==> com.github.javaparser.ast.comments.LineComment
+  Line 225) !objEquals(n1.getContent(), n2.getContent()) ==> boolean
+  Line 226) Boolean.FALSE ==> java.lang.Boolean
+  Line 229) !objEquals(n1.getBeginLine(), n2.getBeginLine()) ==> boolean
+  Line 230) Boolean.FALSE ==> java.lang.Boolean
+  Line 233) Boolean.TRUE ==> java.lang.Boolean
+  Line 237) final BlockComment n2 = (BlockComment) arg ==> com.github.javaparser.ast.comments.BlockComment
+  Line 237) (BlockComment) arg ==> com.github.javaparser.ast.comments.BlockComment
+  Line 239) !objEquals(n1.getContent(), n2.getContent()) ==> boolean
+  Line 240) Boolean.FALSE ==> java.lang.Boolean
+  Line 243) !objEquals(n1.getBeginLine(), n2.getBeginLine()) ==> boolean
+  Line 244) Boolean.FALSE ==> java.lang.Boolean
+  Line 247) Boolean.TRUE ==> java.lang.Boolean
+  Line 251) final ClassOrInterfaceDeclaration n2 = (ClassOrInterfaceDeclaration) arg ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 251) (ClassOrInterfaceDeclaration) arg ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 255) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 256) Boolean.FALSE ==> java.lang.Boolean
+  Line 259) n1.isInterface() != n2.isInterface() ==> boolean
+  Line 260) Boolean.FALSE ==> java.lang.Boolean
+  Line 263) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 264) Boolean.FALSE ==> java.lang.Boolean
+  Line 267) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 268) Boolean.FALSE ==> java.lang.Boolean
+  Line 271) !nodesEquals(n1.getTypeParameters(), n2.getTypeParameters()) ==> boolean
+  Line 272) Boolean.FALSE ==> java.lang.Boolean
+  Line 275) !nodesEquals(n1.getExtends(), n2.getExtends()) ==> boolean
+  Line 276) Boolean.FALSE ==> java.lang.Boolean
+  Line 279) !nodesEquals(n1.getImplements(), n2.getImplements()) ==> boolean
+  Line 280) Boolean.FALSE ==> java.lang.Boolean
+  Line 283) !nodesEquals(n1.getMembers(), n2.getMembers()) ==> boolean
+  Line 284) Boolean.FALSE ==> java.lang.Boolean
+  Line 287) Boolean.TRUE ==> java.lang.Boolean
+  Line 291) final EnumDeclaration n2 = (EnumDeclaration) arg ==> com.github.javaparser.ast.body.EnumDeclaration
+  Line 291) (EnumDeclaration) arg ==> com.github.javaparser.ast.body.EnumDeclaration
+  Line 295) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 296) Boolean.FALSE ==> java.lang.Boolean
+  Line 299) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 300) Boolean.FALSE ==> java.lang.Boolean
+  Line 303) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 304) Boolean.FALSE ==> java.lang.Boolean
+  Line 307) !nodesEquals(n1.getImplements(), n2.getImplements()) ==> boolean
+  Line 308) Boolean.FALSE ==> java.lang.Boolean
+  Line 311) !nodesEquals(n1.getEntries(), n2.getEntries()) ==> boolean
+  Line 312) Boolean.FALSE ==> java.lang.Boolean
+  Line 315) !nodesEquals(n1.getMembers(), n2.getMembers()) ==> boolean
+  Line 316) Boolean.FALSE ==> java.lang.Boolean
+  Line 319) Boolean.TRUE ==> java.lang.Boolean
+  Line 323) Boolean.TRUE ==> java.lang.Boolean
+  Line 327) final EnumConstantDeclaration n2 = (EnumConstantDeclaration) arg ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 327) (EnumConstantDeclaration) arg ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 331) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 332) Boolean.FALSE ==> java.lang.Boolean
+  Line 335) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 336) Boolean.FALSE ==> java.lang.Boolean
+  Line 339) !nodesEquals(n1.getArgs(), n2.getArgs()) ==> boolean
+  Line 340) Boolean.FALSE ==> java.lang.Boolean
+  Line 343) !nodesEquals(n1.getClassBody(), n2.getClassBody()) ==> boolean
+  Line 344) Boolean.FALSE ==> java.lang.Boolean
+  Line 347) Boolean.TRUE ==> java.lang.Boolean
+  Line 351) final AnnotationDeclaration n2 = (AnnotationDeclaration) arg ==> com.github.javaparser.ast.body.AnnotationDeclaration
+  Line 351) (AnnotationDeclaration) arg ==> com.github.javaparser.ast.body.AnnotationDeclaration
+  Line 355) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 356) Boolean.FALSE ==> java.lang.Boolean
+  Line 359) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 360) Boolean.FALSE ==> java.lang.Boolean
+  Line 363) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 364) Boolean.FALSE ==> java.lang.Boolean
+  Line 367) !nodesEquals(n1.getMembers(), n2.getMembers()) ==> boolean
+  Line 368) Boolean.FALSE ==> java.lang.Boolean
+  Line 371) Boolean.TRUE ==> java.lang.Boolean
+  Line 375) final AnnotationMemberDeclaration n2 = (AnnotationMemberDeclaration) arg ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration
+  Line 375) (AnnotationMemberDeclaration) arg ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration
+  Line 379) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 380) Boolean.FALSE ==> java.lang.Boolean
+  Line 383) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 384) Boolean.FALSE ==> java.lang.Boolean
+  Line 387) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 388) Boolean.FALSE ==> java.lang.Boolean
+  Line 391) !nodeEquals(n1.getDefaultValue(), n2.getDefaultValue()) ==> boolean
+  Line 392) Boolean.FALSE ==> java.lang.Boolean
+  Line 395) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 396) Boolean.FALSE ==> java.lang.Boolean
+  Line 399) Boolean.TRUE ==> java.lang.Boolean
+  Line 403) final FieldDeclaration n2 = (FieldDeclaration) arg ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 403) (FieldDeclaration) arg ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 407) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 408) Boolean.FALSE ==> java.lang.Boolean
+  Line 411) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 412) Boolean.FALSE ==> java.lang.Boolean
+  Line 415) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 416) Boolean.FALSE ==> java.lang.Boolean
+  Line 419) !nodesEquals(n1.getVariables(), n2.getVariables()) ==> boolean
+  Line 420) Boolean.FALSE ==> java.lang.Boolean
+  Line 423) Boolean.TRUE ==> java.lang.Boolean
+  Line 427) final VariableDeclarator n2 = (VariableDeclarator) arg ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 427) (VariableDeclarator) arg ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 429) !nodeEquals(n1.getId(), n2.getId()) ==> boolean
+  Line 430) Boolean.FALSE ==> java.lang.Boolean
+  Line 433) !nodeEquals(n1.getInit(), n2.getInit()) ==> boolean
+  Line 434) Boolean.FALSE ==> java.lang.Boolean
+  Line 437) Boolean.TRUE ==> java.lang.Boolean
+  Line 441) final VariableDeclaratorId n2 = (VariableDeclaratorId) arg ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 441) (VariableDeclaratorId) arg ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 443) n1.getArrayCount() != n2.getArrayCount() ==> boolean
+  Line 444) Boolean.FALSE ==> java.lang.Boolean
+  Line 447) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 448) Boolean.FALSE ==> java.lang.Boolean
+  Line 451) Boolean.TRUE ==> java.lang.Boolean
+  Line 455) final ConstructorDeclaration n2 = (ConstructorDeclaration) arg ==> com.github.javaparser.ast.body.ConstructorDeclaration
+  Line 455) (ConstructorDeclaration) arg ==> com.github.javaparser.ast.body.ConstructorDeclaration
+  Line 459) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 460) Boolean.FALSE ==> java.lang.Boolean
+  Line 463) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 464) Boolean.FALSE ==> java.lang.Boolean
+  Line 467) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 468) Boolean.FALSE ==> java.lang.Boolean
+  Line 471) !nodeEquals(n1.getBlock(), n2.getBlock()) ==> boolean
+  Line 472) Boolean.FALSE ==> java.lang.Boolean
+  Line 475) !nodesEquals(n1.getParameters(), n2.getParameters()) ==> boolean
+  Line 476) Boolean.FALSE ==> java.lang.Boolean
+  Line 479) !nodesEquals(n1.getThrows(), n2.getThrows()) ==> boolean
+  Line 480) Boolean.FALSE ==> java.lang.Boolean
+  Line 483) !nodesEquals(n1.getTypeParameters(), n2.getTypeParameters()) ==> boolean
+  Line 484) Boolean.FALSE ==> java.lang.Boolean
+  Line 487) Boolean.TRUE ==> java.lang.Boolean
+  Line 491) final MethodDeclaration n2 = (MethodDeclaration) arg ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 491) (MethodDeclaration) arg ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 495) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 496) Boolean.FALSE ==> java.lang.Boolean
+  Line 499) n1.getArrayCount() != n2.getArrayCount() ==> boolean
+  Line 500) Boolean.FALSE ==> java.lang.Boolean
+  Line 503) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 504) Boolean.FALSE ==> java.lang.Boolean
+  Line 507) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 508) Boolean.FALSE ==> java.lang.Boolean
+  Line 511) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 512) Boolean.FALSE ==> java.lang.Boolean
+  Line 515) !nodeEquals(n1.getBody(), n2.getBody()) ==> boolean
+  Line 516) Boolean.FALSE ==> java.lang.Boolean
+  Line 519) !nodesEquals(n1.getParameters(), n2.getParameters()) ==> boolean
+  Line 520) Boolean.FALSE ==> java.lang.Boolean
+  Line 523) !nodesEquals(n1.getThrows(), n2.getThrows()) ==> boolean
+  Line 524) Boolean.FALSE ==> java.lang.Boolean
+  Line 527) !nodesEquals(n1.getTypeParameters(), n2.getTypeParameters()) ==> boolean
+  Line 528) Boolean.FALSE ==> java.lang.Boolean
+  Line 530) n1.isDefault() != n2.isDefault() ==> boolean
+  Line 531) Boolean.FALSE ==> java.lang.Boolean
+  Line 533) Boolean.TRUE ==> java.lang.Boolean
+  Line 537) final Parameter n2 = (Parameter) arg ==> com.github.javaparser.ast.body.Parameter
+  Line 537) (Parameter) arg ==> com.github.javaparser.ast.body.Parameter
+  Line 538) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 539) Boolean.FALSE ==> java.lang.Boolean
+  Line 541) visit((BaseParameter) n1, arg) ==> java.lang.Boolean
+  Line 545) MultiTypeParameter n2 = (MultiTypeParameter) arg ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 545) (MultiTypeParameter) arg ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 546) n1.getTypes().size() != n2.getTypes().size() ==> boolean
+  Line 547) Boolean.FALSE ==> java.lang.Boolean
+  Line 549) Iterator<Type> n1types = n1.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 549) n1.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 550) Iterator<Type> n2types = n2.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 550) n2.getTypes().iterator() ==> java.util.Iterator<com.github.javaparser.ast.type.Type>
+  Line 551) n1types.hasNext() && n2types.hasNext() ==> boolean
+  Line 552) !nodeEquals(n1types.next(), n2types.next()) ==> boolean
+  Line 553) Boolean.FALSE ==> java.lang.Boolean
+  Line 556) visit((BaseParameter) n1, arg) ==> java.lang.Boolean
+  Line 560) final BaseParameter n2 = (BaseParameter) arg ==> com.github.javaparser.ast.body.BaseParameter
+  Line 560) (BaseParameter) arg ==> com.github.javaparser.ast.body.BaseParameter
+  Line 562) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 563) Boolean.FALSE ==> java.lang.Boolean
+  Line 566) !nodeEquals(n1.getId(), n2.getId()) ==> boolean
+  Line 567) Boolean.FALSE ==> java.lang.Boolean
+  Line 570) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 571) Boolean.FALSE ==> java.lang.Boolean
+  Line 574) Boolean.TRUE ==> java.lang.Boolean
+  Line 578) Boolean.TRUE ==> java.lang.Boolean
+  Line 582) final InitializerDeclaration n2 = (InitializerDeclaration) arg ==> com.github.javaparser.ast.body.InitializerDeclaration
+  Line 582) (InitializerDeclaration) arg ==> com.github.javaparser.ast.body.InitializerDeclaration
+  Line 584) !nodeEquals(n1.getBlock(), n2.getBlock()) ==> boolean
+  Line 585) Boolean.FALSE ==> java.lang.Boolean
+  Line 588) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 589) Boolean.FALSE ==> java.lang.Boolean
+  Line 592) Boolean.TRUE ==> java.lang.Boolean
+  Line 596) final JavadocComment n2 = (JavadocComment) arg ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 596) (JavadocComment) arg ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 598) !objEquals(n1.getContent(), n2.getContent()) ==> boolean
+  Line 599) Boolean.FALSE ==> java.lang.Boolean
+  Line 602) Boolean.TRUE ==> java.lang.Boolean
+  Line 606) final ClassOrInterfaceType n2 = (ClassOrInterfaceType) arg ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 606) (ClassOrInterfaceType) arg ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 608) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 609) Boolean.FALSE ==> java.lang.Boolean
+  Line 612) !nodeEquals(n1.getScope(), n2.getScope()) ==> boolean
+  Line 613) Boolean.FALSE ==> java.lang.Boolean
+  Line 616) !nodesEquals(n1.getTypeArgs(), n2.getTypeArgs()) ==> boolean
+  Line 617) Boolean.FALSE ==> java.lang.Boolean
+  Line 619) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 620) Boolean.FALSE ==> java.lang.Boolean
+  Line 622) Boolean.TRUE ==> java.lang.Boolean
+  Line 626) final PrimitiveType n2 = (PrimitiveType) arg ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 626) (PrimitiveType) arg ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 628) n1.getType() != n2.getType() ==> boolean
+  Line 629) Boolean.FALSE ==> java.lang.Boolean
+  Line 631) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 632) Boolean.FALSE ==> java.lang.Boolean
+  Line 634) Boolean.TRUE ==> java.lang.Boolean
+  Line 638) final ReferenceType n2 = (ReferenceType) arg ==> com.github.javaparser.ast.type.ReferenceType
+  Line 638) (ReferenceType) arg ==> com.github.javaparser.ast.type.ReferenceType
+  Line 640) n1.getArrayCount() != n2.getArrayCount() ==> boolean
+  Line 641) Boolean.FALSE ==> java.lang.Boolean
+  Line 643) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 644) Boolean.FALSE ==> java.lang.Boolean
+  Line 646) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 647) Boolean.FALSE ==> java.lang.Boolean
+  Line 649) List<List<AnnotationExpr>> n1a = n1.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 649) n1.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 650) List<List<AnnotationExpr>> n2a = n2.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 650) n2.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 652) n1a != null && n2a != null ==> boolean
+  Line 653) n1a.size() != n2a.size() ==> boolean
+  Line 654) Boolean.FALSE ==> java.lang.Boolean
+  Line 657) int i = 0 ==> int
+  Line 657) 0 ==> int
+  Line 658) List<AnnotationExpr> aux ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 658) n1a ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 659) !nodesEquals(aux, n2a.get(i)) ==> boolean
+  Line 660) Boolean.FALSE ==> java.lang.Boolean
+  Line 662) i++ ==> int
+  Line 666) n1a != n2a ==> boolean
+  Line 667) Boolean.FALSE ==> java.lang.Boolean
+  Line 669) Boolean.TRUE ==> java.lang.Boolean
+  Line 673) VoidType n2 = (VoidType) arg ==> com.github.javaparser.ast.type.VoidType
+  Line 673) (VoidType) arg ==> com.github.javaparser.ast.type.VoidType
+  Line 674) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 675) Boolean.FALSE ==> java.lang.Boolean
+  Line 677) Boolean.TRUE ==> java.lang.Boolean
+  Line 681) final WildcardType n2 = (WildcardType) arg ==> com.github.javaparser.ast.type.WildcardType
+  Line 681) (WildcardType) arg ==> com.github.javaparser.ast.type.WildcardType
+  Line 683) !nodeEquals(n1.getExtends(), n2.getExtends()) ==> boolean
+  Line 684) Boolean.FALSE ==> java.lang.Boolean
+  Line 687) !nodeEquals(n1.getSuper(), n2.getSuper()) ==> boolean
+  Line 688) Boolean.FALSE ==> java.lang.Boolean
+  Line 690) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 691) Boolean.FALSE ==> java.lang.Boolean
+  Line 693) Boolean.TRUE ==> java.lang.Boolean
+  Line 697) final WildcardType n2 = (WildcardType) arg ==> com.github.javaparser.ast.type.WildcardType
+  Line 697) (WildcardType) arg ==> com.github.javaparser.ast.type.WildcardType
+  Line 699) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 700) Boolean.FALSE ==> java.lang.Boolean
+  Line 702) Boolean.TRUE ==> java.lang.Boolean
+  Line 706) final ArrayAccessExpr n2 = (ArrayAccessExpr) arg ==> com.github.javaparser.ast.expr.ArrayAccessExpr
+  Line 706) (ArrayAccessExpr) arg ==> com.github.javaparser.ast.expr.ArrayAccessExpr
+  Line 708) !nodeEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 709) Boolean.FALSE ==> java.lang.Boolean
+  Line 712) !nodeEquals(n1.getIndex(), n2.getIndex()) ==> boolean
+  Line 713) Boolean.FALSE ==> java.lang.Boolean
+  Line 716) Boolean.TRUE ==> java.lang.Boolean
+  Line 720) final ArrayCreationExpr n2 = (ArrayCreationExpr) arg ==> com.github.javaparser.ast.expr.ArrayCreationExpr
+  Line 720) (ArrayCreationExpr) arg ==> com.github.javaparser.ast.expr.ArrayCreationExpr
+  Line 722) n1.getArrayCount() != n2.getArrayCount() ==> boolean
+  Line 723) Boolean.FALSE ==> java.lang.Boolean
+  Line 726) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 727) Boolean.FALSE ==> java.lang.Boolean
+  Line 730) !nodeEquals(n1.getInitializer(), n2.getInitializer()) ==> boolean
+  Line 731) Boolean.FALSE ==> java.lang.Boolean
+  Line 734) !nodesEquals(n1.getDimensions(), n2.getDimensions()) ==> boolean
+  Line 735) Boolean.FALSE ==> java.lang.Boolean
+  Line 737) List<List<AnnotationExpr>> n1a = n1.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 737) n1.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 738) List<List<AnnotationExpr>> n2a = n2.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 738) n2.getArraysAnnotations() ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 740) n1a != null && n2a != null ==> boolean
+  Line 741) n1a.size() != n2a.size() ==> boolean
+  Line 742) Boolean.FALSE ==> java.lang.Boolean
+  Line 745) int i = 0 ==> int
+  Line 745) 0 ==> int
+  Line 746) List<AnnotationExpr> aux ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 746) n1a ==> java.util.List<java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>>
+  Line 747) !nodesEquals(aux, n2a.get(i)) ==> boolean
+  Line 748) Boolean.FALSE ==> java.lang.Boolean
+  Line 750) i++ ==> int
+  Line 754) n1a != n2a ==> boolean
+  Line 755) Boolean.FALSE ==> java.lang.Boolean
+  Line 757) Boolean.TRUE ==> java.lang.Boolean
+  Line 761) final ArrayInitializerExpr n2 = (ArrayInitializerExpr) arg ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 761) (ArrayInitializerExpr) arg ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 763) !nodesEquals(n1.getValues(), n2.getValues()) ==> boolean
+  Line 764) Boolean.FALSE ==> java.lang.Boolean
+  Line 767) Boolean.TRUE ==> java.lang.Boolean
+  Line 771) final AssignExpr n2 = (AssignExpr) arg ==> com.github.javaparser.ast.expr.AssignExpr
+  Line 771) (AssignExpr) arg ==> com.github.javaparser.ast.expr.AssignExpr
+  Line 773) n1.getOperator() != n2.getOperator() ==> boolean
+  Line 774) Boolean.FALSE ==> java.lang.Boolean
+  Line 777) !nodeEquals(n1.getTarget(), n2.getTarget()) ==> boolean
+  Line 778) Boolean.FALSE ==> java.lang.Boolean
+  Line 781) !nodeEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 782) Boolean.FALSE ==> java.lang.Boolean
+  Line 785) Boolean.TRUE ==> java.lang.Boolean
+  Line 789) final BinaryExpr n2 = (BinaryExpr) arg ==> com.github.javaparser.ast.expr.BinaryExpr
+  Line 789) (BinaryExpr) arg ==> com.github.javaparser.ast.expr.BinaryExpr
+  Line 791) n1.getOperator() != n2.getOperator() ==> boolean
+  Line 792) Boolean.FALSE ==> java.lang.Boolean
+  Line 795) !nodeEquals(n1.getLeft(), n2.getLeft()) ==> boolean
+  Line 796) Boolean.FALSE ==> java.lang.Boolean
+  Line 799) !nodeEquals(n1.getRight(), n2.getRight()) ==> boolean
+  Line 800) Boolean.FALSE ==> java.lang.Boolean
+  Line 803) Boolean.TRUE ==> java.lang.Boolean
+  Line 807) final CastExpr n2 = (CastExpr) arg ==> com.github.javaparser.ast.expr.CastExpr
+  Line 807) (CastExpr) arg ==> com.github.javaparser.ast.expr.CastExpr
+  Line 809) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 810) Boolean.FALSE ==> java.lang.Boolean
+  Line 813) !nodeEquals(n1.getExpr(), n2.getExpr()) ==> boolean
+  Line 814) Boolean.FALSE ==> java.lang.Boolean
+  Line 817) Boolean.TRUE ==> java.lang.Boolean
+  Line 821) final ClassExpr n2 = (ClassExpr) arg ==> com.github.javaparser.ast.expr.ClassExpr
+  Line 821) (ClassExpr) arg ==> com.github.javaparser.ast.expr.ClassExpr
+  Line 823) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 824) Boolean.FALSE ==> java.lang.Boolean
+  Line 827) Boolean.TRUE ==> java.lang.Boolean
+  Line 831) final ConditionalExpr n2 = (ConditionalExpr) arg ==> com.github.javaparser.ast.expr.ConditionalExpr
+  Line 831) (ConditionalExpr) arg ==> com.github.javaparser.ast.expr.ConditionalExpr
+  Line 833) !nodeEquals(n1.getCondition(), n2.getCondition()) ==> boolean
+  Line 834) Boolean.FALSE ==> java.lang.Boolean
+  Line 837) !nodeEquals(n1.getThenExpr(), n2.getThenExpr()) ==> boolean
+  Line 838) Boolean.FALSE ==> java.lang.Boolean
+  Line 841) !nodeEquals(n1.getElseExpr(), n2.getElseExpr()) ==> boolean
+  Line 842) Boolean.FALSE ==> java.lang.Boolean
+  Line 845) Boolean.TRUE ==> java.lang.Boolean
+  Line 849) final EnclosedExpr n2 = (EnclosedExpr) arg ==> com.github.javaparser.ast.expr.EnclosedExpr
+  Line 849) (EnclosedExpr) arg ==> com.github.javaparser.ast.expr.EnclosedExpr
+  Line 851) !nodeEquals(n1.getInner(), n2.getInner()) ==> boolean
+  Line 852) Boolean.FALSE ==> java.lang.Boolean
+  Line 855) Boolean.TRUE ==> java.lang.Boolean
+  Line 859) final FieldAccessExpr n2 = (FieldAccessExpr) arg ==> com.github.javaparser.ast.expr.FieldAccessExpr
+  Line 859) (FieldAccessExpr) arg ==> com.github.javaparser.ast.expr.FieldAccessExpr
+  Line 861) !nodeEquals(n1.getScope(), n2.getScope()) ==> boolean
+  Line 862) Boolean.FALSE ==> java.lang.Boolean
+  Line 865) !objEquals(n1.getField(), n2.getField()) ==> boolean
+  Line 866) Boolean.FALSE ==> java.lang.Boolean
+  Line 869) !nodesEquals(n1.getTypeArgs(), n2.getTypeArgs()) ==> boolean
+  Line 870) Boolean.FALSE ==> java.lang.Boolean
+  Line 873) Boolean.TRUE ==> java.lang.Boolean
+  Line 877) final InstanceOfExpr n2 = (InstanceOfExpr) arg ==> com.github.javaparser.ast.expr.InstanceOfExpr
+  Line 877) (InstanceOfExpr) arg ==> com.github.javaparser.ast.expr.InstanceOfExpr
+  Line 879) !nodeEquals(n1.getExpr(), n2.getExpr()) ==> boolean
+  Line 880) Boolean.FALSE ==> java.lang.Boolean
+  Line 883) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 884) Boolean.FALSE ==> java.lang.Boolean
+  Line 887) Boolean.TRUE ==> java.lang.Boolean
+  Line 891) final StringLiteralExpr n2 = (StringLiteralExpr) arg ==> com.github.javaparser.ast.expr.StringLiteralExpr
+  Line 891) (StringLiteralExpr) arg ==> com.github.javaparser.ast.expr.StringLiteralExpr
+  Line 893) !objEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 894) Boolean.FALSE ==> java.lang.Boolean
+  Line 897) Boolean.TRUE ==> java.lang.Boolean
+  Line 901) final IntegerLiteralExpr n2 = (IntegerLiteralExpr) arg ==> com.github.javaparser.ast.expr.IntegerLiteralExpr
+  Line 901) (IntegerLiteralExpr) arg ==> com.github.javaparser.ast.expr.IntegerLiteralExpr
+  Line 903) !objEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 904) Boolean.FALSE ==> java.lang.Boolean
+  Line 907) Boolean.TRUE ==> java.lang.Boolean
+  Line 911) final LongLiteralExpr n2 = (LongLiteralExpr) arg ==> com.github.javaparser.ast.expr.LongLiteralExpr
+  Line 911) (LongLiteralExpr) arg ==> com.github.javaparser.ast.expr.LongLiteralExpr
+  Line 913) !objEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 914) Boolean.FALSE ==> java.lang.Boolean
+  Line 917) Boolean.TRUE ==> java.lang.Boolean
+  Line 921) final IntegerLiteralMinValueExpr n2 = (IntegerLiteralMinValueExpr) arg ==> com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr
+  Line 921) (IntegerLiteralMinValueExpr) arg ==> com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr
+  Line 923) !objEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 924) Boolean.FALSE ==> java.lang.Boolean
+  Line 927) Boolean.TRUE ==> java.lang.Boolean
+  Line 931) final LongLiteralMinValueExpr n2 = (LongLiteralMinValueExpr) arg ==> com.github.javaparser.ast.expr.LongLiteralMinValueExpr
+  Line 931) (LongLiteralMinValueExpr) arg ==> com.github.javaparser.ast.expr.LongLiteralMinValueExpr
+  Line 933) !objEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 934) Boolean.FALSE ==> java.lang.Boolean
+  Line 937) Boolean.TRUE ==> java.lang.Boolean
+  Line 941) final CharLiteralExpr n2 = (CharLiteralExpr) arg ==> com.github.javaparser.ast.expr.CharLiteralExpr
+  Line 941) (CharLiteralExpr) arg ==> com.github.javaparser.ast.expr.CharLiteralExpr
+  Line 943) !objEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 944) Boolean.FALSE ==> java.lang.Boolean
+  Line 947) Boolean.TRUE ==> java.lang.Boolean
+  Line 951) final DoubleLiteralExpr n2 = (DoubleLiteralExpr) arg ==> com.github.javaparser.ast.expr.DoubleLiteralExpr
+  Line 951) (DoubleLiteralExpr) arg ==> com.github.javaparser.ast.expr.DoubleLiteralExpr
+  Line 953) !objEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 954) Boolean.FALSE ==> java.lang.Boolean
+  Line 957) Boolean.TRUE ==> java.lang.Boolean
+  Line 961) final BooleanLiteralExpr n2 = (BooleanLiteralExpr) arg ==> com.github.javaparser.ast.expr.BooleanLiteralExpr
+  Line 961) (BooleanLiteralExpr) arg ==> com.github.javaparser.ast.expr.BooleanLiteralExpr
+  Line 963) n1.getValue() != n2.getValue() ==> boolean
+  Line 964) Boolean.FALSE ==> java.lang.Boolean
+  Line 967) Boolean.TRUE ==> java.lang.Boolean
+  Line 971) Boolean.TRUE ==> java.lang.Boolean
+  Line 975) final MethodCallExpr n2 = (MethodCallExpr) arg ==> com.github.javaparser.ast.expr.MethodCallExpr
+  Line 975) (MethodCallExpr) arg ==> com.github.javaparser.ast.expr.MethodCallExpr
+  Line 977) !nodeEquals(n1.getScope(), n2.getScope()) ==> boolean
+  Line 978) Boolean.FALSE ==> java.lang.Boolean
+  Line 981) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 982) Boolean.FALSE ==> java.lang.Boolean
+  Line 985) !nodesEquals(n1.getArgs(), n2.getArgs()) ==> boolean
+  Line 986) Boolean.FALSE ==> java.lang.Boolean
+  Line 989) !nodesEquals(n1.getTypeArgs(), n2.getTypeArgs()) ==> boolean
+  Line 990) Boolean.FALSE ==> java.lang.Boolean
+  Line 993) Boolean.TRUE ==> java.lang.Boolean
+  Line 997) final NameExpr n2 = (NameExpr) arg ==> com.github.javaparser.ast.expr.NameExpr
+  Line 997) (NameExpr) arg ==> com.github.javaparser.ast.expr.NameExpr
+  Line 999) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 1000) Boolean.FALSE ==> java.lang.Boolean
+  Line 1003) Boolean.TRUE ==> java.lang.Boolean
+  Line 1007) final ObjectCreationExpr n2 = (ObjectCreationExpr) arg ==> com.github.javaparser.ast.expr.ObjectCreationExpr
+  Line 1007) (ObjectCreationExpr) arg ==> com.github.javaparser.ast.expr.ObjectCreationExpr
+  Line 1009) !nodeEquals(n1.getScope(), n2.getScope()) ==> boolean
+  Line 1010) Boolean.FALSE ==> java.lang.Boolean
+  Line 1013) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 1014) Boolean.FALSE ==> java.lang.Boolean
+  Line 1017) !nodesEquals(n1.getAnonymousClassBody(), n2.getAnonymousClassBody()) ==> boolean
+  Line 1018) Boolean.FALSE ==> java.lang.Boolean
+  Line 1021) !nodesEquals(n1.getArgs(), n2.getArgs()) ==> boolean
+  Line 1022) Boolean.FALSE ==> java.lang.Boolean
+  Line 1025) !nodesEquals(n1.getTypeArgs(), n2.getTypeArgs()) ==> boolean
+  Line 1026) Boolean.FALSE ==> java.lang.Boolean
+  Line 1029) Boolean.TRUE ==> java.lang.Boolean
+  Line 1033) final QualifiedNameExpr n2 = (QualifiedNameExpr) arg ==> com.github.javaparser.ast.expr.QualifiedNameExpr
+  Line 1033) (QualifiedNameExpr) arg ==> com.github.javaparser.ast.expr.QualifiedNameExpr
+  Line 1035) !nodeEquals(n1.getQualifier(), n2.getQualifier()) ==> boolean
+  Line 1036) Boolean.FALSE ==> java.lang.Boolean
+  Line 1039) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 1040) Boolean.FALSE ==> java.lang.Boolean
+  Line 1043) Boolean.TRUE ==> java.lang.Boolean
+  Line 1047) final ThisExpr n2 = (ThisExpr) arg ==> com.github.javaparser.ast.expr.ThisExpr
+  Line 1047) (ThisExpr) arg ==> com.github.javaparser.ast.expr.ThisExpr
+  Line 1049) !nodeEquals(n1.getClassExpr(), n2.getClassExpr()) ==> boolean
+  Line 1050) Boolean.FALSE ==> java.lang.Boolean
+  Line 1053) Boolean.TRUE ==> java.lang.Boolean
+  Line 1057) final SuperExpr n2 = (SuperExpr) arg ==> com.github.javaparser.ast.expr.SuperExpr
+  Line 1057) (SuperExpr) arg ==> com.github.javaparser.ast.expr.SuperExpr
+  Line 1059) !nodeEquals(n1.getClassExpr(), n2.getClassExpr()) ==> boolean
+  Line 1060) Boolean.FALSE ==> java.lang.Boolean
+  Line 1063) Boolean.TRUE ==> java.lang.Boolean
+  Line 1067) final UnaryExpr n2 = (UnaryExpr) arg ==> com.github.javaparser.ast.expr.UnaryExpr
+  Line 1067) (UnaryExpr) arg ==> com.github.javaparser.ast.expr.UnaryExpr
+  Line 1069) n1.getOperator() != n2.getOperator() ==> boolean
+  Line 1070) Boolean.FALSE ==> java.lang.Boolean
+  Line 1073) !nodeEquals(n1.getExpr(), n2.getExpr()) ==> boolean
+  Line 1074) Boolean.FALSE ==> java.lang.Boolean
+  Line 1077) Boolean.TRUE ==> java.lang.Boolean
+  Line 1081) final VariableDeclarationExpr n2 = (VariableDeclarationExpr) arg ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 1081) (VariableDeclarationExpr) arg ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 1083) n1.getModifiers() != n2.getModifiers() ==> boolean
+  Line 1084) Boolean.FALSE ==> java.lang.Boolean
+  Line 1087) !nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> boolean
+  Line 1088) Boolean.FALSE ==> java.lang.Boolean
+  Line 1091) !nodeEquals(n1.getType(), n2.getType()) ==> boolean
+  Line 1092) Boolean.FALSE ==> java.lang.Boolean
+  Line 1095) !nodesEquals(n1.getVars(), n2.getVars()) ==> boolean
+  Line 1096) Boolean.FALSE ==> java.lang.Boolean
+  Line 1099) Boolean.TRUE ==> java.lang.Boolean
+  Line 1103) final MarkerAnnotationExpr n2 = (MarkerAnnotationExpr) arg ==> com.github.javaparser.ast.expr.MarkerAnnotationExpr
+  Line 1103) (MarkerAnnotationExpr) arg ==> com.github.javaparser.ast.expr.MarkerAnnotationExpr
+  Line 1105) !nodeEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 1106) Boolean.FALSE ==> java.lang.Boolean
+  Line 1109) Boolean.TRUE ==> java.lang.Boolean
+  Line 1113) final SingleMemberAnnotationExpr n2 = (SingleMemberAnnotationExpr) arg ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+  Line 1113) (SingleMemberAnnotationExpr) arg ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+  Line 1115) !nodeEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 1116) Boolean.FALSE ==> java.lang.Boolean
+  Line 1119) !nodeEquals(n1.getMemberValue(), n2.getMemberValue()) ==> boolean
+  Line 1120) Boolean.FALSE ==> java.lang.Boolean
+  Line 1123) Boolean.TRUE ==> java.lang.Boolean
+  Line 1127) final NormalAnnotationExpr n2 = (NormalAnnotationExpr) arg ==> com.github.javaparser.ast.expr.NormalAnnotationExpr
+  Line 1127) (NormalAnnotationExpr) arg ==> com.github.javaparser.ast.expr.NormalAnnotationExpr
+  Line 1129) !nodeEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 1130) Boolean.FALSE ==> java.lang.Boolean
+  Line 1133) !nodesEquals(n1.getPairs(), n2.getPairs()) ==> boolean
+  Line 1134) Boolean.FALSE ==> java.lang.Boolean
+  Line 1137) Boolean.TRUE ==> java.lang.Boolean
+  Line 1141) final MemberValuePair n2 = (MemberValuePair) arg ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 1141) (MemberValuePair) arg ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 1143) !objEquals(n1.getName(), n2.getName()) ==> boolean
+  Line 1144) Boolean.FALSE ==> java.lang.Boolean
+  Line 1147) !nodeEquals(n1.getValue(), n2.getValue()) ==> boolean
+  Line 1148) Boolean.FALSE ==> java.lang.Boolean
+  Line 1151) Boolean.TRUE ==> java.lang.Boolean
+  Line 1155) final ExplicitConstructorInvocationStmt n2 = (ExplicitConstructorInvocationStmt) arg ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+  Line 1155) (ExplicitConstructorInvocationStmt) arg ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+  Line 1157) !nodeEquals(n1.getExpr(), n2.getExpr()) ==> boolean
+  Line 1158) Boolean.FALSE ==> java.lang.Boolean
+  Line 1161) !nodesEquals(n1.getArgs(), n2.getArgs()) ==> boolean
+  Line 1162) Boolean.FALSE ==> java.lang.Boolean
+  Line 1165) !nodesEquals(n1.getTypeArgs(), n2.getTypeArgs()) ==> boolean
+  Line 1166) Boolean.FALSE ==> java.lang.Boolean
+  Line 1169) Boolean.TRUE ==> java.lang.Boolean
+  Line 1173) final TypeDeclarationStmt n2 = (TypeDeclarationStmt) arg ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt
+  Line 1173) (TypeDeclarationStmt) arg ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt
+  Line 1175) !nodeEquals(n1.getTypeDeclaration(), n2.getTypeDeclaration()) ==> boolean
+  Line 1176) Boolean.FALSE ==> java.lang.Boolean
+  Line 1179) Boolean.TRUE ==> java.lang.Boolean
+  Line 1183) final AssertStmt n2 = (AssertStmt) arg ==> com.github.javaparser.ast.stmt.AssertStmt
+  Line 1183) (AssertStmt) arg ==> com.github.javaparser.ast.stmt.AssertStmt
+  Line 1185) !nodeEquals(n1.getCheck(), n2.getCheck()) ==> boolean
+  Line 1186) Boolean.FALSE ==> java.lang.Boolean
+  Line 1189) !nodeEquals(n1.getMessage(), n2.getMessage()) ==> boolean
+  Line 1190) Boolean.FALSE ==> java.lang.Boolean
+  Line 1193) Boolean.TRUE ==> java.lang.Boolean
+  Line 1197) final BlockStmt n2 = (BlockStmt) arg ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1197) (BlockStmt) arg ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 1199) !nodesEquals(n1.getStmts(), n2.getStmts()) ==> boolean
+  Line 1200) Boolean.FALSE ==> java.lang.Boolean
+  Line 1203) Boolean.TRUE ==> java.lang.Boolean
+  Line 1207) final LabeledStmt n2 = (LabeledStmt) arg ==> com.github.javaparser.ast.stmt.LabeledStmt
+  Line 1207) (LabeledStmt) arg ==> com.github.javaparser.ast.stmt.LabeledStmt
+  Line 1209) !nodeEquals(n1.getStmt(), n2.getStmt()) ==> boolean
+  Line 1210) Boolean.FALSE ==> java.lang.Boolean
+  Line 1213) Boolean.TRUE ==> java.lang.Boolean
+  Line 1217) Boolean.TRUE ==> java.lang.Boolean
+  Line 1221) final ExpressionStmt n2 = (ExpressionStmt) arg ==> com.github.javaparser.ast.stmt.ExpressionStmt
+  Line 1221) (ExpressionStmt) arg ==> com.github.javaparser.ast.stmt.ExpressionStmt
+  Line 1223) !nodeEquals(n1.getExpression(), n2.getExpression()) ==> boolean
+  Line 1224) Boolean.FALSE ==> java.lang.Boolean
+  Line 1227) Boolean.TRUE ==> java.lang.Boolean
+  Line 1231) final SwitchStmt n2 = (SwitchStmt) arg ==> com.github.javaparser.ast.stmt.SwitchStmt
+  Line 1231) (SwitchStmt) arg ==> com.github.javaparser.ast.stmt.SwitchStmt
+  Line 1233) !nodeEquals(n1.getSelector(), n2.getSelector()) ==> boolean
+  Line 1234) Boolean.FALSE ==> java.lang.Boolean
+  Line 1237) !nodesEquals(n1.getEntries(), n2.getEntries()) ==> boolean
+  Line 1238) Boolean.FALSE ==> java.lang.Boolean
+  Line 1241) Boolean.TRUE ==> java.lang.Boolean
+  Line 1245) final SwitchEntryStmt n2 = (SwitchEntryStmt) arg ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 1245) (SwitchEntryStmt) arg ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 1247) !nodeEquals(n1.getLabel(), n2.getLabel()) ==> boolean
+  Line 1248) Boolean.FALSE ==> java.lang.Boolean
+  Line 1251) !nodesEquals(n1.getStmts(), n2.getStmts()) ==> boolean
+  Line 1252) Boolean.FALSE ==> java.lang.Boolean
+  Line 1255) Boolean.TRUE ==> java.lang.Boolean
+  Line 1259) final BreakStmt n2 = (BreakStmt) arg ==> com.github.javaparser.ast.stmt.BreakStmt
+  Line 1259) (BreakStmt) arg ==> com.github.javaparser.ast.stmt.BreakStmt
+  Line 1261) !objEquals(n1.getId(), n2.getId()) ==> boolean
+  Line 1262) Boolean.FALSE ==> java.lang.Boolean
+  Line 1265) Boolean.TRUE ==> java.lang.Boolean
+  Line 1269) final ReturnStmt n2 = (ReturnStmt) arg ==> com.github.javaparser.ast.stmt.ReturnStmt
+  Line 1269) (ReturnStmt) arg ==> com.github.javaparser.ast.stmt.ReturnStmt
+  Line 1271) !nodeEquals(n1.getExpr(), n2.getExpr()) ==> boolean
+  Line 1272) Boolean.FALSE ==> java.lang.Boolean
+  Line 1275) Boolean.TRUE ==> java.lang.Boolean
+  Line 1279) final IfStmt n2 = (IfStmt) arg ==> com.github.javaparser.ast.stmt.IfStmt
+  Line 1279) (IfStmt) arg ==> com.github.javaparser.ast.stmt.IfStmt
+  Line 1281) !nodeEquals(n1.getCondition(), n2.getCondition()) ==> boolean
+  Line 1282) Boolean.FALSE ==> java.lang.Boolean
+  Line 1285) !nodeEquals(n1.getThenStmt(), n2.getThenStmt()) ==> boolean
+  Line 1286) Boolean.FALSE ==> java.lang.Boolean
+  Line 1289) !nodeEquals(n1.getElseStmt(), n2.getElseStmt()) ==> boolean
+  Line 1290) Boolean.FALSE ==> java.lang.Boolean
+  Line 1293) Boolean.TRUE ==> java.lang.Boolean
+  Line 1297) final WhileStmt n2 = (WhileStmt) arg ==> com.github.javaparser.ast.stmt.WhileStmt
+  Line 1297) (WhileStmt) arg ==> com.github.javaparser.ast.stmt.WhileStmt
+  Line 1299) !nodeEquals(n1.getCondition(), n2.getCondition()) ==> boolean
+  Line 1300) Boolean.FALSE ==> java.lang.Boolean
+  Line 1303) !nodeEquals(n1.getBody(), n2.getBody()) ==> boolean
+  Line 1304) Boolean.FALSE ==> java.lang.Boolean
+  Line 1307) Boolean.TRUE ==> java.lang.Boolean
+  Line 1311) final ContinueStmt n2 = (ContinueStmt) arg ==> com.github.javaparser.ast.stmt.ContinueStmt
+  Line 1311) (ContinueStmt) arg ==> com.github.javaparser.ast.stmt.ContinueStmt
+  Line 1313) !objEquals(n1.getId(), n2.getId()) ==> boolean
+  Line 1314) Boolean.FALSE ==> java.lang.Boolean
+  Line 1317) Boolean.TRUE ==> java.lang.Boolean
+  Line 1321) final DoStmt n2 = (DoStmt) arg ==> com.github.javaparser.ast.stmt.DoStmt
+  Line 1321) (DoStmt) arg ==> com.github.javaparser.ast.stmt.DoStmt
+  Line 1323) !nodeEquals(n1.getBody(), n2.getBody()) ==> boolean
+  Line 1324) Boolean.FALSE ==> java.lang.Boolean
+  Line 1327) !nodeEquals(n1.getCondition(), n2.getCondition()) ==> boolean
+  Line 1328) Boolean.FALSE ==> java.lang.Boolean
+  Line 1331) Boolean.TRUE ==> java.lang.Boolean
+  Line 1335) final ForeachStmt n2 = (ForeachStmt) arg ==> com.github.javaparser.ast.stmt.ForeachStmt
+  Line 1335) (ForeachStmt) arg ==> com.github.javaparser.ast.stmt.ForeachStmt
+  Line 1337) !nodeEquals(n1.getVariable(), n2.getVariable()) ==> boolean
+  Line 1338) Boolean.FALSE ==> java.lang.Boolean
+  Line 1341) !nodeEquals(n1.getIterable(), n2.getIterable()) ==> boolean
+  Line 1342) Boolean.FALSE ==> java.lang.Boolean
+  Line 1345) !nodeEquals(n1.getBody(), n2.getBody()) ==> boolean
+  Line 1346) Boolean.FALSE ==> java.lang.Boolean
+  Line 1349) Boolean.TRUE ==> java.lang.Boolean
+  Line 1353) final ForStmt n2 = (ForStmt) arg ==> com.github.javaparser.ast.stmt.ForStmt
+  Line 1353) (ForStmt) arg ==> com.github.javaparser.ast.stmt.ForStmt
+  Line 1355) !nodesEquals(n1.getInit(), n2.getInit()) ==> boolean
+  Line 1356) Boolean.FALSE ==> java.lang.Boolean
+  Line 1359) !nodeEquals(n1.getCompare(), n2.getCompare()) ==> boolean
+  Line 1360) Boolean.FALSE ==> java.lang.Boolean
+  Line 1363) !nodesEquals(n1.getUpdate(), n2.getUpdate()) ==> boolean
+  Line 1364) Boolean.FALSE ==> java.lang.Boolean
+  Line 1367) !nodeEquals(n1.getBody(), n2.getBody()) ==> boolean
+  Line 1368) Boolean.FALSE ==> java.lang.Boolean
+  Line 1371) Boolean.TRUE ==> java.lang.Boolean
+  Line 1375) final ThrowStmt n2 = (ThrowStmt) arg ==> com.github.javaparser.ast.stmt.ThrowStmt
+  Line 1375) (ThrowStmt) arg ==> com.github.javaparser.ast.stmt.ThrowStmt
+  Line 1377) !nodeEquals(n1.getExpr(), n2.getExpr()) ==> boolean
+  Line 1378) Boolean.FALSE ==> java.lang.Boolean
+  Line 1381) Boolean.TRUE ==> java.lang.Boolean
+  Line 1385) final SynchronizedStmt n2 = (SynchronizedStmt) arg ==> com.github.javaparser.ast.stmt.SynchronizedStmt
+  Line 1385) (SynchronizedStmt) arg ==> com.github.javaparser.ast.stmt.SynchronizedStmt
+  Line 1387) !nodeEquals(n1.getExpr(), n2.getExpr()) ==> boolean
+  Line 1388) Boolean.FALSE ==> java.lang.Boolean
+  Line 1391) !nodeEquals(n1.getBlock(), n2.getBlock()) ==> boolean
+  Line 1392) Boolean.FALSE ==> java.lang.Boolean
+  Line 1395) Boolean.TRUE ==> java.lang.Boolean
+  Line 1399) final TryStmt n2 = (TryStmt) arg ==> com.github.javaparser.ast.stmt.TryStmt
+  Line 1399) (TryStmt) arg ==> com.github.javaparser.ast.stmt.TryStmt
+  Line 1401) !nodeEquals(n1.getTryBlock(), n2.getTryBlock()) ==> boolean
+  Line 1402) Boolean.FALSE ==> java.lang.Boolean
+  Line 1405) !nodesEquals(n1.getCatchs(), n2.getCatchs()) ==> boolean
+  Line 1406) Boolean.FALSE ==> java.lang.Boolean
+  Line 1409) !nodeEquals(n1.getFinallyBlock(), n2.getFinallyBlock()) ==> boolean
+  Line 1410) Boolean.FALSE ==> java.lang.Boolean
+  Line 1413) Boolean.TRUE ==> java.lang.Boolean
+  Line 1417) final CatchClause n2 = (CatchClause) arg ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 1417) (CatchClause) arg ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 1419) !nodeEquals(n1.getExcept(), n2.getExcept()) ==> boolean
+  Line 1420) Boolean.FALSE ==> java.lang.Boolean
+  Line 1423) !nodeEquals(n1.getCatchBlock(), n2.getCatchBlock()) ==> boolean
+  Line 1424) Boolean.FALSE ==> java.lang.Boolean
+  Line 1427) Boolean.TRUE ==> java.lang.Boolean
+  Line 1432) LambdaExpr n2 = (LambdaExpr) arg ==> com.github.javaparser.ast.expr.LambdaExpr
+  Line 1432) (LambdaExpr) arg ==> com.github.javaparser.ast.expr.LambdaExpr
+  Line 1433) !nodesEquals(n1.getParameters(), n2.getParameters()) ==> boolean
+  Line 1434) Boolean.FALSE ==> java.lang.Boolean
+  Line 1436) n1.isParametersEnclosed() != n2.isParametersEnclosed() ==> boolean
+  Line 1437) Boolean.FALSE ==> java.lang.Boolean
+  Line 1439) !nodeEquals(n1.getBody(), n2.getBody()) ==> boolean
+  Line 1440) Boolean.FALSE ==> java.lang.Boolean
+  Line 1442) Boolean.TRUE ==> java.lang.Boolean
+  Line 1447) MethodReferenceExpr n2 = (MethodReferenceExpr) arg ==> com.github.javaparser.ast.expr.MethodReferenceExpr
+  Line 1447) (MethodReferenceExpr) arg ==> com.github.javaparser.ast.expr.MethodReferenceExpr
+  Line 1448) !nodeEquals(n1.getScope(), n2.getScope()) ==> boolean
+  Line 1449) Boolean.FALSE ==> java.lang.Boolean
+  Line 1451) !nodesEquals(n1.getTypeParameters(), n2.getTypeParameters()) ==> boolean
+  Line 1452) Boolean.FALSE ==> java.lang.Boolean
+  Line 1454) !objEquals(n1.getIdentifier(), n2.getIdentifier()) ==> boolean
+  Line 1455) Boolean.FALSE ==> java.lang.Boolean
+  Line 1457) Boolean.TRUE ==> java.lang.Boolean
+  Line 1462) TypeExpr n2 = (TypeExpr) arg ==> com.github.javaparser.ast.expr.TypeExpr
+  Line 1462) (TypeExpr) arg ==> com.github.javaparser.ast.expr.TypeExpr
+  Line 1463) !nodeEquals(n.getType(), n2.getType()) ==> boolean
+  Line 1464) Boolean.FALSE ==> java.lang.Boolean
+  Line 1466) Boolean.TRUE ==> java.lang.Boolean
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_GenericVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_GenericVisitor.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_GenericVisitor.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_GenericVisitorAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_GenericVisitorAdapter.txt
new file mode 100644
index 0000000..a0f97fb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_GenericVisitorAdapter.txt
@@ -0,0 +1,836 @@
+
+[ Class com.github.javaparser.ast.visitor.GenericVisitorAdapter ]
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.visitor.GenericVisitor
+  Line 80) n.getJavaDoc() != null ==> boolean
+  Line 82) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 82) n.getJavaDoc().accept(this, arg) ==> R
+  Line 83) result != null ==> boolean
+  Line 84) result ==> R
+  Line 88) n.getAnnotations() != null ==> boolean
+  Line 89) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 89) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 91) R result = a.accept(this, arg) ==> R
+  Line 91) a.accept(this, arg) ==> R
+  Line 92) result != null ==> boolean
+  Line 93) result ==> R
+  Line 98) n.getMembers() != null ==> boolean
+  Line 99) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 99) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 101) R result = member.accept(this, arg) ==> R
+  Line 101) member.accept(this, arg) ==> R
+  Line 102) result != null ==> boolean
+  Line 103) result ==> R
+  Line 108) null ==> null
+  Line 113) n.getJavaDoc() != null ==> boolean
+  Line 115) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 115) n.getJavaDoc().accept(this, arg) ==> R
+  Line 116) result != null ==> boolean
+  Line 117) result ==> R
+  Line 121) n.getAnnotations() != null ==> boolean
+  Line 122) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 122) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 124) R result = a.accept(this, arg) ==> R
+  Line 124) a.accept(this, arg) ==> R
+  Line 125) result != null ==> boolean
+  Line 126) result ==> R
+  Line 132) R result = n.getType().accept(this, arg) ==> R
+  Line 132) n.getType().accept(this, arg) ==> R
+  Line 133) result != null ==> boolean
+  Line 134) result ==> R
+  Line 137) n.getDefaultValue() != null ==> boolean
+  Line 139) R result = n.getDefaultValue().accept(this, arg) ==> R
+  Line 139) n.getDefaultValue().accept(this, arg) ==> R
+  Line 140) result != null ==> boolean
+  Line 141) result ==> R
+  Line 145) null ==> null
+  Line 151) R result = n.getName().accept(this, arg) ==> R
+  Line 151) n.getName().accept(this, arg) ==> R
+  Line 152) result != null ==> boolean
+  Line 153) result ==> R
+  Line 157) R result = n.getIndex().accept(this, arg) ==> R
+  Line 157) n.getIndex().accept(this, arg) ==> R
+  Line 158) result != null ==> boolean
+  Line 159) result ==> R
+  Line 162) null ==> null
+  Line 168) R result = n.getType().accept(this, arg) ==> R
+  Line 168) n.getType().accept(this, arg) ==> R
+  Line 169) result != null ==> boolean
+  Line 170) result ==> R
+  Line 173) n.getDimensions() != null ==> boolean
+  Line 174) final Expression dim ==> com.github.javaparser.ast.expr.Expression
+  Line 174) n.getDimensions() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 176) R result = dim.accept(this, arg) ==> R
+  Line 176) dim.accept(this, arg) ==> R
+  Line 177) result != null ==> boolean
+  Line 178) result ==> R
+  Line 184) R result = n.getInitializer().accept(this, arg) ==> R
+  Line 184) n.getInitializer().accept(this, arg) ==> R
+  Line 185) result != null ==> boolean
+  Line 186) result ==> R
+  Line 190) null ==> null
+  Line 195) n.getValues() != null ==> boolean
+  Line 196) final Expression expr ==> com.github.javaparser.ast.expr.Expression
+  Line 196) n.getValues() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 198) R result = expr.accept(this, arg) ==> R
+  Line 198) expr.accept(this, arg) ==> R
+  Line 199) result != null ==> boolean
+  Line 200) result ==> R
+  Line 205) null ==> null
+  Line 211) R result = n.getCheck().accept(this, arg) ==> R
+  Line 211) n.getCheck().accept(this, arg) ==> R
+  Line 212) result != null ==> boolean
+  Line 213) result ==> R
+  Line 216) n.getMessage() != null ==> boolean
+  Line 218) R result = n.getMessage().accept(this, arg) ==> R
+  Line 218) n.getMessage().accept(this, arg) ==> R
+  Line 219) result != null ==> boolean
+  Line 220) result ==> R
+  Line 224) null ==> null
+  Line 230) R result = n.getTarget().accept(this, arg) ==> R
+  Line 230) n.getTarget().accept(this, arg) ==> R
+  Line 231) result != null ==> boolean
+  Line 232) result ==> R
+  Line 236) R result = n.getValue().accept(this, arg) ==> R
+  Line 236) n.getValue().accept(this, arg) ==> R
+  Line 237) result != null ==> boolean
+  Line 238) result ==> R
+  Line 241) null ==> null
+  Line 247) R result = n.getLeft().accept(this, arg) ==> R
+  Line 247) n.getLeft().accept(this, arg) ==> R
+  Line 248) result != null ==> boolean
+  Line 249) result ==> R
+  Line 253) R result = n.getRight().accept(this, arg) ==> R
+  Line 253) n.getRight().accept(this, arg) ==> R
+  Line 254) result != null ==> boolean
+  Line 255) result ==> R
+  Line 258) null ==> null
+  Line 263) n.getStmts() != null ==> boolean
+  Line 264) final Statement s ==> com.github.javaparser.ast.stmt.Statement
+  Line 264) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 266) R result = s.accept(this, arg) ==> R
+  Line 266) s.accept(this, arg) ==> R
+  Line 267) result != null ==> boolean
+  Line 268) result ==> R
+  Line 273) null ==> null
+  Line 279) null ==> null
+  Line 284) null ==> null
+  Line 290) R result = n.getType().accept(this, arg) ==> R
+  Line 290) n.getType().accept(this, arg) ==> R
+  Line 291) result != null ==> boolean
+  Line 292) result ==> R
+  Line 296) R result = n.getExpr().accept(this, arg) ==> R
+  Line 296) n.getExpr().accept(this, arg) ==> R
+  Line 297) result != null ==> boolean
+  Line 298) result ==> R
+  Line 301) null ==> null
+  Line 307) R result = n.getExcept().accept(this, arg) ==> R
+  Line 307) n.getExcept().accept(this, arg) ==> R
+  Line 308) result != null ==> boolean
+  Line 309) result ==> R
+  Line 313) R result = n.getCatchBlock().accept(this, arg) ==> R
+  Line 313) n.getCatchBlock().accept(this, arg) ==> R
+  Line 314) result != null ==> boolean
+  Line 315) result ==> R
+  Line 318) null ==> null
+  Line 324) null ==> null
+  Line 330) R result = n.getType().accept(this, arg) ==> R
+  Line 330) n.getType().accept(this, arg) ==> R
+  Line 331) result != null ==> boolean
+  Line 332) result ==> R
+  Line 335) null ==> null
+  Line 340) n.getJavaDoc() != null ==> boolean
+  Line 342) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 342) n.getJavaDoc().accept(this, arg) ==> R
+  Line 343) result != null ==> boolean
+  Line 344) result ==> R
+  Line 348) n.getAnnotations() != null ==> boolean
+  Line 349) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 349) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 351) R result = a.accept(this, arg) ==> R
+  Line 351) a.accept(this, arg) ==> R
+  Line 352) result != null ==> boolean
+  Line 353) result ==> R
+  Line 358) n.getTypeParameters() != null ==> boolean
+  Line 359) final TypeParameter t ==> com.github.javaparser.ast.TypeParameter
+  Line 359) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 361) R result = t.accept(this, arg) ==> R
+  Line 361) t.accept(this, arg) ==> R
+  Line 362) result != null ==> boolean
+  Line 363) result ==> R
+  Line 368) n.getExtends() != null ==> boolean
+  Line 369) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 369) n.getExtends() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 371) R result = c.accept(this, arg) ==> R
+  Line 371) c.accept(this, arg) ==> R
+  Line 372) result != null ==> boolean
+  Line 373) result ==> R
+  Line 379) n.getImplements() != null ==> boolean
+  Line 380) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 380) n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 382) R result = c.accept(this, arg) ==> R
+  Line 382) c.accept(this, arg) ==> R
+  Line 383) result != null ==> boolean
+  Line 384) result ==> R
+  Line 389) n.getMembers() != null ==> boolean
+  Line 390) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 390) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 392) R result = member.accept(this, arg) ==> R
+  Line 392) member.accept(this, arg) ==> R
+  Line 393) result != null ==> boolean
+  Line 394) result ==> R
+  Line 399) null ==> null
+  Line 404) n.getScope() != null ==> boolean
+  Line 406) R result = n.getScope().accept(this, arg) ==> R
+  Line 406) n.getScope().accept(this, arg) ==> R
+  Line 407) result != null ==> boolean
+  Line 408) result ==> R
+  Line 412) n.getTypeArgs() != null ==> boolean
+  Line 413) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 413) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 415) R result = t.accept(this, arg) ==> R
+  Line 415) t.accept(this, arg) ==> R
+  Line 416) result != null ==> boolean
+  Line 417) result ==> R
+  Line 422) null ==> null
+  Line 427) n.getPackage() != null ==> boolean
+  Line 429) R result = n.getPackage().accept(this, arg) ==> R
+  Line 429) n.getPackage().accept(this, arg) ==> R
+  Line 430) result != null ==> boolean
+  Line 431) result ==> R
+  Line 435) n.getImports() != null ==> boolean
+  Line 436) final ImportDeclaration i ==> com.github.javaparser.ast.ImportDeclaration
+  Line 436) n.getImports() ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 438) R result = i.accept(this, arg) ==> R
+  Line 438) i.accept(this, arg) ==> R
+  Line 439) result != null ==> boolean
+  Line 440) result ==> R
+  Line 445) n.getTypes() != null ==> boolean
+  Line 446) final TypeDeclaration typeDeclaration ==> com.github.javaparser.ast.body.TypeDeclaration
+  Line 446) n.getTypes() ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 448) R result = typeDeclaration.accept(this, arg) ==> R
+  Line 448) typeDeclaration.accept(this, arg) ==> R
+  Line 449) result != null ==> boolean
+  Line 450) result ==> R
+  Line 455) null ==> null
+  Line 461) R result = n.getCondition().accept(this, arg) ==> R
+  Line 461) n.getCondition().accept(this, arg) ==> R
+  Line 462) result != null ==> boolean
+  Line 463) result ==> R
+  Line 467) R result = n.getThenExpr().accept(this, arg) ==> R
+  Line 467) n.getThenExpr().accept(this, arg) ==> R
+  Line 468) result != null ==> boolean
+  Line 469) result ==> R
+  Line 473) R result = n.getElseExpr().accept(this, arg) ==> R
+  Line 473) n.getElseExpr().accept(this, arg) ==> R
+  Line 474) result != null ==> boolean
+  Line 475) result ==> R
+  Line 478) null ==> null
+  Line 483) n.getJavaDoc() != null ==> boolean
+  Line 485) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 485) n.getJavaDoc().accept(this, arg) ==> R
+  Line 486) result != null ==> boolean
+  Line 487) result ==> R
+  Line 491) n.getAnnotations() != null ==> boolean
+  Line 492) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 492) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 494) R result = a.accept(this, arg) ==> R
+  Line 494) a.accept(this, arg) ==> R
+  Line 495) result != null ==> boolean
+  Line 496) result ==> R
+  Line 501) n.getTypeParameters() != null ==> boolean
+  Line 502) final TypeParameter t ==> com.github.javaparser.ast.TypeParameter
+  Line 502) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 504) R result = t.accept(this, arg) ==> R
+  Line 504) t.accept(this, arg) ==> R
+  Line 505) result != null ==> boolean
+  Line 506) result ==> R
+  Line 511) n.getParameters() != null ==> boolean
+  Line 512) final Parameter p ==> com.github.javaparser.ast.body.Parameter
+  Line 512) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 514) R result = p.accept(this, arg) ==> R
+  Line 514) p.accept(this, arg) ==> R
+  Line 515) result != null ==> boolean
+  Line 516) result ==> R
+  Line 521) n.getThrows() != null ==> boolean
+  Line 522) final NameExpr name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 522) n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 524) R result = name.accept(this, arg) ==> R
+  Line 524) name.accept(this, arg) ==> R
+  Line 525) result != null ==> boolean
+  Line 526) result ==> R
+  Line 532) R result = n.getBlock().accept(this, arg) ==> R
+  Line 532) n.getBlock().accept(this, arg) ==> R
+  Line 533) result != null ==> boolean
+  Line 534) result ==> R
+  Line 537) null ==> null
+  Line 542) null ==> null
+  Line 548) R result = n.getBody().accept(this, arg) ==> R
+  Line 548) n.getBody().accept(this, arg) ==> R
+  Line 549) result != null ==> boolean
+  Line 550) result ==> R
+  Line 554) R result = n.getCondition().accept(this, arg) ==> R
+  Line 554) n.getCondition().accept(this, arg) ==> R
+  Line 555) result != null ==> boolean
+  Line 556) result ==> R
+  Line 559) null ==> null
+  Line 564) null ==> null
+  Line 569) n.getJavaDoc() != null ==> boolean
+  Line 571) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 571) n.getJavaDoc().accept(this, arg) ==> R
+  Line 572) result != null ==> boolean
+  Line 573) result ==> R
+  Line 577) null ==> null
+  Line 582) null ==> null
+  Line 587) n.getJavaDoc() != null ==> boolean
+  Line 589) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 589) n.getJavaDoc().accept(this, arg) ==> R
+  Line 590) result != null ==> boolean
+  Line 591) result ==> R
+  Line 595) null ==> null
+  Line 601) R result = n.getInner().accept(this, arg) ==> R
+  Line 601) n.getInner().accept(this, arg) ==> R
+  Line 602) result != null ==> boolean
+  Line 603) result ==> R
+  Line 606) null ==> null
+  Line 611) n.getJavaDoc() != null ==> boolean
+  Line 613) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 613) n.getJavaDoc().accept(this, arg) ==> R
+  Line 614) result != null ==> boolean
+  Line 615) result ==> R
+  Line 619) n.getAnnotations() != null ==> boolean
+  Line 620) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 620) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 622) R result = a.accept(this, arg) ==> R
+  Line 622) a.accept(this, arg) ==> R
+  Line 623) result != null ==> boolean
+  Line 624) result ==> R
+  Line 629) n.getArgs() != null ==> boolean
+  Line 630) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 630) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 632) R result = e.accept(this, arg) ==> R
+  Line 632) e.accept(this, arg) ==> R
+  Line 633) result != null ==> boolean
+  Line 634) result ==> R
+  Line 639) n.getClassBody() != null ==> boolean
+  Line 640) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 640) n.getClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 642) R result = member.accept(this, arg) ==> R
+  Line 642) member.accept(this, arg) ==> R
+  Line 643) result != null ==> boolean
+  Line 644) result ==> R
+  Line 649) null ==> null
+  Line 654) n.getJavaDoc() != null ==> boolean
+  Line 656) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 656) n.getJavaDoc().accept(this, arg) ==> R
+  Line 657) result != null ==> boolean
+  Line 658) result ==> R
+  Line 662) n.getAnnotations() != null ==> boolean
+  Line 663) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 663) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 665) R result = a.accept(this, arg) ==> R
+  Line 665) a.accept(this, arg) ==> R
+  Line 666) result != null ==> boolean
+  Line 667) result ==> R
+  Line 672) n.getImplements() != null ==> boolean
+  Line 673) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 673) n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 675) R result = c.accept(this, arg) ==> R
+  Line 675) c.accept(this, arg) ==> R
+  Line 676) result != null ==> boolean
+  Line 677) result ==> R
+  Line 682) n.getEntries() != null ==> boolean
+  Line 683) final EnumConstantDeclaration e ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 683) n.getEntries() ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 685) R result = e.accept(this, arg) ==> R
+  Line 685) e.accept(this, arg) ==> R
+  Line 686) result != null ==> boolean
+  Line 687) result ==> R
+  Line 692) n.getMembers() != null ==> boolean
+  Line 693) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 693) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 695) R result = member.accept(this, arg) ==> R
+  Line 695) member.accept(this, arg) ==> R
+  Line 696) result != null ==> boolean
+  Line 697) result ==> R
+  Line 702) null ==> null
+  Line 707) !n.isThis() ==> boolean
+  Line 708) n.getExpr() != null ==> boolean
+  Line 710) R result = n.getExpr().accept(this, arg) ==> R
+  Line 710) n.getExpr().accept(this, arg) ==> R
+  Line 711) result != null ==> boolean
+  Line 712) result ==> R
+  Line 717) n.getTypeArgs() != null ==> boolean
+  Line 718) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 718) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 720) R result = t.accept(this, arg) ==> R
+  Line 720) t.accept(this, arg) ==> R
+  Line 721) result != null ==> boolean
+  Line 722) result ==> R
+  Line 727) n.getArgs() != null ==> boolean
+  Line 728) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 728) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 730) R result = e.accept(this, arg) ==> R
+  Line 730) e.accept(this, arg) ==> R
+  Line 731) result != null ==> boolean
+  Line 732) result ==> R
+  Line 737) null ==> null
+  Line 743) R result = n.getExpression().accept(this, arg) ==> R
+  Line 743) n.getExpression().accept(this, arg) ==> R
+  Line 744) result != null ==> boolean
+  Line 745) result ==> R
+  Line 748) null ==> null
+  Line 754) R result = n.getScope().accept(this, arg) ==> R
+  Line 754) n.getScope().accept(this, arg) ==> R
+  Line 755) result != null ==> boolean
+  Line 756) result ==> R
+  Line 759) null ==> null
+  Line 764) n.getJavaDoc() != null ==> boolean
+  Line 766) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 766) n.getJavaDoc().accept(this, arg) ==> R
+  Line 767) result != null ==> boolean
+  Line 768) result ==> R
+  Line 772) n.getAnnotations() != null ==> boolean
+  Line 773) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 773) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 775) R result = a.accept(this, arg) ==> R
+  Line 775) a.accept(this, arg) ==> R
+  Line 776) result != null ==> boolean
+  Line 777) result ==> R
+  Line 783) R result = n.getType().accept(this, arg) ==> R
+  Line 783) n.getType().accept(this, arg) ==> R
+  Line 784) result != null ==> boolean
+  Line 785) result ==> R
+  Line 788) final VariableDeclarator var ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 788) n.getVariables() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 790) R result = var.accept(this, arg) ==> R
+  Line 790) var.accept(this, arg) ==> R
+  Line 791) result != null ==> boolean
+  Line 792) result ==> R
+  Line 796) null ==> null
+  Line 802) R result = n.getVariable().accept(this, arg) ==> R
+  Line 802) n.getVariable().accept(this, arg) ==> R
+  Line 803) result != null ==> boolean
+  Line 804) result ==> R
+  Line 808) R result = n.getIterable().accept(this, arg) ==> R
+  Line 808) n.getIterable().accept(this, arg) ==> R
+  Line 809) result != null ==> boolean
+  Line 810) result ==> R
+  Line 814) R result = n.getBody().accept(this, arg) ==> R
+  Line 814) n.getBody().accept(this, arg) ==> R
+  Line 815) result != null ==> boolean
+  Line 816) result ==> R
+  Line 819) null ==> null
+  Line 824) n.getInit() != null ==> boolean
+  Line 825) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 825) n.getInit() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 827) R result = e.accept(this, arg) ==> R
+  Line 827) e.accept(this, arg) ==> R
+  Line 828) result != null ==> boolean
+  Line 829) result ==> R
+  Line 834) n.getCompare() != null ==> boolean
+  Line 836) R result = n.getCompare().accept(this, arg) ==> R
+  Line 836) n.getCompare().accept(this, arg) ==> R
+  Line 837) result != null ==> boolean
+  Line 838) result ==> R
+  Line 842) n.getUpdate() != null ==> boolean
+  Line 843) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 843) n.getUpdate() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 845) R result = e.accept(this, arg) ==> R
+  Line 845) e.accept(this, arg) ==> R
+  Line 846) result != null ==> boolean
+  Line 847) result ==> R
+  Line 853) R result = n.getBody().accept(this, arg) ==> R
+  Line 853) n.getBody().accept(this, arg) ==> R
+  Line 854) result != null ==> boolean
+  Line 855) result ==> R
+  Line 858) null ==> null
+  Line 864) R result = n.getCondition().accept(this, arg) ==> R
+  Line 864) n.getCondition().accept(this, arg) ==> R
+  Line 865) result != null ==> boolean
+  Line 866) result ==> R
+  Line 870) R result = n.getThenStmt().accept(this, arg) ==> R
+  Line 870) n.getThenStmt().accept(this, arg) ==> R
+  Line 871) result != null ==> boolean
+  Line 872) result ==> R
+  Line 875) n.getElseStmt() != null ==> boolean
+  Line 877) R result = n.getElseStmt().accept(this, arg) ==> R
+  Line 877) n.getElseStmt().accept(this, arg) ==> R
+  Line 878) result != null ==> boolean
+  Line 879) result ==> R
+  Line 883) null ==> null
+  Line 889) R result = n.getName().accept(this, arg) ==> R
+  Line 889) n.getName().accept(this, arg) ==> R
+  Line 890) result != null ==> boolean
+  Line 891) result ==> R
+  Line 894) null ==> null
+  Line 899) n.getJavaDoc() != null ==> boolean
+  Line 901) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 901) n.getJavaDoc().accept(this, arg) ==> R
+  Line 902) result != null ==> boolean
+  Line 903) result ==> R
+  Line 908) R result = n.getBlock().accept(this, arg) ==> R
+  Line 908) n.getBlock().accept(this, arg) ==> R
+  Line 909) result != null ==> boolean
+  Line 910) result ==> R
+  Line 913) null ==> null
+  Line 919) R result = n.getExpr().accept(this, arg) ==> R
+  Line 919) n.getExpr().accept(this, arg) ==> R
+  Line 920) result != null ==> boolean
+  Line 921) result ==> R
+  Line 925) R result = n.getType().accept(this, arg) ==> R
+  Line 925) n.getType().accept(this, arg) ==> R
+  Line 926) result != null ==> boolean
+  Line 927) result ==> R
+  Line 930) null ==> null
+  Line 935) null ==> null
+  Line 940) null ==> null
+  Line 945) null ==> null
+  Line 951) R result = n.getStmt().accept(this, arg) ==> R
+  Line 951) n.getStmt().accept(this, arg) ==> R
+  Line 952) result != null ==> boolean
+  Line 953) result ==> R
+  Line 956) null ==> null
+  Line 961) null ==> null
+  Line 966) null ==> null
+  Line 972) R result = n.getName().accept(this, arg) ==> R
+  Line 972) n.getName().accept(this, arg) ==> R
+  Line 973) result != null ==> boolean
+  Line 974) result ==> R
+  Line 977) null ==> null
+  Line 983) R result = n.getValue().accept(this, arg) ==> R
+  Line 983) n.getValue().accept(this, arg) ==> R
+  Line 984) result != null ==> boolean
+  Line 985) result ==> R
+  Line 988) null ==> null
+  Line 993) n.getScope() != null ==> boolean
+  Line 995) R result = n.getScope().accept(this, arg) ==> R
+  Line 995) n.getScope().accept(this, arg) ==> R
+  Line 996) result != null ==> boolean
+  Line 997) result ==> R
+  Line 1001) n.getTypeArgs() != null ==> boolean
+  Line 1002) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 1002) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 1004) R result = t.accept(this, arg) ==> R
+  Line 1004) t.accept(this, arg) ==> R
+  Line 1005) result != null ==> boolean
+  Line 1006) result ==> R
+  Line 1011) n.getArgs() != null ==> boolean
+  Line 1012) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 1012) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 1014) R result = e.accept(this, arg) ==> R
+  Line 1014) e.accept(this, arg) ==> R
+  Line 1015) result != null ==> boolean
+  Line 1016) result ==> R
+  Line 1021) null ==> null
+  Line 1026) n.getJavaDoc() != null ==> boolean
+  Line 1028) R result = n.getJavaDoc().accept(this, arg) ==> R
+  Line 1028) n.getJavaDoc().accept(this, arg) ==> R
+  Line 1029) result != null ==> boolean
+  Line 1030) result ==> R
+  Line 1034) n.getAnnotations() != null ==> boolean
+  Line 1035) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 1035) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 1037) R result = a.accept(this, arg) ==> R
+  Line 1037) a.accept(this, arg) ==> R
+  Line 1038) result != null ==> boolean
+  Line 1039) result ==> R
+  Line 1044) n.getTypeParameters() != null ==> boolean
+  Line 1045) final TypeParameter t ==> com.github.javaparser.ast.TypeParameter
+  Line 1045) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 1047) R result = t.accept(this, arg) ==> R
+  Line 1047) t.accept(this, arg) ==> R
+  Line 1048) result != null ==> boolean
+  Line 1049) result ==> R
+  Line 1055) R result = n.getType().accept(this, arg) ==> R
+  Line 1055) n.getType().accept(this, arg) ==> R
+  Line 1056) result != null ==> boolean
+  Line 1057) result ==> R
+  Line 1060) n.getParameters() != null ==> boolean
+  Line 1061) final Parameter p ==> com.github.javaparser.ast.body.Parameter
+  Line 1061) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 1063) R result = p.accept(this, arg) ==> R
+  Line 1063) p.accept(this, arg) ==> R
+  Line 1064) result != null ==> boolean
+  Line 1065) result ==> R
+  Line 1070) n.getThrows() != null ==> boolean
+  Line 1071) final NameExpr name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 1071) n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 1073) R result = name.accept(this, arg) ==> R
+  Line 1073) name.accept(this, arg) ==> R
+  Line 1074) result != null ==> boolean
+  Line 1075) result ==> R
+  Line 1080) n.getBody() != null ==> boolean
+  Line 1082) R result = n.getBody().accept(this, arg) ==> R
+  Line 1082) n.getBody().accept(this, arg) ==> R
+  Line 1083) result != null ==> boolean
+  Line 1084) result ==> R
+  Line 1088) null ==> null
+  Line 1093) null ==> null
+  Line 1099) R result = n.getName().accept(this, arg) ==> R
+  Line 1099) n.getName().accept(this, arg) ==> R
+  Line 1100) result != null ==> boolean
+  Line 1101) result ==> R
+  Line 1104) n.getPairs() != null ==> boolean
+  Line 1105) final MemberValuePair m ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 1105) n.getPairs() ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 1107) R result = m.accept(this, arg) ==> R
+  Line 1107) m.accept(this, arg) ==> R
+  Line 1108) result != null ==> boolean
+  Line 1109) result ==> R
+  Line 1114) null ==> null
+  Line 1119) null ==> null
+  Line 1124) n.getScope() != null ==> boolean
+  Line 1126) R result = n.getScope().accept(this, arg) ==> R
+  Line 1126) n.getScope().accept(this, arg) ==> R
+  Line 1127) result != null ==> boolean
+  Line 1128) result ==> R
+  Line 1132) n.getTypeArgs() != null ==> boolean
+  Line 1133) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 1133) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 1135) R result = t.accept(this, arg) ==> R
+  Line 1135) t.accept(this, arg) ==> R
+  Line 1136) result != null ==> boolean
+  Line 1137) result ==> R
+  Line 1143) R result = n.getType().accept(this, arg) ==> R
+  Line 1143) n.getType().accept(this, arg) ==> R
+  Line 1144) result != null ==> boolean
+  Line 1145) result ==> R
+  Line 1148) n.getArgs() != null ==> boolean
+  Line 1149) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 1149) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 1151) R result = e.accept(this, arg) ==> R
+  Line 1151) e.accept(this, arg) ==> R
+  Line 1152) result != null ==> boolean
+  Line 1153) result ==> R
+  Line 1158) n.getAnonymousClassBody() != null ==> boolean
+  Line 1159) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 1159) n.getAnonymousClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 1161) R result = member.accept(this, arg) ==> R
+  Line 1161) member.accept(this, arg) ==> R
+  Line 1162) result != null ==> boolean
+  Line 1163) result ==> R
+  Line 1168) null ==> null
+  Line 1173) n.getAnnotations() != null ==> boolean
+  Line 1174) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 1174) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 1176) R result = a.accept(this, arg) ==> R
+  Line 1176) a.accept(this, arg) ==> R
+  Line 1177) result != null ==> boolean
+  Line 1178) result ==> R
+  Line 1184) R result = n.getName().accept(this, arg) ==> R
+  Line 1184) n.getName().accept(this, arg) ==> R
+  Line 1185) result != null ==> boolean
+  Line 1186) result ==> R
+  Line 1189) null ==> null
+  Line 1194) n.getAnnotations() != null ==> boolean
+  Line 1195) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 1195) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 1197) R result = a.accept(this, arg) ==> R
+  Line 1197) a.accept(this, arg) ==> R
+  Line 1198) result != null ==> boolean
+  Line 1199) result ==> R
+  Line 1205) R result = n.getType().accept(this, arg) ==> R
+  Line 1205) n.getType().accept(this, arg) ==> R
+  Line 1206) result != null ==> boolean
+  Line 1207) result ==> R
+  Line 1211) R result = n.getId().accept(this, arg) ==> R
+  Line 1211) n.getId().accept(this, arg) ==> R
+  Line 1212) result != null ==> boolean
+  Line 1213) result ==> R
+  Line 1216) null ==> null
+  Line 1221) n.getAnnotations() != null ==> boolean
+  Line 1222) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 1222) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 1224) R result = a.accept(this, arg) ==> R
+  Line 1224) a.accept(this, arg) ==> R
+  Line 1225) result != null ==> boolean
+  Line 1226) result ==> R
+  Line 1232) final Type type ==> com.github.javaparser.ast.type.Type
+  Line 1232) n.getTypes() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 1233) R result = type.accept(this, arg) ==> R
+  Line 1233) type.accept(this, arg) ==> R
+  Line 1234) result != null ==> boolean
+  Line 1235) result ==> R
+  Line 1240) R result = n.getId().accept(this, arg) ==> R
+  Line 1240) n.getId().accept(this, arg) ==> R
+  Line 1241) result != null ==> boolean
+  Line 1242) result ==> R
+  Line 1245) null ==> null
+  Line 1250) null ==> null
+  Line 1256) R result = n.getQualifier().accept(this, arg) ==> R
+  Line 1256) n.getQualifier().accept(this, arg) ==> R
+  Line 1257) result != null ==> boolean
+  Line 1258) result ==> R
+  Line 1261) null ==> null
+  Line 1267) R result = n.getType().accept(this, arg) ==> R
+  Line 1267) n.getType().accept(this, arg) ==> R
+  Line 1268) result != null ==> boolean
+  Line 1269) result ==> R
+  Line 1272) null ==> null
+  Line 1277) n.getExpr() != null ==> boolean
+  Line 1279) R result = n.getExpr().accept(this, arg) ==> R
+  Line 1279) n.getExpr().accept(this, arg) ==> R
+  Line 1280) result != null ==> boolean
+  Line 1281) result ==> R
+  Line 1285) null ==> null
+  Line 1291) R result = n.getName().accept(this, arg) ==> R
+  Line 1291) n.getName().accept(this, arg) ==> R
+  Line 1292) result != null ==> boolean
+  Line 1293) result ==> R
+  Line 1297) R result = n.getMemberValue().accept(this, arg) ==> R
+  Line 1297) n.getMemberValue().accept(this, arg) ==> R
+  Line 1298) result != null ==> boolean
+  Line 1299) result ==> R
+  Line 1302) null ==> null
+  Line 1307) null ==> null
+  Line 1312) n.getClassExpr() != null ==> boolean
+  Line 1314) R result = n.getClassExpr().accept(this, arg) ==> R
+  Line 1314) n.getClassExpr().accept(this, arg) ==> R
+  Line 1315) result != null ==> boolean
+  Line 1316) result ==> R
+  Line 1320) null ==> null
+  Line 1325) n.getLabel() != null ==> boolean
+  Line 1327) R result = n.getLabel().accept(this, arg) ==> R
+  Line 1327) n.getLabel().accept(this, arg) ==> R
+  Line 1328) result != null ==> boolean
+  Line 1329) result ==> R
+  Line 1333) n.getStmts() != null ==> boolean
+  Line 1334) final Statement s ==> com.github.javaparser.ast.stmt.Statement
+  Line 1334) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 1336) R result = s.accept(this, arg) ==> R
+  Line 1336) s.accept(this, arg) ==> R
+  Line 1337) result != null ==> boolean
+  Line 1338) result ==> R
+  Line 1343) null ==> null
+  Line 1349) R result = n.getSelector().accept(this, arg) ==> R
+  Line 1349) n.getSelector().accept(this, arg) ==> R
+  Line 1350) result != null ==> boolean
+  Line 1351) result ==> R
+  Line 1354) n.getEntries() != null ==> boolean
+  Line 1355) final SwitchEntryStmt e ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 1355) n.getEntries() ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 1357) R result = e.accept(this, arg) ==> R
+  Line 1357) e.accept(this, arg) ==> R
+  Line 1358) result != null ==> boolean
+  Line 1359) result ==> R
+  Line 1364) null ==> null
+  Line 1371) n.getExpr() != null ==> boolean
+  Line 1372) R result = n.getExpr().accept(this, arg) ==> R
+  Line 1372) n.getExpr().accept(this, arg) ==> R
+  Line 1373) result != null ==> boolean
+  Line 1374) result ==> R
+  Line 1379) R result = n.getBlock().accept(this, arg) ==> R
+  Line 1379) n.getBlock().accept(this, arg) ==> R
+  Line 1380) result != null ==> boolean
+  Line 1381) result ==> R
+  Line 1384) null ==> null
+  Line 1389) n.getClassExpr() != null ==> boolean
+  Line 1391) R result = n.getClassExpr().accept(this, arg) ==> R
+  Line 1391) n.getClassExpr().accept(this, arg) ==> R
+  Line 1392) result != null ==> boolean
+  Line 1393) result ==> R
+  Line 1397) null ==> null
+  Line 1403) R result = n.getExpr().accept(this, arg) ==> R
+  Line 1403) n.getExpr().accept(this, arg) ==> R
+  Line 1404) result != null ==> boolean
+  Line 1405) result ==> R
+  Line 1408) null ==> null
+  Line 1413) n.getResources() != null ==> boolean
+  Line 1414) final VariableDeclarationExpr v ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 1414) n.getResources() ==> java.util.List<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 1416) R result = v.accept(this, arg) ==> R
+  Line 1416) v.accept(this, arg) ==> R
+  Line 1417) result != null ==> boolean
+  Line 1418) result ==> R
+  Line 1424) R result = n.getTryBlock().accept(this, arg) ==> R
+  Line 1424) n.getTryBlock().accept(this, arg) ==> R
+  Line 1425) result != null ==> boolean
+  Line 1426) result ==> R
+  Line 1429) n.getCatchs() != null ==> boolean
+  Line 1430) final CatchClause c ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 1430) n.getCatchs() ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 1432) R result = c.accept(this, arg) ==> R
+  Line 1432) c.accept(this, arg) ==> R
+  Line 1433) result != null ==> boolean
+  Line 1434) result ==> R
+  Line 1439) n.getFinallyBlock() != null ==> boolean
+  Line 1441) R result = n.getFinallyBlock().accept(this, arg) ==> R
+  Line 1441) n.getFinallyBlock().accept(this, arg) ==> R
+  Line 1442) result != null ==> boolean
+  Line 1443) result ==> R
+  Line 1447) null ==> null
+  Line 1453) R result = n.getTypeDeclaration().accept(this, arg) ==> R
+  Line 1453) n.getTypeDeclaration().accept(this, arg) ==> R
+  Line 1454) result != null ==> boolean
+  Line 1455) result ==> R
+  Line 1458) null ==> null
+  Line 1463) n.getTypeBound() != null ==> boolean
+  Line 1464) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 1464) n.getTypeBound() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 1466) R result = c.accept(this, arg) ==> R
+  Line 1466) c.accept(this, arg) ==> R
+  Line 1467) result != null ==> boolean
+  Line 1468) result ==> R
+  Line 1473) null ==> null
+  Line 1479) R result = n.getExpr().accept(this, arg) ==> R
+  Line 1479) n.getExpr().accept(this, arg) ==> R
+  Line 1480) result != null ==> boolean
+  Line 1481) result ==> R
+  Line 1484) null ==> null
+  Line 1489) null ==> null
+  Line 1494) n.getAnnotations() != null ==> boolean
+  Line 1495) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 1495) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 1497) R result = a.accept(this, arg) ==> R
+  Line 1497) a.accept(this, arg) ==> R
+  Line 1498) result != null ==> boolean
+  Line 1499) result ==> R
+  Line 1505) R result = n.getType().accept(this, arg) ==> R
+  Line 1505) n.getType().accept(this, arg) ==> R
+  Line 1506) result != null ==> boolean
+  Line 1507) result ==> R
+  Line 1510) final VariableDeclarator v ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 1510) n.getVars() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 1512) R result = v.accept(this, arg) ==> R
+  Line 1512) v.accept(this, arg) ==> R
+  Line 1513) result != null ==> boolean
+  Line 1514) result ==> R
+  Line 1518) null ==> null
+  Line 1524) R result = n.getId().accept(this, arg) ==> R
+  Line 1524) n.getId().accept(this, arg) ==> R
+  Line 1525) result != null ==> boolean
+  Line 1526) result ==> R
+  Line 1529) n.getInit() != null ==> boolean
+  Line 1531) R result = n.getInit().accept(this, arg) ==> R
+  Line 1531) n.getInit().accept(this, arg) ==> R
+  Line 1532) result != null ==> boolean
+  Line 1533) result ==> R
+  Line 1537) null ==> null
+  Line 1542) null ==> null
+  Line 1547) null ==> null
+  Line 1553) R result = n.getCondition().accept(this, arg) ==> R
+  Line 1553) n.getCondition().accept(this, arg) ==> R
+  Line 1554) result != null ==> boolean
+  Line 1555) result ==> R
+  Line 1559) R result = n.getBody().accept(this, arg) ==> R
+  Line 1559) n.getBody().accept(this, arg) ==> R
+  Line 1560) result != null ==> boolean
+  Line 1561) result ==> R
+  Line 1564) null ==> null
+  Line 1569) n.getExtends() != null ==> boolean
+  Line 1571) R result = n.getExtends().accept(this, arg) ==> R
+  Line 1571) n.getExtends().accept(this, arg) ==> R
+  Line 1572) result != null ==> boolean
+  Line 1573) result ==> R
+  Line 1577) n.getSuper() != null ==> boolean
+  Line 1579) R result = n.getSuper().accept(this, arg) ==> R
+  Line 1579) n.getSuper().accept(this, arg) ==> R
+  Line 1580) result != null ==> boolean
+  Line 1581) result ==> R
+  Line 1585) null ==> null
+  Line 1590) null ==> null
+  Line 1595) null ==> null
+  Line 1600) null ==> null
+  Line 1605) null ==> null
+  Line 1610) null ==> null
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_ModifierVisitorAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_ModifierVisitorAdapter.txt
new file mode 100644
index 0000000..a02c699
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_ModifierVisitorAdapter.txt
@@ -0,0 +1,662 @@
+
+[ Class com.github.javaparser.ast.visitor.ModifierVisitorAdapter ]
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.visitor.GenericVisitor
+  Line 124) int i = list.size() - 1 ==> int
+  Line 124) list.size() - 1 ==> int
+  Line 124) i >= 0 ==> boolean
+  Line 124) i-- ==> int
+  Line 125) list.get(i) == null ==> boolean
+  Line 126) list.remove(i) ==> ?
+  Line 132) n.getJavaDoc() != null ==> boolean
+  Line 133) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 135) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 135) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 136) annotations != null ==> boolean
+  Line 137) int i = 0 ==> int
+  Line 137) 0 ==> int
+  Line 137) i < annotations.size() ==> boolean
+  Line 137) i++ ==> int
+  Line 138) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 140) removeNulls(annotations) ==> void
+  Line 142) final List<BodyDeclaration> members = n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 142) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 143) members != null ==> boolean
+  Line 144) int i = 0 ==> int
+  Line 144) 0 ==> int
+  Line 144) i < members.size() ==> boolean
+  Line 144) i++ ==> int
+  Line 145) members.set(i, (BodyDeclaration) members.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 147) removeNulls(members) ==> void
+  Line 149) n ==> com.github.javaparser.ast.body.AnnotationDeclaration
+  Line 153) n.getJavaDoc() != null ==> boolean
+  Line 154) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 156) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 156) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 157) annotations != null ==> boolean
+  Line 158) int i = 0 ==> int
+  Line 158) 0 ==> int
+  Line 158) i < annotations.size() ==> boolean
+  Line 158) i++ ==> int
+  Line 159) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 161) removeNulls(annotations) ==> void
+  Line 163) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 164) n.getDefaultValue() != null ==> boolean
+  Line 165) n.setDefaultValue((Expression) n.getDefaultValue().accept(this, arg)) ==> void
+  Line 167) n ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration
+  Line 171) n.setName((Expression) n.getName().accept(this, arg)) ==> void
+  Line 172) n.setIndex((Expression) n.getIndex().accept(this, arg)) ==> void
+  Line 173) n ==> com.github.javaparser.ast.expr.ArrayAccessExpr
+  Line 177) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 178) n.getDimensions() != null ==> boolean
+  Line 179) final List<Expression> dimensions = n.getDimensions() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 179) n.getDimensions() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 180) dimensions != null ==> boolean
+  Line 181) int i = 0 ==> int
+  Line 181) 0 ==> int
+  Line 181) i < dimensions.size() ==> boolean
+  Line 181) i++ ==> int
+  Line 182) dimensions.set(i, (Expression) dimensions.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 184) removeNulls(dimensions) ==> void
+  Line 187) n.setInitializer((ArrayInitializerExpr) n.getInitializer().accept(this, arg)) ==> void
+  Line 189) n ==> com.github.javaparser.ast.expr.ArrayCreationExpr
+  Line 193) n.getValues() != null ==> boolean
+  Line 194) final List<Expression> values = n.getValues() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 194) n.getValues() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 195) values != null ==> boolean
+  Line 196) int i = 0 ==> int
+  Line 196) 0 ==> int
+  Line 196) i < values.size() ==> boolean
+  Line 196) i++ ==> int
+  Line 197) values.set(i, (Expression) values.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 199) removeNulls(values) ==> void
+  Line 202) n ==> com.github.javaparser.ast.expr.ArrayInitializerExpr
+  Line 206) n.setCheck((Expression) n.getCheck().accept(this, arg)) ==> void
+  Line 207) n.getMessage() != null ==> boolean
+  Line 208) n.setMessage((Expression) n.getMessage().accept(this, arg)) ==> void
+  Line 210) n ==> com.github.javaparser.ast.stmt.AssertStmt
+  Line 214) n.setTarget((Expression) n.getTarget().accept(this, arg)) ==> void
+  Line 215) n.setValue((Expression) n.getValue().accept(this, arg)) ==> void
+  Line 216) n ==> com.github.javaparser.ast.expr.AssignExpr
+  Line 220) n.setLeft((Expression) n.getLeft().accept(this, arg)) ==> void
+  Line 221) n.setRight((Expression) n.getRight().accept(this, arg)) ==> void
+  Line 222) n ==> com.github.javaparser.ast.expr.BinaryExpr
+  Line 226) final List<Statement> stmts = n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 226) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 227) stmts != null ==> boolean
+  Line 228) int i = 0 ==> int
+  Line 228) 0 ==> int
+  Line 228) i < stmts.size() ==> boolean
+  Line 228) i++ ==> int
+  Line 229) stmts.set(i, (Statement) stmts.get(i).accept(this, arg)) ==> com.github.javaparser.ast.stmt.Statement
+  Line 231) removeNulls(stmts) ==> void
+  Line 233) n ==> com.github.javaparser.ast.stmt.BlockStmt
+  Line 237) n ==> com.github.javaparser.ast.expr.BooleanLiteralExpr
+  Line 241) n ==> com.github.javaparser.ast.stmt.BreakStmt
+  Line 245) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 246) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> void
+  Line 247) n ==> com.github.javaparser.ast.expr.CastExpr
+  Line 251) n.setExcept((MultiTypeParameter) n.getExcept().accept(this, arg)) ==> void
+  Line 252) n.setCatchBlock((BlockStmt) n.getCatchBlock().accept(this, arg)) ==> void
+  Line 253) n ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 258) n ==> com.github.javaparser.ast.expr.CharLiteralExpr
+  Line 262) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 263) n ==> com.github.javaparser.ast.expr.ClassExpr
+  Line 267) n.getJavaDoc() != null ==> boolean
+  Line 268) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 270) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 270) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 271) annotations != null ==> boolean
+  Line 272) int i = 0 ==> int
+  Line 272) 0 ==> int
+  Line 272) i < annotations.size() ==> boolean
+  Line 272) i++ ==> int
+  Line 273) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 275) removeNulls(annotations) ==> void
+  Line 277) final List<TypeParameter> typeParameters = n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 277) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 278) typeParameters != null ==> boolean
+  Line 279) int i = 0 ==> int
+  Line 279) 0 ==> int
+  Line 279) i < typeParameters.size() ==> boolean
+  Line 279) i++ ==> int
+  Line 280) typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg)) ==> com.github.javaparser.ast.TypeParameter
+  Line 282) removeNulls(typeParameters) ==> void
+  Line 284) final List<ClassOrInterfaceType> extendz = n.getExtends() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 284) n.getExtends() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 285) extendz != null ==> boolean
+  Line 286) int i = 0 ==> int
+  Line 286) 0 ==> int
+  Line 286) i < extendz.size() ==> boolean
+  Line 286) i++ ==> int
+  Line 287) extendz.set(i, (ClassOrInterfaceType) extendz.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 289) removeNulls(extendz) ==> void
+  Line 291) final List<ClassOrInterfaceType> implementz = n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 291) n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 292) implementz != null ==> boolean
+  Line 293) int i = 0 ==> int
+  Line 293) 0 ==> int
+  Line 293) i < implementz.size() ==> boolean
+  Line 293) i++ ==> int
+  Line 294) implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 296) removeNulls(implementz) ==> void
+  Line 298) final List<BodyDeclaration> members = n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 298) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 299) members != null ==> boolean
+  Line 300) int i = 0 ==> int
+  Line 300) 0 ==> int
+  Line 300) i < members.size() ==> boolean
+  Line 300) i++ ==> int
+  Line 301) members.set(i, (BodyDeclaration) members.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 303) removeNulls(members) ==> void
+  Line 305) n ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
+  Line 309) n.getScope() != null ==> boolean
+  Line 310) n.setScope((ClassOrInterfaceType) n.getScope().accept(this, arg)) ==> void
+  Line 312) final List<Type> typeArgs = n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 312) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 313) typeArgs != null ==> boolean
+  Line 314) int i = 0 ==> int
+  Line 314) 0 ==> int
+  Line 314) i < typeArgs.size() ==> boolean
+  Line 314) i++ ==> int
+  Line 315) typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.Type
+  Line 317) removeNulls(typeArgs) ==> void
+  Line 319) n ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 323) n.getPackage() != null ==> boolean
+  Line 324) n.setPackage((PackageDeclaration) n.getPackage().accept(this, arg)) ==> void
+  Line 326) final List<ImportDeclaration> imports = n.getImports() ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 326) n.getImports() ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 327) imports != null ==> boolean
+  Line 328) int i = 0 ==> int
+  Line 328) 0 ==> int
+  Line 328) i < imports.size() ==> boolean
+  Line 328) i++ ==> int
+  Line 329) imports.set(i, (ImportDeclaration) imports.get(i).accept(this, arg)) ==> com.github.javaparser.ast.ImportDeclaration
+  Line 331) removeNulls(imports) ==> void
+  Line 333) final List<TypeDeclaration> types = n.getTypes() ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 333) n.getTypes() ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 334) types != null ==> boolean
+  Line 335) int i = 0 ==> int
+  Line 335) 0 ==> int
+  Line 335) i < types.size() ==> boolean
+  Line 335) i++ ==> int
+  Line 336) types.set(i, (TypeDeclaration) types.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.TypeDeclaration
+  Line 338) removeNulls(types) ==> void
+  Line 340) n ==> com.github.javaparser.ast.CompilationUnit
+  Line 344) n.setCondition((Expression) n.getCondition().accept(this, arg)) ==> void
+  Line 345) n.setThenExpr((Expression) n.getThenExpr().accept(this, arg)) ==> void
+  Line 346) n.setElseExpr((Expression) n.getElseExpr().accept(this, arg)) ==> void
+  Line 347) n ==> com.github.javaparser.ast.expr.ConditionalExpr
+  Line 351) n.getJavaDoc() != null ==> boolean
+  Line 352) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 354) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 354) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 355) annotations != null ==> boolean
+  Line 356) int i = 0 ==> int
+  Line 356) 0 ==> int
+  Line 356) i < annotations.size() ==> boolean
+  Line 356) i++ ==> int
+  Line 357) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 359) removeNulls(annotations) ==> void
+  Line 361) final List<TypeParameter> typeParameters = n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 361) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 362) typeParameters != null ==> boolean
+  Line 363) int i = 0 ==> int
+  Line 363) 0 ==> int
+  Line 363) i < typeParameters.size() ==> boolean
+  Line 363) i++ ==> int
+  Line 364) typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg)) ==> com.github.javaparser.ast.TypeParameter
+  Line 366) removeNulls(typeParameters) ==> void
+  Line 368) final List<Parameter> parameters = n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 368) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 369) parameters != null ==> boolean
+  Line 370) int i = 0 ==> int
+  Line 370) 0 ==> int
+  Line 370) i < parameters.size() ==> boolean
+  Line 370) i++ ==> int
+  Line 371) parameters.set(i, (Parameter) parameters.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.Parameter
+  Line 373) removeNulls(parameters) ==> void
+  Line 375) final List<NameExpr> throwz = n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 375) n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 376) throwz != null ==> boolean
+  Line 377) int i = 0 ==> int
+  Line 377) 0 ==> int
+  Line 377) i < throwz.size() ==> boolean
+  Line 377) i++ ==> int
+  Line 378) throwz.set(i, (NameExpr) throwz.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 380) removeNulls(throwz) ==> void
+  Line 382) n.setBlock((BlockStmt) n.getBlock().accept(this, arg)) ==> void
+  Line 383) n ==> com.github.javaparser.ast.body.ConstructorDeclaration
+  Line 387) n ==> com.github.javaparser.ast.stmt.ContinueStmt
+  Line 391) n.setBody((Statement) n.getBody().accept(this, arg)) ==> void
+  Line 392) n.setCondition((Expression) n.getCondition().accept(this, arg)) ==> void
+  Line 393) n ==> com.github.javaparser.ast.stmt.DoStmt
+  Line 397) n ==> com.github.javaparser.ast.expr.DoubleLiteralExpr
+  Line 401) n.getJavaDoc() != null ==> boolean
+  Line 402) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 404) n ==> com.github.javaparser.ast.body.EmptyMemberDeclaration
+  Line 408) n ==> com.github.javaparser.ast.stmt.EmptyStmt
+  Line 412) n.getJavaDoc() != null ==> boolean
+  Line 413) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 415) n ==> com.github.javaparser.ast.body.EmptyTypeDeclaration
+  Line 419) n.setInner((Expression) n.getInner().accept(this, arg)) ==> void
+  Line 420) n ==> com.github.javaparser.ast.expr.EnclosedExpr
+  Line 424) n.getJavaDoc() != null ==> boolean
+  Line 425) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 427) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 427) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 428) annotations != null ==> boolean
+  Line 429) int i = 0 ==> int
+  Line 429) 0 ==> int
+  Line 429) i < annotations.size() ==> boolean
+  Line 429) i++ ==> int
+  Line 430) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 432) removeNulls(annotations) ==> void
+  Line 434) final List<Expression> args = n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 434) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 435) args != null ==> boolean
+  Line 436) int i = 0 ==> int
+  Line 436) 0 ==> int
+  Line 436) i < args.size() ==> boolean
+  Line 436) i++ ==> int
+  Line 437) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 439) removeNulls(args) ==> void
+  Line 441) final List<BodyDeclaration> classBody = n.getClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 441) n.getClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 442) classBody != null ==> boolean
+  Line 443) int i = 0 ==> int
+  Line 443) 0 ==> int
+  Line 443) i < classBody.size() ==> boolean
+  Line 443) i++ ==> int
+  Line 444) classBody.set(i, (BodyDeclaration) classBody.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 446) removeNulls(classBody) ==> void
+  Line 448) n ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 452) n.getJavaDoc() != null ==> boolean
+  Line 453) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 455) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 455) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 456) annotations != null ==> boolean
+  Line 457) int i = 0 ==> int
+  Line 457) 0 ==> int
+  Line 457) i < annotations.size() ==> boolean
+  Line 457) i++ ==> int
+  Line 458) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 460) removeNulls(annotations) ==> void
+  Line 462) final List<ClassOrInterfaceType> implementz = n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 462) n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 463) implementz != null ==> boolean
+  Line 464) int i = 0 ==> int
+  Line 464) 0 ==> int
+  Line 464) i < implementz.size() ==> boolean
+  Line 464) i++ ==> int
+  Line 465) implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 467) removeNulls(implementz) ==> void
+  Line 469) final List<EnumConstantDeclaration> entries = n.getEntries() ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 469) n.getEntries() ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 470) entries != null ==> boolean
+  Line 471) int i = 0 ==> int
+  Line 471) 0 ==> int
+  Line 471) i < entries.size() ==> boolean
+  Line 471) i++ ==> int
+  Line 472) entries.set(i, (EnumConstantDeclaration) entries.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 474) removeNulls(entries) ==> void
+  Line 476) final List<BodyDeclaration> members = n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 476) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 477) members != null ==> boolean
+  Line 478) int i = 0 ==> int
+  Line 478) 0 ==> int
+  Line 478) i < members.size() ==> boolean
+  Line 478) i++ ==> int
+  Line 479) members.set(i, (BodyDeclaration) members.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 481) removeNulls(members) ==> void
+  Line 483) n ==> com.github.javaparser.ast.body.EnumDeclaration
+  Line 487) !n.isThis() ==> boolean
+  Line 488) n.getExpr() != null ==> boolean
+  Line 489) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> void
+  Line 492) final List<Type> typeArgs = n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 492) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 493) typeArgs != null ==> boolean
+  Line 494) int i = 0 ==> int
+  Line 494) 0 ==> int
+  Line 494) i < typeArgs.size() ==> boolean
+  Line 494) i++ ==> int
+  Line 495) typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.Type
+  Line 497) removeNulls(typeArgs) ==> void
+  Line 499) final List<Expression> args = n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 499) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 500) args != null ==> boolean
+  Line 501) int i = 0 ==> int
+  Line 501) 0 ==> int
+  Line 501) i < args.size() ==> boolean
+  Line 501) i++ ==> int
+  Line 502) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 504) removeNulls(args) ==> void
+  Line 506) n ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt
+  Line 510) n.setExpression((Expression) n.getExpression().accept(this, arg)) ==> void
+  Line 511) n ==> com.github.javaparser.ast.stmt.ExpressionStmt
+  Line 515) n.setScope((Expression) n.getScope().accept(this, arg)) ==> void
+  Line 516) n ==> com.github.javaparser.ast.expr.FieldAccessExpr
+  Line 520) n.getJavaDoc() != null ==> boolean
+  Line 521) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 523) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 523) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 524) annotations != null ==> boolean
+  Line 525) int i = 0 ==> int
+  Line 525) 0 ==> int
+  Line 525) i < annotations.size() ==> boolean
+  Line 525) i++ ==> int
+  Line 526) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 528) removeNulls(annotations) ==> void
+  Line 530) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 531) final List<VariableDeclarator> variables = n.getVariables() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 531) n.getVariables() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 532) int i = 0 ==> int
+  Line 532) 0 ==> int
+  Line 532) i < variables.size() ==> boolean
+  Line 532) i++ ==> int
+  Line 533) variables.set(i, (VariableDeclarator) variables.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 535) removeNulls(variables) ==> void
+  Line 536) n ==> com.github.javaparser.ast.body.FieldDeclaration
+  Line 540) n.setVariable((VariableDeclarationExpr) n.getVariable().accept(this, arg)) ==> void
+  Line 541) n.setIterable((Expression) n.getIterable().accept(this, arg)) ==> void
+  Line 542) n.setBody((Statement) n.getBody().accept(this, arg)) ==> void
+  Line 543) n ==> com.github.javaparser.ast.stmt.ForeachStmt
+  Line 547) final List<Expression> init = n.getInit() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 547) n.getInit() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 548) init != null ==> boolean
+  Line 549) int i = 0 ==> int
+  Line 549) 0 ==> int
+  Line 549) i < init.size() ==> boolean
+  Line 549) i++ ==> int
+  Line 550) init.set(i, (Expression) init.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 552) removeNulls(init) ==> void
+  Line 554) n.getCompare() != null ==> boolean
+  Line 555) n.setCompare((Expression) n.getCompare().accept(this, arg)) ==> void
+  Line 557) final List<Expression> update = n.getUpdate() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 557) n.getUpdate() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 558) update != null ==> boolean
+  Line 559) int i = 0 ==> int
+  Line 559) 0 ==> int
+  Line 559) i < update.size() ==> boolean
+  Line 559) i++ ==> int
+  Line 560) update.set(i, (Expression) update.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 562) removeNulls(update) ==> void
+  Line 564) n.setBody((Statement) n.getBody().accept(this, arg)) ==> void
+  Line 565) n ==> com.github.javaparser.ast.stmt.ForStmt
+  Line 569) n.setCondition((Expression) n.getCondition().accept(this, arg)) ==> void
+  Line 570) n.setThenStmt((Statement) n.getThenStmt().accept(this, arg)) ==> void
+  Line 571) n.getElseStmt() != null ==> boolean
+  Line 572) n.setElseStmt((Statement) n.getElseStmt().accept(this, arg)) ==> void
+  Line 574) n ==> com.github.javaparser.ast.stmt.IfStmt
+  Line 578) n.setName((NameExpr) n.getName().accept(this, arg)) ==> void
+  Line 579) n ==> com.github.javaparser.ast.ImportDeclaration
+  Line 583) n.getJavaDoc() != null ==> boolean
+  Line 584) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 586) n.setBlock((BlockStmt) n.getBlock().accept(this, arg)) ==> void
+  Line 587) n ==> com.github.javaparser.ast.body.InitializerDeclaration
+  Line 591) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> void
+  Line 592) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 593) n ==> com.github.javaparser.ast.expr.InstanceOfExpr
+  Line 597) n ==> com.github.javaparser.ast.expr.IntegerLiteralExpr
+  Line 601) n ==> com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr
+  Line 605) n ==> com.github.javaparser.ast.comments.JavadocComment
+  Line 609) n.setStmt((Statement) n.getStmt().accept(this, arg)) ==> void
+  Line 610) n ==> com.github.javaparser.ast.stmt.LabeledStmt
+  Line 614) n ==> com.github.javaparser.ast.expr.LongLiteralExpr
+  Line 618) n ==> com.github.javaparser.ast.expr.LongLiteralMinValueExpr
+  Line 622) n.setName((NameExpr) n.getName().accept(this, arg)) ==> void
+  Line 623) n ==> com.github.javaparser.ast.expr.MarkerAnnotationExpr
+  Line 627) n.setValue((Expression) n.getValue().accept(this, arg)) ==> void
+  Line 628) n ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 632) n.getScope() != null ==> boolean
+  Line 633) n.setScope((Expression) n.getScope().accept(this, arg)) ==> void
+  Line 635) final List<Type> typeArgs = n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 635) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 636) typeArgs != null ==> boolean
+  Line 637) int i = 0 ==> int
+  Line 637) 0 ==> int
+  Line 637) i < typeArgs.size() ==> boolean
+  Line 637) i++ ==> int
+  Line 638) typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.Type
+  Line 640) removeNulls(typeArgs) ==> void
+  Line 642) final List<Expression> args = n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 642) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 643) args != null ==> boolean
+  Line 644) int i = 0 ==> int
+  Line 644) 0 ==> int
+  Line 644) i < args.size() ==> boolean
+  Line 644) i++ ==> int
+  Line 645) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 647) removeNulls(args) ==> void
+  Line 649) n ==> com.github.javaparser.ast.expr.MethodCallExpr
+  Line 653) n.getJavaDoc() != null ==> boolean
+  Line 654) n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg)) ==> void
+  Line 656) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 656) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 657) annotations != null ==> boolean
+  Line 658) int i = 0 ==> int
+  Line 658) 0 ==> int
+  Line 658) i < annotations.size() ==> boolean
+  Line 658) i++ ==> int
+  Line 659) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 661) removeNulls(annotations) ==> void
+  Line 663) final List<TypeParameter> typeParameters = n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 663) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 664) typeParameters != null ==> boolean
+  Line 665) int i = 0 ==> int
+  Line 665) 0 ==> int
+  Line 665) i < typeParameters.size() ==> boolean
+  Line 665) i++ ==> int
+  Line 666) typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg)) ==> com.github.javaparser.ast.TypeParameter
+  Line 668) removeNulls(typeParameters) ==> void
+  Line 670) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 671) final List<Parameter> parameters = n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 671) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 672) parameters != null ==> boolean
+  Line 673) int i = 0 ==> int
+  Line 673) 0 ==> int
+  Line 673) i < parameters.size() ==> boolean
+  Line 673) i++ ==> int
+  Line 674) parameters.set(i, (Parameter) parameters.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.Parameter
+  Line 676) removeNulls(parameters) ==> void
+  Line 678) final List<NameExpr> throwz = n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 678) n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 679) throwz != null ==> boolean
+  Line 680) int i = 0 ==> int
+  Line 680) 0 ==> int
+  Line 680) i < throwz.size() ==> boolean
+  Line 680) i++ ==> int
+  Line 681) throwz.set(i, (NameExpr) throwz.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.NameExpr
+  Line 683) removeNulls(throwz) ==> void
+  Line 685) n.getBody() != null ==> boolean
+  Line 686) n.setBody((BlockStmt) n.getBody().accept(this, arg)) ==> void
+  Line 688) n ==> com.github.javaparser.ast.body.MethodDeclaration
+  Line 692) n ==> com.github.javaparser.ast.expr.NameExpr
+  Line 696) n.setName((NameExpr) n.getName().accept(this, arg)) ==> void
+  Line 697) final List<MemberValuePair> pairs = n.getPairs() ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 697) n.getPairs() ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 698) pairs != null ==> boolean
+  Line 699) int i = 0 ==> int
+  Line 699) 0 ==> int
+  Line 699) i < pairs.size() ==> boolean
+  Line 699) i++ ==> int
+  Line 700) pairs.set(i, (MemberValuePair) pairs.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 702) removeNulls(pairs) ==> void
+  Line 704) n ==> com.github.javaparser.ast.expr.NormalAnnotationExpr
+  Line 708) n ==> com.github.javaparser.ast.expr.NullLiteralExpr
+  Line 712) n.getScope() != null ==> boolean
+  Line 713) n.setScope((Expression) n.getScope().accept(this, arg)) ==> void
+  Line 715) final List<Type> typeArgs = n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 715) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 716) typeArgs != null ==> boolean
+  Line 717) int i = 0 ==> int
+  Line 717) 0 ==> int
+  Line 717) i < typeArgs.size() ==> boolean
+  Line 717) i++ ==> int
+  Line 718) typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.Type
+  Line 720) removeNulls(typeArgs) ==> void
+  Line 722) n.setType((ClassOrInterfaceType) n.getType().accept(this, arg)) ==> void
+  Line 723) final List<Expression> args = n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 723) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 724) args != null ==> boolean
+  Line 725) int i = 0 ==> int
+  Line 725) 0 ==> int
+  Line 725) i < args.size() ==> boolean
+  Line 725) i++ ==> int
+  Line 726) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.Expression
+  Line 728) removeNulls(args) ==> void
+  Line 730) final List<BodyDeclaration> anonymousClassBody = n.getAnonymousClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 730) n.getAnonymousClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 731) anonymousClassBody != null ==> boolean
+  Line 732) int i = 0 ==> int
+  Line 732) 0 ==> int
+  Line 732) i < anonymousClassBody.size() ==> boolean
+  Line 732) i++ ==> int
+  Line 733) anonymousClassBody.set(i, (BodyDeclaration) anonymousClassBody.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 735) removeNulls(anonymousClassBody) ==> void
+  Line 737) n ==> com.github.javaparser.ast.expr.ObjectCreationExpr
+  Line 741) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 741) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 742) annotations != null ==> boolean
+  Line 743) int i = 0 ==> int
+  Line 743) 0 ==> int
+  Line 743) i < annotations.size() ==> boolean
+  Line 743) i++ ==> int
+  Line 744) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 746) removeNulls(annotations) ==> void
+  Line 748) n.setName((NameExpr) n.getName().accept(this, arg)) ==> void
+  Line 749) n ==> com.github.javaparser.ast.PackageDeclaration
+  Line 753) visit((BaseParameter) n, arg) ==> com.github.javaparser.ast.Node
+  Line 754) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 755) n ==> com.github.javaparser.ast.body.Parameter
+  Line 759) visit((BaseParameter) n, arg) ==> com.github.javaparser.ast.Node
+  Line 760) List<Type> types = new LinkedList<Type>() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 760) new LinkedList<Type>() ==> java.util.LinkedList<com.github.javaparser.ast.type.Type>
+  Line 761) Type type ==> com.github.javaparser.ast.type.Type
+  Line 761) n.getTypes() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 762) types.add((Type) type.accept(this, arg)) ==> boolean
+  Line 764) n.setTypes(types) ==> void
+  Line 765) n ==> com.github.javaparser.ast.body.MultiTypeParameter
+  Line 769) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 769) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 770) annotations != null ==> boolean
+  Line 771) int i = 0 ==> int
+  Line 771) 0 ==> int
+  Line 771) i < annotations.size() ==> boolean
+  Line 771) i++ ==> int
+  Line 772) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 774) removeNulls(annotations) ==> void
+  Line 777) n.setId((VariableDeclaratorId) n.getId().accept(this, arg)) ==> void
+  Line 778) n ==> com.github.javaparser.ast.body.BaseParameter
+  Line 782) n ==> com.github.javaparser.ast.type.PrimitiveType
+  Line 786) n.setQualifier((NameExpr) n.getQualifier().accept(this, arg)) ==> void
+  Line 787) n ==> com.github.javaparser.ast.expr.QualifiedNameExpr
+  Line 791) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 792) n ==> com.github.javaparser.ast.type.ReferenceType
+  Line 796) n.getExpr() != null ==> boolean
+  Line 797) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> void
+  Line 799) n ==> com.github.javaparser.ast.stmt.ReturnStmt
+  Line 803) n.setName((NameExpr) n.getName().accept(this, arg)) ==> void
+  Line 804) n.setMemberValue((Expression) n.getMemberValue().accept(this, arg)) ==> void
+  Line 805) n ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
+  Line 809) n ==> com.github.javaparser.ast.expr.StringLiteralExpr
+  Line 813) n.getClassExpr() != null ==> boolean
+  Line 814) n.setClassExpr((Expression) n.getClassExpr().accept(this, arg)) ==> void
+  Line 816) n ==> com.github.javaparser.ast.expr.SuperExpr
+  Line 820) n.getLabel() != null ==> boolean
+  Line 821) n.setLabel((Expression) n.getLabel().accept(this, arg)) ==> void
+  Line 823) final List<Statement> stmts = n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 823) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 824) stmts != null ==> boolean
+  Line 825) int i = 0 ==> int
+  Line 825) 0 ==> int
+  Line 825) i < stmts.size() ==> boolean
+  Line 825) i++ ==> int
+  Line 826) stmts.set(i, (Statement) stmts.get(i).accept(this, arg)) ==> com.github.javaparser.ast.stmt.Statement
+  Line 828) removeNulls(stmts) ==> void
+  Line 830) n ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 834) n.setSelector((Expression) n.getSelector().accept(this, arg)) ==> void
+  Line 835) final List<SwitchEntryStmt> entries = n.getEntries() ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 835) n.getEntries() ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 836) entries != null ==> boolean
+  Line 837) int i = 0 ==> int
+  Line 837) 0 ==> int
+  Line 837) i < entries.size() ==> boolean
+  Line 837) i++ ==> int
+  Line 838) entries.set(i, (SwitchEntryStmt) entries.get(i).accept(this, arg)) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 840) removeNulls(entries) ==> void
+  Line 842) n ==> com.github.javaparser.ast.stmt.SwitchStmt
+  Line 847) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> void
+  Line 848) n.setBlock((BlockStmt) n.getBlock().accept(this, arg)) ==> void
+  Line 849) n ==> com.github.javaparser.ast.stmt.SynchronizedStmt
+  Line 853) n.getClassExpr() != null ==> boolean
+  Line 854) n.setClassExpr((Expression) n.getClassExpr().accept(this, arg)) ==> void
+  Line 856) n ==> com.github.javaparser.ast.expr.ThisExpr
+  Line 860) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> void
+  Line 861) n ==> com.github.javaparser.ast.stmt.ThrowStmt
+  Line 865) n.setTryBlock((BlockStmt) n.getTryBlock().accept(this, arg)) ==> void
+  Line 866) final List<CatchClause> catchs = n.getCatchs() ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 866) n.getCatchs() ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 867) catchs != null ==> boolean
+  Line 868) int i = 0 ==> int
+  Line 868) 0 ==> int
+  Line 868) i < catchs.size() ==> boolean
+  Line 868) i++ ==> int
+  Line 869) catchs.set(i, (CatchClause) catchs.get(i).accept(this, arg)) ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 871) removeNulls(catchs) ==> void
+  Line 873) n.getFinallyBlock() != null ==> boolean
+  Line 874) n.setFinallyBlock((BlockStmt) n.getFinallyBlock().accept(this, arg)) ==> void
+  Line 876) n ==> com.github.javaparser.ast.stmt.TryStmt
+  Line 880) n.setTypeDeclaration((TypeDeclaration) n.getTypeDeclaration().accept(this, arg)) ==> void
+  Line 881) n ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt
+  Line 885) final List<ClassOrInterfaceType> typeBound = n.getTypeBound() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 885) n.getTypeBound() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 886) typeBound != null ==> boolean
+  Line 887) int i = 0 ==> int
+  Line 887) 0 ==> int
+  Line 887) i < typeBound.size() ==> boolean
+  Line 887) i++ ==> int
+  Line 888) typeBound.set(i, (ClassOrInterfaceType) typeBound.get(i).accept(this, arg)) ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 890) removeNulls(typeBound) ==> void
+  Line 892) n ==> com.github.javaparser.ast.TypeParameter
+  Line 896) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> void
+  Line 897) n ==> com.github.javaparser.ast.expr.UnaryExpr
+  Line 901) n ==> com.github.javaparser.ast.type.UnknownType
+  Line 905) final List<AnnotationExpr> annotations = n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 905) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 906) annotations != null ==> boolean
+  Line 907) int i = 0 ==> int
+  Line 907) 0 ==> int
+  Line 907) i < annotations.size() ==> boolean
+  Line 907) i++ ==> int
+  Line 908) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 910) removeNulls(annotations) ==> void
+  Line 912) n.setType((Type) n.getType().accept(this, arg)) ==> void
+  Line 913) final List<VariableDeclarator> vars = n.getVars() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 913) n.getVars() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 914) int i = 0 ==> int
+  Line 914) 0 ==> int
+  Line 914) i < vars.size() ==> boolean
+  Line 914) i++ ==> int
+  Line 915) vars.set(i, (VariableDeclarator) vars.get(i).accept(this, arg)) ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 917) removeNulls(vars) ==> void
+  Line 918) n ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 922) n.setId((VariableDeclaratorId) n.getId().accept(this, arg)) ==> void
+  Line 923) n.getInit() != null ==> boolean
+  Line 924) n.setInit((Expression) n.getInit().accept(this, arg)) ==> void
+  Line 926) n ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 930) n ==> com.github.javaparser.ast.body.VariableDeclaratorId
+  Line 934) n ==> com.github.javaparser.ast.type.VoidType
+  Line 938) n.setCondition((Expression) n.getCondition().accept(this, arg)) ==> void
+  Line 939) n.setBody((Statement) n.getBody().accept(this, arg)) ==> void
+  Line 940) n ==> com.github.javaparser.ast.stmt.WhileStmt
+  Line 944) n.getExtends() != null ==> boolean
+  Line 945) n.setExtends((ReferenceType) n.getExtends().accept(this, arg)) ==> void
+  Line 947) n.getSuper() != null ==> boolean
+  Line 948) n.setSuper((ReferenceType) n.getSuper().accept(this, arg)) ==> void
+  Line 950) n ==> com.github.javaparser.ast.type.WildcardType
+  Line 954) n ==> com.github.javaparser.ast.expr.LambdaExpr
+  Line 958) n ==> com.github.javaparser.ast.expr.MethodReferenceExpr
+  Line 962) n ==> com.github.javaparser.ast.expr.TypeExpr
+  Line 966) n ==> com.github.javaparser.ast.comments.BlockComment
+  Line 970) n ==> com.github.javaparser.ast.comments.LineComment
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_VoidVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_VoidVisitor.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_VoidVisitor.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_VoidVisitorAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_VoidVisitorAdapter.txt
new file mode 100644
index 0000000..e3d27e4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_expected_output/com_github_javaparser_ast_visitor_VoidVisitorAdapter.txt
@@ -0,0 +1,425 @@
+
+[ Class com.github.javaparser.ast.visitor.VoidVisitorAdapter ]
+  superclass: java.lang.Object
+  interface: com.github.javaparser.ast.visitor.VoidVisitor
+  Line 82) visitComment(n.getComment(), arg) ==> void
+  Line 83) n.getJavaDoc() != null ==> boolean
+  Line 84) n.getJavaDoc().accept(this, arg) ==> void
+  Line 86) n.getAnnotations() != null ==> boolean
+  Line 87) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 87) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 88) a.accept(this, arg) ==> void
+  Line 91) n.getMembers() != null ==> boolean
+  Line 92) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 92) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 93) member.accept(this, arg) ==> void
+  Line 99) visitComment(n.getComment(), arg) ==> void
+  Line 100) n.getJavaDoc() != null ==> boolean
+  Line 101) n.getJavaDoc().accept(this, arg) ==> void
+  Line 103) n.getAnnotations() != null ==> boolean
+  Line 104) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 104) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 105) a.accept(this, arg) ==> void
+  Line 108) n.getType().accept(this, arg) ==> void
+  Line 109) n.getDefaultValue() != null ==> boolean
+  Line 110) n.getDefaultValue().accept(this, arg) ==> void
+  Line 115) visitComment(n.getComment(), arg) ==> void
+  Line 116) n.getName().accept(this, arg) ==> void
+  Line 117) n.getIndex().accept(this, arg) ==> void
+  Line 121) visitComment(n.getComment(), arg) ==> void
+  Line 122) n.getType().accept(this, arg) ==> void
+  Line 123) !isNullOrEmpty(n.getDimensions()) ==> boolean
+  Line 124) final Expression dim ==> com.github.javaparser.ast.expr.Expression
+  Line 124) n.getDimensions() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 125) dim.accept(this, arg) ==> void
+  Line 128) n.getInitializer().accept(this, arg) ==> void
+  Line 133) visitComment(n.getComment(), arg) ==> void
+  Line 134) n.getValues() != null ==> boolean
+  Line 135) final Expression expr ==> com.github.javaparser.ast.expr.Expression
+  Line 135) n.getValues() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 136) expr.accept(this, arg) ==> void
+  Line 142) visitComment(n.getComment(), arg) ==> void
+  Line 143) n.getCheck().accept(this, arg) ==> void
+  Line 144) n.getMessage() != null ==> boolean
+  Line 145) n.getMessage().accept(this, arg) ==> void
+  Line 150) visitComment(n.getComment(), arg) ==> void
+  Line 151) n.getTarget().accept(this, arg) ==> void
+  Line 152) n.getValue().accept(this, arg) ==> void
+  Line 156) visitComment(n.getComment(), arg) ==> void
+  Line 157) n.getLeft().accept(this, arg) ==> void
+  Line 158) n.getRight().accept(this, arg) ==> void
+  Line 162) visitComment(n.getComment(), arg) ==> void
+  Line 166) visitComment(n.getComment(), arg) ==> void
+  Line 167) n.getStmts() != null ==> boolean
+  Line 168) final Statement s ==> com.github.javaparser.ast.stmt.Statement
+  Line 168) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 169) s.accept(this, arg) ==> void
+  Line 175) visitComment(n.getComment(), arg) ==> void
+  Line 179) visitComment(n.getComment(), arg) ==> void
+  Line 183) visitComment(n.getComment(), arg) ==> void
+  Line 184) n.getType().accept(this, arg) ==> void
+  Line 185) n.getExpr().accept(this, arg) ==> void
+  Line 189) visitComment(n.getComment(), arg) ==> void
+  Line 190) n.getExcept().accept(this, arg) ==> void
+  Line 191) n.getCatchBlock().accept(this, arg) ==> void
+  Line 195) visitComment(n.getComment(), arg) ==> void
+  Line 199) visitComment(n.getComment(), arg) ==> void
+  Line 200) n.getType().accept(this, arg) ==> void
+  Line 204) visitComment(n.getComment(), arg) ==> void
+  Line 205) n.getJavaDoc() != null ==> boolean
+  Line 206) n.getJavaDoc().accept(this, arg) ==> void
+  Line 208) n.getAnnotations() != null ==> boolean
+  Line 209) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 209) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 210) a.accept(this, arg) ==> void
+  Line 213) n.getTypeParameters() != null ==> boolean
+  Line 214) final TypeParameter t ==> com.github.javaparser.ast.TypeParameter
+  Line 214) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 215) t.accept(this, arg) ==> void
+  Line 218) n.getExtends() != null ==> boolean
+  Line 219) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 219) n.getExtends() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 220) c.accept(this, arg) ==> void
+  Line 224) n.getImplements() != null ==> boolean
+  Line 225) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 225) n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 226) c.accept(this, arg) ==> void
+  Line 229) n.getMembers() != null ==> boolean
+  Line 230) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 230) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 231) member.accept(this, arg) ==> void
+  Line 237) visitComment(n.getComment(), arg) ==> void
+  Line 238) n.getScope() != null ==> boolean
+  Line 239) n.getScope().accept(this, arg) ==> void
+  Line 241) n.getTypeArgs() != null ==> boolean
+  Line 242) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 242) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 243) t.accept(this, arg) ==> void
+  Line 249) visitComment(n.getComment(), arg) ==> void
+  Line 250) n.getPackage() != null ==> boolean
+  Line 251) n.getPackage().accept(this, arg) ==> void
+  Line 253) n.getImports() != null ==> boolean
+  Line 254) final ImportDeclaration i ==> com.github.javaparser.ast.ImportDeclaration
+  Line 254) n.getImports() ==> java.util.List<com.github.javaparser.ast.ImportDeclaration>
+  Line 255) i.accept(this, arg) ==> void
+  Line 258) n.getTypes() != null ==> boolean
+  Line 259) final TypeDeclaration typeDeclaration ==> com.github.javaparser.ast.body.TypeDeclaration
+  Line 259) n.getTypes() ==> java.util.List<com.github.javaparser.ast.body.TypeDeclaration>
+  Line 260) typeDeclaration.accept(this, arg) ==> void
+  Line 266) visitComment(n.getComment(), arg) ==> void
+  Line 267) n.getCondition().accept(this, arg) ==> void
+  Line 268) n.getThenExpr().accept(this, arg) ==> void
+  Line 269) n.getElseExpr().accept(this, arg) ==> void
+  Line 273) visitComment(n.getComment(), arg) ==> void
+  Line 274) n.getJavaDoc() != null ==> boolean
+  Line 275) n.getJavaDoc().accept(this, arg) ==> void
+  Line 277) n.getAnnotations() != null ==> boolean
+  Line 278) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 278) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 279) a.accept(this, arg) ==> void
+  Line 282) n.getTypeParameters() != null ==> boolean
+  Line 283) final TypeParameter t ==> com.github.javaparser.ast.TypeParameter
+  Line 283) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 284) t.accept(this, arg) ==> void
+  Line 287) n.getParameters() != null ==> boolean
+  Line 288) final Parameter p ==> com.github.javaparser.ast.body.Parameter
+  Line 288) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 289) p.accept(this, arg) ==> void
+  Line 292) n.getThrows() != null ==> boolean
+  Line 293) final NameExpr name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 293) n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 294) name.accept(this, arg) ==> void
+  Line 297) n.getBlock().accept(this, arg) ==> void
+  Line 301) visitComment(n.getComment(), arg) ==> void
+  Line 305) visitComment(n.getComment(), arg) ==> void
+  Line 306) n.getBody().accept(this, arg) ==> void
+  Line 307) n.getCondition().accept(this, arg) ==> void
+  Line 311) visitComment(n.getComment(), arg) ==> void
+  Line 315) visitComment(n.getComment(), arg) ==> void
+  Line 316) n.getJavaDoc() != null ==> boolean
+  Line 317) n.getJavaDoc().accept(this, arg) ==> void
+  Line 322) visitComment(n.getComment(), arg) ==> void
+  Line 326) visitComment(n.getComment(), arg) ==> void
+  Line 327) n.getJavaDoc() != null ==> boolean
+  Line 328) n.getJavaDoc().accept(this, arg) ==> void
+  Line 333) visitComment(n.getComment(), arg) ==> void
+  Line 334) n.getInner().accept(this, arg) ==> void
+  Line 338) visitComment(n.getComment(), arg) ==> void
+  Line 339) n.getJavaDoc() != null ==> boolean
+  Line 340) n.getJavaDoc().accept(this, arg) ==> void
+  Line 342) n.getAnnotations() != null ==> boolean
+  Line 343) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 343) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 344) a.accept(this, arg) ==> void
+  Line 347) n.getArgs() != null ==> boolean
+  Line 348) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 348) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 349) e.accept(this, arg) ==> void
+  Line 352) n.getClassBody() != null ==> boolean
+  Line 353) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 353) n.getClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 354) member.accept(this, arg) ==> void
+  Line 360) visitComment(n.getComment(), arg) ==> void
+  Line 361) n.getJavaDoc() != null ==> boolean
+  Line 362) n.getJavaDoc().accept(this, arg) ==> void
+  Line 364) n.getAnnotations() != null ==> boolean
+  Line 365) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 365) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 366) a.accept(this, arg) ==> void
+  Line 369) n.getImplements() != null ==> boolean
+  Line 370) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 370) n.getImplements() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 371) c.accept(this, arg) ==> void
+  Line 374) n.getEntries() != null ==> boolean
+  Line 375) final EnumConstantDeclaration e ==> com.github.javaparser.ast.body.EnumConstantDeclaration
+  Line 375) n.getEntries() ==> java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>
+  Line 376) e.accept(this, arg) ==> void
+  Line 379) n.getMembers() != null ==> boolean
+  Line 380) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 380) n.getMembers() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 381) member.accept(this, arg) ==> void
+  Line 387) visitComment(n.getComment(), arg) ==> void
+  Line 388) !n.isThis() ==> boolean
+  Line 389) n.getExpr() != null ==> boolean
+  Line 390) n.getExpr().accept(this, arg) ==> void
+  Line 393) n.getTypeArgs() != null ==> boolean
+  Line 394) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 394) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 395) t.accept(this, arg) ==> void
+  Line 398) n.getArgs() != null ==> boolean
+  Line 399) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 399) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 400) e.accept(this, arg) ==> void
+  Line 406) visitComment(n.getComment(), arg) ==> void
+  Line 407) n.getExpression().accept(this, arg) ==> void
+  Line 411) visitComment(n.getComment(), arg) ==> void
+  Line 412) n.getScope().accept(this, arg) ==> void
+  Line 416) visitComment(n.getComment(), arg) ==> void
+  Line 417) n.getJavaDoc() != null ==> boolean
+  Line 418) n.getJavaDoc().accept(this, arg) ==> void
+  Line 420) n.getAnnotations() != null ==> boolean
+  Line 421) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 421) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 422) a.accept(this, arg) ==> void
+  Line 425) n.getType().accept(this, arg) ==> void
+  Line 426) final VariableDeclarator var ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 426) n.getVariables() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 427) var.accept(this, arg) ==> void
+  Line 432) visitComment(n.getComment(), arg) ==> void
+  Line 433) n.getVariable().accept(this, arg) ==> void
+  Line 434) n.getIterable().accept(this, arg) ==> void
+  Line 435) n.getBody().accept(this, arg) ==> void
+  Line 439) visitComment(n.getComment(), arg) ==> void
+  Line 440) n.getInit() != null ==> boolean
+  Line 441) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 441) n.getInit() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 442) e.accept(this, arg) ==> void
+  Line 445) n.getCompare() != null ==> boolean
+  Line 446) n.getCompare().accept(this, arg) ==> void
+  Line 448) n.getUpdate() != null ==> boolean
+  Line 449) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 449) n.getUpdate() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 450) e.accept(this, arg) ==> void
+  Line 453) n.getBody().accept(this, arg) ==> void
+  Line 457) visitComment(n.getComment(), arg) ==> void
+  Line 458) n.getCondition().accept(this, arg) ==> void
+  Line 459) n.getThenStmt().accept(this, arg) ==> void
+  Line 460) n.getElseStmt() != null ==> boolean
+  Line 461) n.getElseStmt().accept(this, arg) ==> void
+  Line 466) visitComment(n.getComment(), arg) ==> void
+  Line 467) n.getName().accept(this, arg) ==> void
+  Line 471) visitComment(n.getComment(), arg) ==> void
+  Line 472) n.getJavaDoc() != null ==> boolean
+  Line 473) n.getJavaDoc().accept(this, arg) ==> void
+  Line 475) n.getBlock().accept(this, arg) ==> void
+  Line 479) visitComment(n.getComment(), arg) ==> void
+  Line 480) n.getExpr().accept(this, arg) ==> void
+  Line 481) n.getType().accept(this, arg) ==> void
+  Line 485) visitComment(n.getComment(), arg) ==> void
+  Line 489) visitComment(n.getComment(), arg) ==> void
+  Line 493) visitComment(n.getComment(), arg) ==> void
+  Line 497) visitComment(n.getComment(), arg) ==> void
+  Line 498) n.getStmt().accept(this, arg) ==> void
+  Line 502) visitComment(n.getComment(), arg) ==> void
+  Line 506) visitComment(n.getComment(), arg) ==> void
+  Line 510) visitComment(n.getComment(), arg) ==> void
+  Line 514) visitComment(n.getComment(), arg) ==> void
+  Line 515) n.getName().accept(this, arg) ==> void
+  Line 519) visitComment(n.getComment(), arg) ==> void
+  Line 520) n.getValue().accept(this, arg) ==> void
+  Line 524) visitComment(n.getComment(), arg) ==> void
+  Line 525) n.getScope() != null ==> boolean
+  Line 526) n.getScope().accept(this, arg) ==> void
+  Line 528) n.getTypeArgs() != null ==> boolean
+  Line 529) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 529) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 530) t.accept(this, arg) ==> void
+  Line 533) n.getArgs() != null ==> boolean
+  Line 534) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 534) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 535) e.accept(this, arg) ==> void
+  Line 541) visitComment(n.getComment(), arg) ==> void
+  Line 542) n.getJavaDoc() != null ==> boolean
+  Line 543) n.getJavaDoc().accept(this, arg) ==> void
+  Line 545) n.getAnnotations() != null ==> boolean
+  Line 546) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 546) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 547) a.accept(this, arg) ==> void
+  Line 550) n.getTypeParameters() != null ==> boolean
+  Line 551) final TypeParameter t ==> com.github.javaparser.ast.TypeParameter
+  Line 551) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 552) t.accept(this, arg) ==> void
+  Line 555) n.getType().accept(this, arg) ==> void
+  Line 556) n.getParameters() != null ==> boolean
+  Line 557) final Parameter p ==> com.github.javaparser.ast.body.Parameter
+  Line 557) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 558) p.accept(this, arg) ==> void
+  Line 561) n.getThrows() != null ==> boolean
+  Line 562) final NameExpr name ==> com.github.javaparser.ast.expr.NameExpr
+  Line 562) n.getThrows() ==> java.util.List<com.github.javaparser.ast.expr.NameExpr>
+  Line 563) name.accept(this, arg) ==> void
+  Line 566) n.getBody() != null ==> boolean
+  Line 567) n.getBody().accept(this, arg) ==> void
+  Line 572) visitComment(n.getComment(), arg) ==> void
+  Line 576) visitComment(n.getComment(), arg) ==> void
+  Line 577) n.getName().accept(this, arg) ==> void
+  Line 578) n.getPairs() != null ==> boolean
+  Line 579) final MemberValuePair m ==> com.github.javaparser.ast.expr.MemberValuePair
+  Line 579) n.getPairs() ==> java.util.List<com.github.javaparser.ast.expr.MemberValuePair>
+  Line 580) m.accept(this, arg) ==> void
+  Line 586) visitComment(n.getComment(), arg) ==> void
+  Line 590) visitComment(n.getComment(), arg) ==> void
+  Line 591) n.getScope() != null ==> boolean
+  Line 592) n.getScope().accept(this, arg) ==> void
+  Line 594) n.getTypeArgs() != null ==> boolean
+  Line 595) final Type t ==> com.github.javaparser.ast.type.Type
+  Line 595) n.getTypeArgs() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 596) t.accept(this, arg) ==> void
+  Line 599) n.getType().accept(this, arg) ==> void
+  Line 600) n.getArgs() != null ==> boolean
+  Line 601) final Expression e ==> com.github.javaparser.ast.expr.Expression
+  Line 601) n.getArgs() ==> java.util.List<com.github.javaparser.ast.expr.Expression>
+  Line 602) e.accept(this, arg) ==> void
+  Line 605) n.getAnonymousClassBody() != null ==> boolean
+  Line 606) final BodyDeclaration member ==> com.github.javaparser.ast.body.BodyDeclaration
+  Line 606) n.getAnonymousClassBody() ==> java.util.List<com.github.javaparser.ast.body.BodyDeclaration>
+  Line 607) member.accept(this, arg) ==> void
+  Line 613) visitComment(n.getComment(), arg) ==> void
+  Line 614) n.getAnnotations() != null ==> boolean
+  Line 615) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 615) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 616) a.accept(this, arg) ==> void
+  Line 619) n.getName().accept(this, arg) ==> void
+  Line 623) visitComment(n.getComment(), arg) ==> void
+  Line 624) n.getAnnotations() != null ==> boolean
+  Line 625) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 625) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 626) a.accept(this, arg) ==> void
+  Line 629) n.getType().accept(this, arg) ==> void
+  Line 630) n.getId().accept(this, arg) ==> void
+  Line 634) visitComment(n.getComment(), arg) ==> void
+  Line 635) n.getAnnotations() != null ==> boolean
+  Line 636) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 636) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 637) a.accept(this, arg) ==> void
+  Line 640) final Type type ==> com.github.javaparser.ast.type.Type
+  Line 640) n.getTypes() ==> java.util.List<com.github.javaparser.ast.type.Type>
+  Line 641) type.accept(this, arg) ==> void
+  Line 643) n.getId().accept(this, arg) ==> void
+  Line 647) visitComment(n.getComment(), arg) ==> void
+  Line 651) visitComment(n.getComment(), arg) ==> void
+  Line 652) n.getQualifier().accept(this, arg) ==> void
+  Line 656) visitComment(n.getComment(), arg) ==> void
+  Line 657) n.getType().accept(this, arg) ==> void
+  Line 661) visitComment(n.getComment(), arg) ==> void
+  Line 662) n.getExpr() != null ==> boolean
+  Line 663) n.getExpr().accept(this, arg) ==> void
+  Line 668) visitComment(n.getComment(), arg) ==> void
+  Line 669) n.getName().accept(this, arg) ==> void
+  Line 670) n.getMemberValue().accept(this, arg) ==> void
+  Line 674) visitComment(n.getComment(), arg) ==> void
+  Line 678) visitComment(n.getComment(), arg) ==> void
+  Line 679) n.getClassExpr() != null ==> boolean
+  Line 680) n.getClassExpr().accept(this, arg) ==> void
+  Line 685) visitComment(n.getComment(), arg) ==> void
+  Line 686) n.getLabel() != null ==> boolean
+  Line 687) n.getLabel().accept(this, arg) ==> void
+  Line 689) n.getStmts() != null ==> boolean
+  Line 690) final Statement s ==> com.github.javaparser.ast.stmt.Statement
+  Line 690) n.getStmts() ==> java.util.List<com.github.javaparser.ast.stmt.Statement>
+  Line 691) s.accept(this, arg) ==> void
+  Line 697) visitComment(n.getComment(), arg) ==> void
+  Line 698) n.getSelector().accept(this, arg) ==> void
+  Line 699) n.getEntries() != null ==> boolean
+  Line 700) final SwitchEntryStmt e ==> com.github.javaparser.ast.stmt.SwitchEntryStmt
+  Line 700) n.getEntries() ==> java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>
+  Line 701) e.accept(this, arg) ==> void
+  Line 707) visitComment(n.getComment(), arg) ==> void
+  Line 708) n.getExpr().accept(this, arg) ==> void
+  Line 709) n.getBlock().accept(this, arg) ==> void
+  Line 713) visitComment(n.getComment(), arg) ==> void
+  Line 714) n.getClassExpr() != null ==> boolean
+  Line 715) n.getClassExpr().accept(this, arg) ==> void
+  Line 720) visitComment(n.getComment(), arg) ==> void
+  Line 721) n.getExpr().accept(this, arg) ==> void
+  Line 725) visitComment(n.getComment(), arg) ==> void
+  Line 726) n.getResources() != null ==> boolean
+  Line 727) final VariableDeclarationExpr v ==> com.github.javaparser.ast.expr.VariableDeclarationExpr
+  Line 727) n.getResources() ==> java.util.List<com.github.javaparser.ast.expr.VariableDeclarationExpr>
+  Line 728) v.accept(this, arg) ==> void
+  Line 731) n.getTryBlock().accept(this, arg) ==> void
+  Line 732) n.getCatchs() != null ==> boolean
+  Line 733) final CatchClause c ==> com.github.javaparser.ast.stmt.CatchClause
+  Line 733) n.getCatchs() ==> java.util.List<com.github.javaparser.ast.stmt.CatchClause>
+  Line 734) c.accept(this, arg) ==> void
+  Line 737) n.getFinallyBlock() != null ==> boolean
+  Line 738) n.getFinallyBlock().accept(this, arg) ==> void
+  Line 743) visitComment(n.getComment(), arg) ==> void
+  Line 744) n.getTypeDeclaration().accept(this, arg) ==> void
+  Line 748) visitComment(n.getComment(), arg) ==> void
+  Line 749) n.getTypeBound() != null ==> boolean
+  Line 750) final ClassOrInterfaceType c ==> com.github.javaparser.ast.type.ClassOrInterfaceType
+  Line 750) n.getTypeBound() ==> java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>
+  Line 751) c.accept(this, arg) ==> void
+  Line 757) visitComment(n.getComment(), arg) ==> void
+  Line 758) n.getExpr().accept(this, arg) ==> void
+  Line 762) visitComment(n.getComment(), arg) ==> void
+  Line 766) visitComment(n.getComment(), arg) ==> void
+  Line 767) n.getAnnotations() != null ==> boolean
+  Line 768) final AnnotationExpr a ==> com.github.javaparser.ast.expr.AnnotationExpr
+  Line 768) n.getAnnotations() ==> java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>
+  Line 769) a.accept(this, arg) ==> void
+  Line 772) n.getType().accept(this, arg) ==> void
+  Line 773) final VariableDeclarator v ==> com.github.javaparser.ast.body.VariableDeclarator
+  Line 773) n.getVars() ==> java.util.List<com.github.javaparser.ast.body.VariableDeclarator>
+  Line 774) v.accept(this, arg) ==> void
+  Line 779) visitComment(n.getComment(), arg) ==> void
+  Line 780) n.getId().accept(this, arg) ==> void
+  Line 781) n.getInit() != null ==> boolean
+  Line 782) n.getInit().accept(this, arg) ==> void
+  Line 787) visitComment(n.getComment(), arg) ==> void
+  Line 791) visitComment(n.getComment(), arg) ==> void
+  Line 795) visitComment(n.getComment(), arg) ==> void
+  Line 796) n.getCondition().accept(this, arg) ==> void
+  Line 797) n.getBody().accept(this, arg) ==> void
+  Line 801) visitComment(n.getComment(), arg) ==> void
+  Line 802) n.getExtends() != null ==> boolean
+  Line 803) n.getExtends().accept(this, arg) ==> void
+  Line 805) n.getSuper() != null ==> boolean
+  Line 806) n.getSuper().accept(this, arg) ==> void
+  Line 812) n.getParameters() != null ==> boolean
+  Line 813) final Parameter a ==> com.github.javaparser.ast.body.Parameter
+  Line 813) n.getParameters() ==> java.util.List<com.github.javaparser.ast.body.Parameter>
+  Line 814) a.accept(this, arg) ==> void
+  Line 817) n.getBody() != null ==> boolean
+  Line 818) n.getBody().accept(this, arg) ==> void
+  Line 824) n.getTypeParameters() != null ==> boolean
+  Line 825) final TypeParameter a ==> com.github.javaparser.ast.TypeParameter
+  Line 825) n.getTypeParameters() ==> java.util.List<com.github.javaparser.ast.TypeParameter>
+  Line 826) a.accept(this, arg) ==> void
+  Line 829) n.getScope() != null ==> boolean
+  Line 830) n.getScope().accept(this, arg) ==> void
+  Line 836) n.getType() != null ==> boolean
+  Line 837) n.getType().accept(this, arg) ==> void
+  Line 842) n != null ==> boolean
+  Line 843) n.accept(this, arg) ==> void
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_CommentsInserter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_CommentsInserter.txt
new file mode 100644
index 0000000..003f216
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_CommentsInserter.txt
@@ -0,0 +1,49 @@
+  Line 52) comments.isEmpty() ==> java.util.TreeSet.isEmpty()
+  Line 63) cu.getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 64) PositionUtils.sortByBeginPosition(children) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>)
+  Line 66) comments.iterator().next() ==> java.util.Iterator.next()
+  Line 66) comments.iterator() ==> java.util.TreeSet.iterator()
+  Line 67) cu.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 68) children.isEmpty() ==> java.util.List.isEmpty()
+  Line 68) PositionUtils.areInOrder(firstComment, children.get(0)) ==> com.github.javaparser.utils.PositionUtils.areInOrder(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node)
+  Line 69) children.get(0) ==> java.util.List.get(int)
+  Line 70) cu.setComment(firstComment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 71) comments.remove(firstComment) ==> java.util.TreeSet.remove(java.lang.Object)
+  Line 80) commentsToAttribute.isEmpty() ==> java.util.TreeSet.isEmpty()
+  Line 84) insertComments((CompilationUnit) node, commentsToAttribute) ==> com.github.javaparser.CommentsInserter.insertComments(com.github.javaparser.ast.CompilationUnit, java.util.TreeSet<com.github.javaparser.ast.comments.Comment>)
+  Line 95) node.getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 96) PositionUtils.sortByBeginPosition(children) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>)
+  Line 101) PositionUtils.nodeContains(child, c, configuration.doNotConsiderAnnotationsAsNodeStartForCodeAttribution) ==> com.github.javaparser.utils.PositionUtils.nodeContains(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node, boolean)
+  Line 103) commentsInsideChild.add(c) ==> java.util.TreeSet.add(E)
+  Line 106) commentsToAttribute.removeAll(commentsInsideChild) ==> java.util.AbstractSet.removeAll(java.util.Collection<? extends java.lang.Object>)
+  Line 107) insertComments(child, commentsInsideChild) ==> com.github.javaparser.CommentsInserter.insertComments(com.github.javaparser.ast.Node, java.util.TreeSet<com.github.javaparser.ast.comments.Comment>)
+  Line 114) comment.isLineComment() ==> com.github.javaparser.ast.comments.Comment.isLineComment()
+  Line 116) child.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 116) comment.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 117) attributeLineCommentToNodeOrChild(child, comment.asLineComment()) ==> com.github.javaparser.CommentsInserter.attributeLineCommentToNodeOrChild(com.github.javaparser.ast.Node, com.github.javaparser.ast.comments.LineComment)
+  Line 118) comment.asLineComment() ==> com.github.javaparser.ast.comments.Comment.asLineComment()
+  Line 119) attributedComments.add(comment) ==> java.util.List.add(E)
+  Line 130) childrenAndComments.addAll(children) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 131) childrenAndComments.addAll(commentsToAttribute) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 132) PositionUtils.sortByBeginPosition(childrenAndComments, configuration.doNotConsiderAnnotationsAsNodeStartForCodeAttribution) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>, boolean)
+  Line 138) previousComment.isOrphan() ==> com.github.javaparser.ast.comments.Comment.isOrphan()
+  Line 142) thing.hasComment() ==> com.github.javaparser.ast.Node.hasComment()
+  Line 144) thereAreLinesBetween(previousComment, thing) ==> com.github.javaparser.CommentsInserter.thereAreLinesBetween(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node)
+  Line 145) thing.setComment(previousComment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 146) attributedComments.add(previousComment) ==> java.util.List.add(E)
+  Line 153) commentsToAttribute.removeAll(attributedComments) ==> java.util.AbstractSet.removeAll(java.util.Collection<? extends java.lang.Object>)
+  Line 157) c.isOrphan() ==> com.github.javaparser.ast.comments.Comment.isOrphan()
+  Line 158) node.addOrphanComment(c) ==> com.github.javaparser.ast.Node.addOrphanComment(com.github.javaparser.ast.comments.Comment)
+  Line 166) node.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 166) lineComment.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 167) node.hasComment() ==> com.github.javaparser.ast.Node.hasComment()
+  Line 169) node.setComment(lineComment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 176) children.addAll(node.getChildrenNodes()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 176) node.getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 177) PositionUtils.sortByBeginPosition(children) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>)
+  Line 178) Collections.reverse(children) ==> java.util.Collections.reverse(java.util.List<? extends java.lang.Object>)
+  Line 181) attributeLineCommentToNodeOrChild(child, lineComment) ==> com.github.javaparser.CommentsInserter.attributeLineCommentToNodeOrChild(com.github.javaparser.ast.Node, com.github.javaparser.ast.comments.LineComment)
+  Line 191) PositionUtils.areInOrder(a, b) ==> com.github.javaparser.utils.PositionUtils.areInOrder(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node)
+  Line 192) thereAreLinesBetween(b, a) ==> com.github.javaparser.CommentsInserter.thereAreLinesBetween(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node)
+  Line 194) a.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 195) b.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_JavaParser.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_JavaParser.txt
new file mode 100644
index 0000000..beda6f7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_JavaParser.txt
@@ -0,0 +1,49 @@
+  Line 73) astParser.ReInit(provider) ==> com.github.javaparser.ASTParser.ReInit(com.github.javaparser.Provider)
+  Line 90) getParserForProvider(provider) ==> com.github.javaparser.JavaParser.getParserForProvider(com.github.javaparser.Provider)
+  Line 91) start.parse(parser) ==> com.github.javaparser.ParseStart.parse(com.github.javaparser.ASTParser)
+  Line 92) astParser.getCommentsCollection() ==> com.github.javaparser.ASTParser.getCommentsCollection()
+  Line 93) commentsInserter.insertComments(resultNode, comments.copy().getComments()) ==> com.github.javaparser.CommentsInserter.insertComments(com.github.javaparser.ast.Node, java.util.TreeSet<com.github.javaparser.ast.comments.Comment>)
+  Line 93) comments.copy().getComments() ==> com.github.javaparser.ast.comments.CommentsCollection.getComments()
+  Line 93) comments.copy() ==> com.github.javaparser.ast.comments.CommentsCollection.copy()
+  Line 95) Optional.of(resultNode) ==> java.util.Optional.of(T)
+  Line 95) Optional.of(astParser.getTokens()) ==> java.util.Optional.of(T)
+  Line 95) astParser.getTokens() ==> com.github.javaparser.ASTParser.getTokens()
+  Line 95) Optional.of(astParser.getCommentsCollection()) ==> java.util.Optional.of(T)
+  Line 95) astParser.getCommentsCollection() ==> com.github.javaparser.ASTParser.getCommentsCollection()
+  Line 102) provider.close() ==> com.github.javaparser.Provider.close()
+  Line 119) simplifiedParse(COMPILATION_UNIT, provider(in, encoding)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 119) provider(in, encoding) ==> com.github.javaparser.Providers.provider(java.io.InputStream, java.nio.charset.Charset)
+  Line 132) parse(in, UTF8) ==> com.github.javaparser.JavaParser.parse(java.io.InputStream, java.nio.charset.Charset)
+  Line 146) simplifiedParse(COMPILATION_UNIT, provider(file, encoding)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 146) provider(file, encoding) ==> com.github.javaparser.Providers.provider(java.io.File, java.nio.charset.Charset)
+  Line 160) simplifiedParse(COMPILATION_UNIT, provider(file)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 160) provider(file) ==> com.github.javaparser.Providers.provider(java.io.File)
+  Line 174) simplifiedParse(COMPILATION_UNIT, provider(path, encoding)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 174) provider(path, encoding) ==> com.github.javaparser.Providers.provider(java.nio.file.Path, java.nio.charset.Charset)
+  Line 188) simplifiedParse(COMPILATION_UNIT, provider(path)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 188) provider(path) ==> com.github.javaparser.Providers.provider(java.nio.file.Path)
+  Line 200) simplifiedParse(COMPILATION_UNIT, provider(reader)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 200) provider(reader) ==> com.github.javaparser.Providers.provider(java.io.Reader)
+  Line 212) simplifiedParse(COMPILATION_UNIT, provider(code)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 212) provider(code) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 224) simplifiedParse(BLOCK, provider(blockStatement)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 224) provider(blockStatement) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 236) simplifiedParse(STATEMENT, provider(statement)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 236) provider(statement) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 240) new JavaParser(new ParserConfiguration()).parse(context, provider) ==> com.github.javaparser.JavaParser.parse(com.github.javaparser.ParseStart<N>, com.github.javaparser.Provider)
+  Line 241) result.isSuccessful() ==> com.github.javaparser.ParseResult.isSuccessful()
+  Line 242) result.getResult().get() ==> java.util.Optional.get()
+  Line 242) result.getResult() ==> com.github.javaparser.ParseResult.getResult()
+  Line 244) result.getProblems() ==> com.github.javaparser.ParseResult.getProblems()
+  Line 256) simplifiedParse(IMPORT_DECLARATION, provider(importDeclaration)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 256) provider(importDeclaration) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 268) simplifiedParse(EXPRESSION, provider(expression)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 268) provider(expression) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 280) simplifiedParse(ANNOTATION, provider(annotation)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 280) provider(annotation) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 292) simplifiedParse(ANNOTATION_BODY, provider(body)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 292) provider(body) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 304) simplifiedParse(CLASS_BODY, provider(body)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 304) provider(body) ==> com.github.javaparser.Providers.provider(java.lang.String)
+  Line 316) simplifiedParse(INTERFACE_BODY, provider(body)) ==> com.github.javaparser.JavaParser.simplifiedParse(com.github.javaparser.ParseStart<T>, com.github.javaparser.Provider)
+  Line 316) provider(body) ==> com.github.javaparser.Providers.provider(java.lang.String)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseProblemException.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseProblemException.txt
new file mode 100644
index 0000000..45f56b6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseProblemException.txt
@@ -0,0 +1,10 @@
+  Line 21) createMessage(assertNotNull(problems)) ==> com.github.javaparser.ParseProblemException.createMessage(java.util.List<com.github.javaparser.Problem>)
+  Line 21) assertNotNull(problems) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 26) singletonList(new Problem(throwable.getMessage(), Optional.empty(), Optional.of(throwable))) ==> java.util.Collections.singletonList(T)
+  Line 26) throwable.getMessage() ==> java.lang.Throwable.getMessage()
+  Line 26) Optional.empty() ==> java.util.Optional.empty()
+  Line 26) Optional.of(throwable) ==> java.util.Optional.of(T)
+  Line 32) message.append(problem.toString()).append(EOL) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 32) message.append(problem.toString()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 32) problem.toString() ==> com.github.javaparser.Problem.toString()
+  Line 34) message.toString() ==> java.lang.StringBuilder.toString()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseResult.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseResult.txt
new file mode 100644
index 0000000..726ad56
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseResult.txt
@@ -0,0 +1,19 @@
+  Line 29) assertNotNull(commentsCollection) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 30) assertNotNull(result) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 31) assertNotNull(problems) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 32) assertNotNull(tokens) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 39) Optional.empty() ==> java.util.Optional.empty()
+  Line 39) singletonList(new Problem(throwable.getMessage(), Optional.empty(), Optional.of(throwable))) ==> java.util.Collections.singletonList(T)
+  Line 39) throwable.getMessage() ==> java.lang.Throwable.getMessage()
+  Line 39) Optional.empty() ==> java.util.Optional.empty()
+  Line 39) Optional.of(throwable) ==> java.util.Optional.of(T)
+  Line 39) Optional.empty() ==> java.util.Optional.empty()
+  Line 39) Optional.empty() ==> java.util.Optional.empty()
+  Line 46) problems.isEmpty() ==> java.util.List.isEmpty()
+  Line 46) result.isPresent() ==> java.util.Optional.isPresent()
+  Line 79) isSuccessful() ==> com.github.javaparser.ParseResult.isSuccessful()
+  Line 82) new StringBuilder("Parsing failed:").append(EOL) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 84) message.append(problem.toString()).append(EOL) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 84) message.append(problem.toString()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 84) problem.toString() ==> com.github.javaparser.Problem.toString()
+  Line 86) message.toString() ==> java.lang.StringBuilder.toString()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseStart.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseStart.txt
new file mode 100644
index 0000000..ea6800d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParseStart.txt
@@ -0,0 +1,2 @@
+  Line 28) p.ClassOrInterfaceBodyDeclaration(false) ==> com.github.javaparser.ASTParser.ClassOrInterfaceBodyDeclaration(boolean)
+  Line 29) p.ClassOrInterfaceBodyDeclaration(true) ==> com.github.javaparser.ASTParser.ClassOrInterfaceBodyDeclaration(boolean)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParserConfiguration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParserConfiguration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ParserConfiguration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Position.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Position.txt
new file mode 100644
index 0000000..e07e79e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Position.txt
@@ -0,0 +1,9 @@
+  Line 78) valid() ==> com.github.javaparser.Position.valid()
+  Line 82) valid() ==> com.github.javaparser.Position.valid()
+  Line 89) assertNotNull(position) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 101) assertNotNull(position) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 113) assertNotNull(o) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 114) isBefore(o) ==> com.github.javaparser.Position.isBefore(com.github.javaparser.Position)
+  Line 117) isAfter(o) ==> com.github.javaparser.Position.isAfter(com.github.javaparser.Position)
+  Line 126) getClass() ==> java.lang.Object.getClass()
+  Line 126) o.getClass() ==> java.lang.Object.getClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Problem.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Problem.txt
new file mode 100644
index 0000000..a3d24ee
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Problem.txt
@@ -0,0 +1,7 @@
+  Line 16) assertNotNull(message) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 17) assertNotNull(range) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 18) assertNotNull(cause) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 24) range.ifPresent(r -> str.append(" ").append(r)) ==> java.util.Optional.ifPresent(java.util.function.Consumer<? super T>)
+  Line 24) str.append(" ").append(r) ==> java.lang.StringBuilder.append(java.lang.Object)
+  Line 24) str.append(" ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 25) str.toString() ==> java.lang.StringBuilder.toString()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Providers.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Providers.txt
new file mode 100644
index 0000000..1376d31
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Providers.txt
@@ -0,0 +1,18 @@
+  Line 16) Charset.forName("utf-8") ==> java.nio.charset.Charset.forName(java.lang.String)
+  Line 22) assertNotNull(reader) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 26) assertNotNull(input) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 27) assertNotNull(encoding) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 29) encoding.name() ==> java.nio.charset.Charset.name()
+  Line 38) provider(input, UTF8) ==> com.github.javaparser.Providers.provider(java.io.InputStream, java.nio.charset.Charset)
+  Line 42) provider(new FileInputStream(assertNotNull(file)), assertNotNull(encoding)) ==> com.github.javaparser.Providers.provider(java.io.InputStream, java.nio.charset.Charset)
+  Line 42) assertNotNull(file) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 42) assertNotNull(encoding) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 46) provider(assertNotNull(file), UTF8) ==> com.github.javaparser.Providers.provider(java.io.File, java.nio.charset.Charset)
+  Line 46) assertNotNull(file) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 50) provider(Files.newInputStream(assertNotNull(path)), assertNotNull(encoding)) ==> com.github.javaparser.Providers.provider(java.io.InputStream, java.nio.charset.Charset)
+  Line 50) Files.newInputStream(assertNotNull(path)) ==> java.nio.file.Files.newInputStream(java.nio.file.Path, java.nio.file.OpenOption...)
+  Line 50) assertNotNull(path) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 50) assertNotNull(encoding) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 54) provider(assertNotNull(path), UTF8) ==> com.github.javaparser.Providers.provider(java.nio.file.Path, java.nio.charset.Charset)
+  Line 54) assertNotNull(path) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
+  Line 58) assertNotNull(source) ==> com.github.javaparser.utils.Utils.assertNotNull(T)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Range.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Range.txt
new file mode 100644
index 0000000..4a15476
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_Range.txt
@@ -0,0 +1,23 @@
+  Line 9) range(Position.UNKNOWN, Position.UNKNOWN) ==> com.github.javaparser.Range.range(com.github.javaparser.Position, com.github.javaparser.Position)
+  Line 30) pos(beginLine, beginColumn) ==> com.github.javaparser.Position.pos(int, int)
+  Line 30) pos(endLine, endColumn) ==> com.github.javaparser.Position.pos(int, int)
+  Line 34) range(begin.withColumn(column), end) ==> com.github.javaparser.Range.range(com.github.javaparser.Position, com.github.javaparser.Position)
+  Line 34) begin.withColumn(column) ==> com.github.javaparser.Position.withColumn(int)
+  Line 38) range(begin.withLine(line), end) ==> com.github.javaparser.Range.range(com.github.javaparser.Position, com.github.javaparser.Position)
+  Line 38) begin.withLine(line) ==> com.github.javaparser.Position.withLine(int)
+  Line 42) range(begin, end.withColumn(column)) ==> com.github.javaparser.Range.range(com.github.javaparser.Position, com.github.javaparser.Position)
+  Line 42) end.withColumn(column) ==> com.github.javaparser.Position.withColumn(int)
+  Line 46) range(begin, end.withLine(line)) ==> com.github.javaparser.Range.range(com.github.javaparser.Position, com.github.javaparser.Position)
+  Line 46) end.withLine(line) ==> com.github.javaparser.Position.withLine(int)
+  Line 50) range(begin, this.end) ==> com.github.javaparser.Range.range(com.github.javaparser.Position, com.github.javaparser.Position)
+  Line 54) range(this.begin, end) ==> com.github.javaparser.Range.range(com.github.javaparser.Position, com.github.javaparser.Position)
+  Line 58) begin.isBefore(other.begin) ==> com.github.javaparser.Position.isBefore(com.github.javaparser.Position)
+  Line 58) end.isAfter(other.end) ==> com.github.javaparser.Position.isAfter(com.github.javaparser.Position)
+  Line 62) end.isBefore(position) ==> com.github.javaparser.Position.isBefore(com.github.javaparser.Position)
+  Line 66) begin.isAfter(position) ==> com.github.javaparser.Position.isAfter(com.github.javaparser.Position)
+  Line 72) getClass() ==> java.lang.Object.getClass()
+  Line 72) o.getClass() ==> java.lang.Object.getClass()
+  Line 76) begin.equals(range.begin) ==> com.github.javaparser.Position.equals(java.lang.Object)
+  Line 76) end.equals(range.end) ==> com.github.javaparser.Position.equals(java.lang.Object)
+  Line 82) begin.hashCode() ==> com.github.javaparser.Position.hashCode()
+  Line 82) end.hashCode() ==> com.github.javaparser.Position.hashCode()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_AccessSpecifier.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_AccessSpecifier.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_AccessSpecifier.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ArrayBracketPair.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ArrayBracketPair.txt
new file mode 100644
index 0000000..429ac17
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ArrayBracketPair.txt
@@ -0,0 +1,5 @@
+  Line 23) setAnnotations(annotations) ==> com.github.javaparser.ast.ArrayBracketPair.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 27) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.ArrayBracketPair, A)
+  Line 31) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.ArrayBracketPair, A)
+  Line 35) ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 40) setAsParentNodeOf(annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ArrayCreationLevel.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ArrayCreationLevel.txt
new file mode 100644
index 0000000..f096ed0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ArrayCreationLevel.txt
@@ -0,0 +1,7 @@
+  Line 25) setDimension(dimension) ==> com.github.javaparser.ast.ArrayCreationLevel.setDimension(com.github.javaparser.ast.expr.Expression)
+  Line 26) setAnnotations(annotations) ==> com.github.javaparser.ast.ArrayCreationLevel.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 30) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.ArrayCreationLevel, A)
+  Line 34) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.ArrayCreationLevel, A)
+  Line 39) setAsParentNodeOf(dimension) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 47) ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 52) setAsParentNodeOf(annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_CompilationUnit.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_CompilationUnit.txt
new file mode 100644
index 0000000..eb74121
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_CompilationUnit.txt
@@ -0,0 +1,103 @@
+  Line 79) setPackage(pakage) ==> com.github.javaparser.ast.CompilationUnit.setPackage(com.github.javaparser.ast.PackageDeclaration)
+  Line 80) setImports(imports) ==> com.github.javaparser.ast.CompilationUnit.setImports(java.util.List<com.github.javaparser.ast.ImportDeclaration>)
+  Line 81) setTypes(types) ==> com.github.javaparser.ast.CompilationUnit.setTypes(java.util.List<com.github.javaparser.ast.body.TypeDeclaration<?>>)
+  Line 87) setPackage(pakage) ==> com.github.javaparser.ast.CompilationUnit.setPackage(com.github.javaparser.ast.PackageDeclaration)
+  Line 88) setImports(imports) ==> com.github.javaparser.ast.CompilationUnit.setImports(java.util.List<com.github.javaparser.ast.ImportDeclaration>)
+  Line 89) setTypes(types) ==> com.github.javaparser.ast.CompilationUnit.setTypes(java.util.List<com.github.javaparser.ast.body.TypeDeclaration<?>>)
+  Line 94) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.CompilationUnit, A)
+  Line 99) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.CompilationUnit, A)
+  Line 115) this.getAllContainedComments() ==> com.github.javaparser.ast.Node.getAllContainedComments()
+  Line 125) ensureNotNull(imports) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 151) ensureNotNull(types) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 174) setAsParentNodeOf(this.imports) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 187) setAsParentNodeOf(this.pakage) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 199) setAsParentNodeOf(this.types) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 210) setPackage(new PackageDeclaration(name(name))) ==> com.github.javaparser.ast.CompilationUnit.setPackage(com.github.javaparser.ast.PackageDeclaration)
+  Line 210) name(name) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 222) addImport(name, false, false) ==> com.github.javaparser.ast.CompilationUnit.addImport(java.lang.String, boolean, boolean)
+  Line 233) ClassUtils.isPrimitiveOrWrapper(clazz) ==> com.github.javaparser.utils.ClassUtils.isPrimitiveOrWrapper(java.lang.Class<?>)
+  Line 233) clazz.getName().startsWith("java.lang") ==> java.lang.String.startsWith(java.lang.String)
+  Line 233) clazz.getName() ==> java.lang.Class.getName()
+  Line 235) clazz.isArray() ==> java.lang.Class.isArray()
+  Line 235) ClassUtils.isPrimitiveOrWrapper(clazz.getComponentType()) ==> com.github.javaparser.utils.ClassUtils.isPrimitiveOrWrapper(java.lang.Class<?>)
+  Line 235) clazz.getComponentType() ==> java.lang.Class.getComponentType()
+  Line 236) clazz.getComponentType().getName().startsWith("java.lang") ==> java.lang.String.startsWith(java.lang.String)
+  Line 236) clazz.getComponentType().getName() ==> java.lang.Class.getName()
+  Line 236) clazz.getComponentType() ==> java.lang.Class.getComponentType()
+  Line 237) addImport(clazz.getComponentType().getName()) ==> com.github.javaparser.ast.CompilationUnit.addImport(java.lang.String)
+  Line 237) clazz.getComponentType().getName() ==> java.lang.Class.getName()
+  Line 237) clazz.getComponentType() ==> java.lang.Class.getComponentType()
+  Line 238) addImport(clazz.getName()) ==> com.github.javaparser.ast.CompilationUnit.addImport(java.lang.String)
+  Line 238) clazz.getName() ==> java.lang.Class.getName()
+  Line 251) getImports().stream().anyMatch(i -> i.getName().toString().equals(name)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 251) getImports().stream() ==> java.util.Collection.stream()
+  Line 251) getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 251) i.getName().toString().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 251) i.getName().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 251) i.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 254) name(name) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 256) getImports().add(importDeclaration) ==> java.util.List.add(E)
+  Line 256) getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 257) importDeclaration.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 269) addClass(name, Modifier.PUBLIC) ==> com.github.javaparser.ast.CompilationUnit.addClass(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 281) Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 281) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 282) Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 282) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 284) getTypes().add(classOrInterfaceDeclaration) ==> java.util.List.add(E)
+  Line 284) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 285) classOrInterfaceDeclaration.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 296) addInterface(name, Modifier.PUBLIC) ==> com.github.javaparser.ast.CompilationUnit.addInterface(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 308) Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 308) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 309) Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 309) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 311) getTypes().add(classOrInterfaceDeclaration) ==> java.util.List.add(E)
+  Line 311) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 312) classOrInterfaceDeclaration.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 323) addEnum(name, Modifier.PUBLIC) ==> com.github.javaparser.ast.CompilationUnit.addEnum(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 334) Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 334) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 335) Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 335) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 336) getTypes().add(enumDeclaration) ==> java.util.List.add(E)
+  Line 336) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 337) enumDeclaration.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 348) addAnnotationDeclaration(name, Modifier.PUBLIC) ==> com.github.javaparser.ast.CompilationUnit.addAnnotationDeclaration(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 359) Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 359) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 360) Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 360) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 361) getTypes().add(annotationDeclaration) ==> java.util.List.add(E)
+  Line 361) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 362) annotationDeclaration.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 373) getTypes().stream().filter(type -> type.getName().equals(className) && type instanceof ClassOrInterfaceDeclaration && !((ClassOrInterfaceDeclaration) type).isInterface()).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 373) getTypes().stream().filter(type -> type.getName().equals(className) && type instanceof ClassOrInterfaceDeclaration && !((ClassOrInterfaceDeclaration) type).isInterface()).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 373) getTypes().stream().filter(type -> type.getName().equals(className) && type instanceof ClassOrInterfaceDeclaration && !((ClassOrInterfaceDeclaration) type).isInterface()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 373) getTypes().stream() ==> java.util.Collection.stream()
+  Line 373) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 373) type.getName().equals(className) ==> java.lang.String.equals(java.lang.Object)
+  Line 373) type.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 374) ((ClassOrInterfaceDeclaration) type).isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 385) getTypes().stream().filter(type -> type.getName().equals(interfaceName) && type instanceof ClassOrInterfaceDeclaration && ((ClassOrInterfaceDeclaration) type).isInterface()).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 385) getTypes().stream().filter(type -> type.getName().equals(interfaceName) && type instanceof ClassOrInterfaceDeclaration && ((ClassOrInterfaceDeclaration) type).isInterface()).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 385) getTypes().stream().filter(type -> type.getName().equals(interfaceName) && type instanceof ClassOrInterfaceDeclaration && ((ClassOrInterfaceDeclaration) type).isInterface()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 385) getTypes().stream() ==> java.util.Collection.stream()
+  Line 385) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 385) type.getName().equals(interfaceName) ==> java.lang.String.equals(java.lang.Object)
+  Line 385) type.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 386) ((ClassOrInterfaceDeclaration) type).isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 397) getTypes().stream().filter(type -> type.getName().equals(enumName) && type instanceof EnumDeclaration).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 397) getTypes().stream().filter(type -> type.getName().equals(enumName) && type instanceof EnumDeclaration).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 397) getTypes().stream().filter(type -> type.getName().equals(enumName) && type instanceof EnumDeclaration) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 397) getTypes().stream() ==> java.util.Collection.stream()
+  Line 397) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 397) type.getName().equals(enumName) ==> java.lang.String.equals(java.lang.Object)
+  Line 397) type.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 409) getTypes().stream().filter(type -> type.getName().equals(annotationName) && type instanceof AnnotationDeclaration).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 409) getTypes().stream().filter(type -> type.getName().equals(annotationName) && type instanceof AnnotationDeclaration).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 409) getTypes().stream().filter(type -> type.getName().equals(annotationName) && type instanceof AnnotationDeclaration) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 409) getTypes().stream() ==> java.util.Collection.stream()
+  Line 409) getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 409) type.getName().equals(annotationName) ==> java.lang.String.equals(java.lang.Object)
+  Line 409) type.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Example.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Example.txt
new file mode 100644
index 0000000..81c2b22
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Example.txt
@@ -0,0 +1,2 @@
+  Line 26) code.getBytes("UTF-8") ==> java.lang.String.getBytes(java.lang.String)
+  Line 27) JavaParser.parse(stream) ==> com.github.javaparser.JavaParser.parse(java.io.InputStream)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ImportDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ImportDeclaration.txt
new file mode 100644
index 0000000..8b3dfa4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_ImportDeclaration.txt
@@ -0,0 +1,9 @@
+  Line 78) setAsterisk(isAsterisk) ==> com.github.javaparser.ast.ImportDeclaration.setAsterisk(boolean)
+  Line 79) setName(name) ==> com.github.javaparser.ast.ImportDeclaration.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 80) setStatic(isStatic) ==> com.github.javaparser.ast.ImportDeclaration.setStatic(boolean)
+  Line 86) setAsterisk(isAsterisk) ==> com.github.javaparser.ast.ImportDeclaration.setAsterisk(boolean)
+  Line 87) setName(name) ==> com.github.javaparser.ast.ImportDeclaration.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 88) setStatic(isStatic) ==> com.github.javaparser.ast.ImportDeclaration.setStatic(boolean)
+  Line 101) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.ImportDeclaration, A)
+  Line 106) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.ImportDeclaration, A)
+  Line 169) setAsParentNodeOf(this.name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Modifier.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Modifier.txt
new file mode 100644
index 0000000..87fedea
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Modifier.txt
@@ -0,0 +1,4 @@
+  Line 32) EnumSet.of(this) ==> java.util.EnumSet.of(E)
+  Line 36) modifiers.contains(Modifier.PUBLIC) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 38) modifiers.contains(Modifier.PROTECTED) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 40) modifiers.contains(Modifier.PRIVATE) ==> java.util.AbstractCollection.contains(java.lang.Object)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Modifier_J9.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Modifier_J9.txt
new file mode 100644
index 0000000..c17b5bf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Modifier_J9.txt
@@ -0,0 +1,4 @@
+  Line 32) EnumSet.of(this) ==> java.util.Set.of(E...)
+  Line 36) modifiers.contains(Modifier.PUBLIC) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 38) modifiers.contains(Modifier.PROTECTED) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 40) modifiers.contains(Modifier.PRIVATE) ==> java.util.AbstractCollection.contains(java.lang.Object)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Node.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Node.txt
new file mode 100644
index 0000000..4ca45ef
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_Node.txt
@@ -0,0 +1,46 @@
+  Line 46) a.getBegin().compareTo(b.getBegin()) ==> com.github.javaparser.Position.compareTo(com.github.javaparser.Position)
+  Line 46) a.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 46) b.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 121) range.withBegin(begin) ==> com.github.javaparser.Range.withBegin(com.github.javaparser.Position)
+  Line 129) range.withEnd(end) ==> com.github.javaparser.Range.withEnd(com.github.javaparser.Position)
+  Line 158) this.comment.setCommentedNode(null) ==> com.github.javaparser.ast.comments.Comment.setCommentedNode(com.github.javaparser.ast.Node)
+  Line 162) this.comment.setCommentedNode(this) ==> com.github.javaparser.ast.comments.Comment.setCommentedNode(com.github.javaparser.ast.Node)
+  Line 175) setComment(new LineComment(comment)) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 184) setComment(new BlockComment(comment)) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 195) accept(visitor, null) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 196) visitor.getSource() ==> com.github.javaparser.ast.visitor.DumpVisitor.getSource()
+  Line 201) accept(visitor, null) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 202) visitor.getSource() ==> com.github.javaparser.ast.visitor.DumpVisitor.getSource()
+  Line 207) toString().hashCode() ==> java.lang.String.hashCode()
+  Line 207) toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 215) EqualsVisitor.equals(this, (Node) obj) ==> com.github.javaparser.ast.visitor.EqualsVisitor.equals(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node)
+  Line 220) this.accept(new CloneVisitor(), null) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 231) classType.isAssignableFrom(parent.getClass()) ==> java.lang.Class.isAssignableFrom(java.lang.Class<? extends java.lang.Object>)
+  Line 231) parent.getClass() ==> java.lang.Object.getClass()
+  Line 243) range.contains(other.range) ==> com.github.javaparser.Range.contains(com.github.javaparser.Range)
+  Line 247) orphanComments.add(comment) ==> java.util.List.add(E)
+  Line 248) comment.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 276) comments.addAll(getOrphanComments()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 276) getOrphanComments() ==> com.github.javaparser.ast.Node.getOrphanComments()
+  Line 278) getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 279) child.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 280) comments.add(child.getComment()) ==> java.util.List.add(E)
+  Line 280) child.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 282) comments.addAll(child.getAllContainedComments()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 282) child.getAllContainedComments() ==> com.github.javaparser.ast.Node.getAllContainedComments()
+  Line 297) this.parentNode.childrenNodes.remove(this) ==> java.util.List.remove(java.lang.Object)
+  Line 302) this.parentNode.childrenNodes.add(this) ==> java.util.List.add(E)
+  Line 309) current.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 316) childNode.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 324) range.isAfter(position) ==> com.github.javaparser.Range.isAfter(com.github.javaparser.Position)
+  Line 328) range.isBefore(position) ==> com.github.javaparser.Range.isBefore(com.github.javaparser.Position)
+  Line 336) getParentNodeOfType(CompilationUnit.class) ==> com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)
+  Line 338) parentNode.addImport(clazz) ==> com.github.javaparser.ast.CompilationUnit.addImport(java.lang.Class<?>)
+  Line 349) getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 350) clazz.isInstance(child) ==> java.lang.Class.isInstance(java.lang.Object)
+  Line 351) nodes.add(clazz.cast(child)) ==> java.util.List.add(E)
+  Line 351) clazz.cast(child) ==> java.lang.Class.cast(java.lang.Object)
+  Line 353) nodes.addAll(child.getNodesByType(clazz)) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 353) child.getNodesByType(clazz) ==> com.github.javaparser.ast.Node.getNodesByType(java.lang.Class<N>)
+  Line 373) userData.get(key) ==> java.util.IdentityHashMap.get(java.lang.Object)
+  Line 394) userData.put(key, object) ==> java.util.IdentityHashMap.put(K, V)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_PackageDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_PackageDeclaration.txt
new file mode 100644
index 0000000..1c72dc6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_PackageDeclaration.txt
@@ -0,0 +1,11 @@
+  Line 57) setName(name) ==> com.github.javaparser.ast.PackageDeclaration.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 61) setAnnotations(annotations) ==> com.github.javaparser.ast.PackageDeclaration.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 62) setName(name) ==> com.github.javaparser.ast.PackageDeclaration.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 67) setAnnotations(annotations) ==> com.github.javaparser.ast.PackageDeclaration.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 68) setName(name) ==> com.github.javaparser.ast.PackageDeclaration.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 73) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.PackageDeclaration, A)
+  Line 78) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.PackageDeclaration, A)
+  Line 88) Utils.ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 105) name.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 114) setAsParentNodeOf(this.annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 126) setAsParentNodeOf(this.name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_UserDataKey.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_UserDataKey.txt
new file mode 100644
index 0000000..b3f6df7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_UserDataKey.txt
@@ -0,0 +1,5 @@
+  Line 28) getClass().hashCode() ==> java.lang.Object.hashCode()
+  Line 28) getClass() ==> java.lang.Object.getClass()
+  Line 37) getClass().equals(obj.getClass()) ==> java.lang.Object.equals(java.lang.Object)
+  Line 37) getClass() ==> java.lang.Object.getClass()
+  Line 37) obj.getClass() ==> java.lang.Object.getClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_AnnotationDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_AnnotationDeclaration.txt
new file mode 100644
index 0000000..b04655d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_AnnotationDeclaration.txt
@@ -0,0 +1,2 @@
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.AnnotationDeclaration, A)
+  Line 63) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.AnnotationDeclaration, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_AnnotationMemberDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_AnnotationMemberDeclaration.txt
new file mode 100644
index 0000000..d32463f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_AnnotationMemberDeclaration.txt
@@ -0,0 +1,19 @@
+  Line 47) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 59) setModifiers(modifiers) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 60) setType(type) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setType(com.github.javaparser.ast.type.Type)
+  Line 61) setName(name) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setName(java.lang.String)
+  Line 62) setDefaultValue(defaultValue) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setDefaultValue(com.github.javaparser.ast.expr.Expression)
+  Line 68) setModifiers(modifiers) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 69) setType(type) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setType(com.github.javaparser.ast.type.Type)
+  Line 70) setName(name) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setName(java.lang.String)
+  Line 71) setDefaultValue(defaultValue) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setDefaultValue(com.github.javaparser.ast.expr.Expression)
+  Line 77) setModifiers(modifiers) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 78) setType(type) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setType(com.github.javaparser.ast.type.Type)
+  Line 79) setName(name) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setName(java.lang.String)
+  Line 80) setDefaultValue(defaultValue) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setDefaultValue(com.github.javaparser.ast.expr.Expression)
+  Line 85) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.AnnotationMemberDeclaration, A)
+  Line 90) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.AnnotationMemberDeclaration, A)
+  Line 120) setAsParentNodeOf(defaultValue) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 139) setAsParentNodeOf(type) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 145) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 146) getComment() ==> com.github.javaparser.ast.Node.getComment()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_BodyDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_BodyDeclaration.txt
new file mode 100644
index 0000000..7460575
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_BodyDeclaration.txt
@@ -0,0 +1,4 @@
+  Line 43) setAnnotations(annotations) ==> com.github.javaparser.ast.body.BodyDeclaration.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 48) setAnnotations(annotations) ==> com.github.javaparser.ast.body.BodyDeclaration.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 53) Utils.ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 66) setAsParentNodeOf(this.annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_ClassOrInterfaceDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_ClassOrInterfaceDeclaration.txt
new file mode 100644
index 0000000..13c8f5c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_ClassOrInterfaceDeclaration.txt
@@ -0,0 +1,17 @@
+  Line 60) setInterface(isInterface) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setInterface(boolean)
+  Line 71) setInterface(isInterface) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setInterface(boolean)
+  Line 72) setTypeParameters(typeParameters) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)
+  Line 73) setExtends(extendsList) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setExtends(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 74) setImplements(implementsList) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setImplements(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 85) setInterface(isInterface) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setInterface(boolean)
+  Line 86) setTypeParameters(typeParameters) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)
+  Line 87) setExtends(extendsList) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setExtends(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 88) setImplements(implementsList) ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.setImplements(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 93) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration, A)
+  Line 98) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration, A)
+  Line 102) ensureNotNull(extendsList) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 108) ensureNotNull(implementsList) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 113) ensureNotNull(typeParameters) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 130) setAsParentNodeOf(this.extendsList) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 142) setAsParentNodeOf(this.implementsList) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 158) setAsParentNodeOf(this.typeParameters) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_ConstructorDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_ConstructorDeclaration.txt
new file mode 100644
index 0000000..2fdf81c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_ConstructorDeclaration.txt
@@ -0,0 +1,53 @@
+  Line 51) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 67) setModifiers(modifiers) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 68) setName(name) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)
+  Line 76) setModifiers(modifiers) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 77) setTypeParameters(typeParameters) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)
+  Line 78) setName(name) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)
+  Line 79) setParameters(parameters) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)
+  Line 80) setThrows(throws_) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 81) setBody(block) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 88) setModifiers(modifiers) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 89) setTypeParameters(typeParameters) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)
+  Line 90) setName(name) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)
+  Line 91) setParameters(parameters) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)
+  Line 92) setThrows(throws_) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 93) setBody(block) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 98) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.ConstructorDeclaration, A)
+  Line 103) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.ConstructorDeclaration, A)
+  Line 119) name.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 128) ensureNotNull(parameters) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 134) ensureNotNull(throws_) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 139) ensureNotNull(typeParameters) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 151) setNameExpr(new NameExpr(name)) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)
+  Line 157) setAsParentNodeOf(this.name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 164) setAsParentNodeOf(this.parameters) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 171) setAsParentNodeOf(this.throws_) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 177) setAsParentNodeOf(this.typeParameters) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 192) Modifier.getAccessSpecifier(getModifiers()) ==> com.github.javaparser.ast.Modifier.getAccessSpecifier(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 192) getModifiers() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()
+  Line 193) sb.append(accessSpecifier.getCodeRepresenation()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 193) accessSpecifier.getCodeRepresenation() ==> com.github.javaparser.ast.AccessSpecifier.getCodeRepresenation()
+  Line 194) sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 196) sb.append(getName()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 196) getName() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getName()
+  Line 197) sb.append("(") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 199) getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 203) sb.append(", ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 206) sb.append(param.toStringWithoutComments()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 206) param.toStringWithoutComments() ==> com.github.javaparser.ast.Node.toStringWithoutComments()
+  Line 208) sb.append(param.getElementType().toStringWithoutComments()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 208) param.getElementType().toStringWithoutComments() ==> com.github.javaparser.ast.Node.toStringWithoutComments()
+  Line 208) param.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 211) sb.append(")") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 214) getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 217) sb.append(" throws ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 219) sb.append(", ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 221) sb.append(thr.toStringWithoutComments()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 221) thr.toStringWithoutComments() ==> com.github.javaparser.ast.Node.toStringWithoutComments()
+  Line 224) sb.toString() ==> java.lang.StringBuilder.toString()
+  Line 229) getDeclarationAsString(includingModifiers, includingThrows, true) ==> com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)
+  Line 234) getDeclarationAsString(true, true, true) ==> com.github.javaparser.ast.body.ConstructorDeclaration.getDeclarationAsString(boolean, boolean, boolean)
+  Line 239) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 240) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 253) setAsParentNodeOf(body) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EmptyMemberDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EmptyMemberDeclaration.txt
new file mode 100644
index 0000000..341d9fb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EmptyMemberDeclaration.txt
@@ -0,0 +1,4 @@
+  Line 46) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.EmptyMemberDeclaration, A)
+  Line 51) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.EmptyMemberDeclaration, A)
+  Line 56) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 57) getComment() ==> com.github.javaparser.ast.Node.getComment()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EmptyTypeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EmptyTypeDeclaration.txt
new file mode 100644
index 0000000..1218195
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EmptyTypeDeclaration.txt
@@ -0,0 +1,4 @@
+  Line 37) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 41) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 46) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.EmptyTypeDeclaration, A)
+  Line 51) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.EmptyTypeDeclaration, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EnumConstantDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EnumConstantDeclaration.txt
new file mode 100644
index 0000000..aee75d7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EnumConstantDeclaration.txt
@@ -0,0 +1,18 @@
+  Line 59) setName(name) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.setName(java.lang.String)
+  Line 65) setName(name) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.setName(java.lang.String)
+  Line 66) setArgs(args) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 67) setClassBody(classBody) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.setClassBody(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>)
+  Line 73) setName(name) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.setName(java.lang.String)
+  Line 74) setArgs(args) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 75) setClassBody(classBody) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.setClassBody(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>)
+  Line 80) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.EnumConstantDeclaration, A)
+  Line 85) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.EnumConstantDeclaration, A)
+  Line 89) ensureNotNull(args) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 94) ensureNotNull(classBody) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 105) setAsParentNodeOf(this.args) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 111) setAsParentNodeOf(this.classBody) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 123) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 124) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 130) getArgs().add(name(valueExpr)) ==> java.util.List.add(E)
+  Line 130) getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 130) name(valueExpr) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EnumDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EnumDeclaration.txt
new file mode 100644
index 0000000..e06afc3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_EnumDeclaration.txt
@@ -0,0 +1,13 @@
+  Line 58) setImplements(implementsList) ==> com.github.javaparser.ast.body.EnumDeclaration.setImplements(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 59) setEntries(entries) ==> com.github.javaparser.ast.body.EnumDeclaration.setEntries(java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>)
+  Line 66) setImplements(implementsList) ==> com.github.javaparser.ast.body.EnumDeclaration.setImplements(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 67) setEntries(entries) ==> com.github.javaparser.ast.body.EnumDeclaration.setEntries(java.util.List<com.github.javaparser.ast.body.EnumConstantDeclaration>)
+  Line 72) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.EnumDeclaration, A)
+  Line 78) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.EnumDeclaration, A)
+  Line 82) ensureNotNull(entries) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 88) ensureNotNull(implementsList) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 94) setAsParentNodeOf(this.entries) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 101) setAsParentNodeOf(this.implementsList) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 109) getEntries().add(enumConstant) ==> java.util.List.add(E)
+  Line 109) getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 110) enumConstant.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_FieldDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_FieldDeclaration.txt
new file mode 100644
index 0000000..234f63a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_FieldDeclaration.txt
@@ -0,0 +1,68 @@
+  Line 58) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 70) setModifiers(modifiers) ==> com.github.javaparser.ast.body.FieldDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 71) setElementType(elementType) ==> com.github.javaparser.ast.body.FieldDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 73) aux.add(variable) ==> java.util.List.add(E)
+  Line 74) setVariables(aux) ==> com.github.javaparser.ast.body.FieldDeclaration.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 78) setModifiers(modifiers) ==> com.github.javaparser.ast.body.FieldDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 79) setElementType(elementType) ==> com.github.javaparser.ast.body.FieldDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 80) setVariables(variables) ==> com.github.javaparser.ast.body.FieldDeclaration.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 86) setModifiers(modifiers) ==> com.github.javaparser.ast.body.FieldDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 87) setElementType(elementType) ==> com.github.javaparser.ast.body.FieldDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 88) setVariables(variables) ==> com.github.javaparser.ast.body.FieldDeclaration.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 89) setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType) ==> com.github.javaparser.ast.body.FieldDeclaration.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 95) setModifiers(modifiers) ==> com.github.javaparser.ast.body.FieldDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 96) setElementType(elementType) ==> com.github.javaparser.ast.body.FieldDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 97) setVariables(variables) ==> com.github.javaparser.ast.body.FieldDeclaration.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 98) setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType) ==> com.github.javaparser.ast.body.FieldDeclaration.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 115) variables.add(variable) ==> java.util.List.add(E)
+  Line 133) create(modifiers, type, variable) ==> com.github.javaparser.ast.body.FieldDeclaration.create(java.util.EnumSet<com.github.javaparser.ast.Modifier>, com.github.javaparser.ast.type.Type, com.github.javaparser.ast.body.VariableDeclarator)
+  Line 138) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.FieldDeclaration, A)
+  Line 143) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.FieldDeclaration, A)
+  Line 159) ensureNotNull(variables) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 172) setAsParentNodeOf(this.variables) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 178) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 179) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 193) getVariables().size() ==> java.util.List.size()
+  Line 193) getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 195) getParentNodeOfType(ClassOrInterfaceDeclaration.class) ==> com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)
+  Line 196) getParentNodeOfType(EnumDeclaration.class) ==> com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)
+  Line 197) parentClass.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 201) getVariables().get(0) ==> java.util.List.get(int)
+  Line 201) getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 202) variable.getId().getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 202) variable.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 203) fieldName.toUpperCase().substring(0, 1) ==> java.lang.String.substring(int, int)
+  Line 203) fieldName.toUpperCase() ==> java.lang.String.toUpperCase()
+  Line 203) fieldName.substring(1, fieldName.length()) ==> java.lang.String.substring(int, int)
+  Line 203) fieldName.length() ==> java.lang.String.length()
+  Line 206) parentClass.addMethod("get" + fieldNameUpper, PUBLIC) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addMethod(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 208) parentEnum.addMethod("get" + fieldNameUpper, PUBLIC) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addMethod(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 209) getter.setType(variable.getType()) ==> com.github.javaparser.ast.body.MethodDeclaration.setType(com.github.javaparser.ast.type.Type)
+  Line 209) variable.getType() ==> com.github.javaparser.ast.body.VariableDeclarator.getType()
+  Line 211) getter.setBody(blockStmt) ==> com.github.javaparser.ast.body.MethodDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 212) blockStmt.addStatement(new ReturnStmt(name(fieldName))) ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.addStatement(com.github.javaparser.ast.stmt.Statement)
+  Line 212) name(fieldName) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 225) getVariables().size() ==> java.util.List.size()
+  Line 225) getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 227) getParentNodeOfType(ClassOrInterfaceDeclaration.class) ==> com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)
+  Line 228) getParentNodeOfType(EnumDeclaration.class) ==> com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)
+  Line 229) parentClass.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 233) getVariables().get(0) ==> java.util.List.get(int)
+  Line 233) getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 234) variable.getId().getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 234) variable.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 235) fieldName.toUpperCase().substring(0, 1) ==> java.lang.String.substring(int, int)
+  Line 235) fieldName.toUpperCase() ==> java.lang.String.toUpperCase()
+  Line 235) fieldName.substring(1, fieldName.length()) ==> java.lang.String.substring(int, int)
+  Line 235) fieldName.length() ==> java.lang.String.length()
+  Line 239) parentClass.addMethod("set" + fieldNameUpper, PUBLIC) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addMethod(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 241) parentEnum.addMethod("set" + fieldNameUpper, PUBLIC) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addMethod(java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 242) setter.setType(VOID_TYPE) ==> com.github.javaparser.ast.body.MethodDeclaration.setType(com.github.javaparser.ast.type.Type)
+  Line 243) setter.getParameters().add(new Parameter(variable.getType(), new VariableDeclaratorId(fieldName))) ==> java.util.List.add(E)
+  Line 243) setter.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 243) variable.getType() ==> com.github.javaparser.ast.body.VariableDeclarator.getType()
+  Line 245) setter.setBody(blockStmt2) ==> com.github.javaparser.ast.body.MethodDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 246) blockStmt2.addStatement(new AssignExpr(new NameExpr("this." + fieldName), new NameExpr(fieldName), Operator.assign)) ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.addStatement(com.github.javaparser.ast.expr.Expression)
+  Line 259) setAsParentNodeOf(this.elementType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 267) ensureNotNull(arrayBracketPairsAfterElementType) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 274) setAsParentNodeOf(arrayBracketPairsAfterType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_InitializerDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_InitializerDeclaration.txt
new file mode 100644
index 0000000..42f3b8e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_InitializerDeclaration.txt
@@ -0,0 +1,9 @@
+  Line 46) setStatic(isStatic) ==> com.github.javaparser.ast.body.InitializerDeclaration.setStatic(boolean)
+  Line 47) setBlock(block) ==> com.github.javaparser.ast.body.InitializerDeclaration.setBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 52) setStatic(isStatic) ==> com.github.javaparser.ast.body.InitializerDeclaration.setStatic(boolean)
+  Line 53) setBlock(block) ==> com.github.javaparser.ast.body.InitializerDeclaration.setBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.InitializerDeclaration, A)
+  Line 63) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.InitializerDeclaration, A)
+  Line 76) setAsParentNodeOf(this.block) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 87) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 88) getComment() ==> com.github.javaparser.ast.Node.getComment()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_MethodDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_MethodDeclaration.txt
new file mode 100644
index 0000000..c36ddc8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_MethodDeclaration.txt
@@ -0,0 +1,98 @@
+  Line 67) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 91) setModifiers(modifiers) ==> com.github.javaparser.ast.body.MethodDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 92) setElementType(elementType) ==> com.github.javaparser.ast.body.MethodDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 93) setName(name) ==> com.github.javaparser.ast.body.MethodDeclaration.setName(java.lang.String)
+  Line 98) setModifiers(modifiers) ==> com.github.javaparser.ast.body.MethodDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 99) setElementType(elementType) ==> com.github.javaparser.ast.body.MethodDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 100) setName(name) ==> com.github.javaparser.ast.body.MethodDeclaration.setName(java.lang.String)
+  Line 101) setParameters(parameters) ==> com.github.javaparser.ast.body.MethodDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)
+  Line 115) setModifiers(modifiers) ==> com.github.javaparser.ast.body.MethodDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 116) setTypeParameters(typeParameters) ==> com.github.javaparser.ast.body.MethodDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)
+  Line 117) setElementType(elementType) ==> com.github.javaparser.ast.body.MethodDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 118) setName(name) ==> com.github.javaparser.ast.body.MethodDeclaration.setName(java.lang.String)
+  Line 119) setParameters(parameters) ==> com.github.javaparser.ast.body.MethodDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)
+  Line 120) setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType) ==> com.github.javaparser.ast.body.MethodDeclaration.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 121) setArrayBracketPairsAfterParameterList(arrayBracketPairsAfterParameterList) ==> com.github.javaparser.ast.body.MethodDeclaration.setArrayBracketPairsAfterParameterList(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 122) setThrows(throws_) ==> com.github.javaparser.ast.body.MethodDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 123) setBody(body) ==> com.github.javaparser.ast.body.MethodDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 138) setModifiers(modifiers) ==> com.github.javaparser.ast.body.MethodDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 139) setTypeParameters(typeParameters) ==> com.github.javaparser.ast.body.MethodDeclaration.setTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>)
+  Line 140) setElementType(elementType) ==> com.github.javaparser.ast.body.MethodDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 141) setNameExpr(nameExpr) ==> com.github.javaparser.ast.body.MethodDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)
+  Line 142) setParameters(parameters) ==> com.github.javaparser.ast.body.MethodDeclaration.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)
+  Line 143) setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType) ==> com.github.javaparser.ast.body.MethodDeclaration.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 144) setArrayBracketPairsAfterParameterList(arrayBracketPairsAfterParameterList) ==> com.github.javaparser.ast.body.MethodDeclaration.setArrayBracketPairsAfterParameterList(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 145) setThrows(throws_) ==> com.github.javaparser.ast.body.MethodDeclaration.setThrows(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 146) setBody(body) ==> com.github.javaparser.ast.body.MethodDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 151) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.MethodDeclaration, A)
+  Line 156) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.MethodDeclaration, A)
+  Line 177) name.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 186) ensureNotNull(parameters) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 192) ensureNotNull(throws_) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 198) wrapInArrayTypes(getElementType(), getArrayBracketPairsAfterElementType(), getArrayBracketPairsAfterParameterList()) ==> com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes(com.github.javaparser.ast.type.Type, java.util.List<com.github.javaparser.ast.ArrayBracketPair>...)
+  Line 198) getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 199) getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterElementType()
+  Line 200) getArrayBracketPairsAfterParameterList() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterParameterList()
+  Line 209) ensureNotNull(typeParameters) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 216) setAsParentNodeOf(this.body) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 228) setNameExpr(new NameExpr(name)) ==> com.github.javaparser.ast.body.MethodDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)
+  Line 234) setAsParentNodeOf(this.name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 241) setAsParentNodeOf(this.parameters) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 248) setAsParentNodeOf(this.throws_) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 254) unwrapArrayTypes(type) ==> com.github.javaparser.ast.type.ArrayType.unwrapArrayTypes(com.github.javaparser.ast.type.Type)
+  Line 255) setElementType(typeListPair.a) ==> com.github.javaparser.ast.body.MethodDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 256) setArrayBracketPairsAfterElementType(typeListPair.b) ==> com.github.javaparser.ast.body.MethodDeclaration.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 257) setArrayBracketPairsAfterParameterList(null) ==> com.github.javaparser.ast.body.MethodDeclaration.setArrayBracketPairsAfterParameterList(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 264) setAsParentNodeOf(this.elementType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 270) setAsParentNodeOf(typeParameters) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 285) getDeclarationAsString(true, true, true) ==> com.github.javaparser.ast.body.MethodDeclaration.getDeclarationAsString(boolean, boolean, boolean)
+  Line 290) getDeclarationAsString(includingModifiers, includingThrows, true) ==> com.github.javaparser.ast.body.MethodDeclaration.getDeclarationAsString(boolean, boolean, boolean)
+  Line 307) Modifier.getAccessSpecifier(getModifiers()) ==> com.github.javaparser.ast.Modifier.getAccessSpecifier(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 307) getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 308) sb.append(accessSpecifier.getCodeRepresenation()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 308) accessSpecifier.getCodeRepresenation() ==> com.github.javaparser.ast.AccessSpecifier.getCodeRepresenation()
+  Line 309) sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 310) getModifiers().contains(Modifier.STATIC) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 310) getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 311) sb.append("static ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 313) getModifiers().contains(Modifier.ABSTRACT) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 313) getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 314) sb.append("abstract ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 316) getModifiers().contains(Modifier.FINAL) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 316) getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 317) sb.append("final ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 319) getModifiers().contains(Modifier.NATIVE) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 319) getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 320) sb.append("native ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 322) getModifiers().contains(Modifier.SYNCHRONIZED) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 322) getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 323) sb.append("synchronized ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 327) sb.append(getElementType().toStringWithoutComments()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 327) getElementType().toStringWithoutComments() ==> com.github.javaparser.ast.Node.toStringWithoutComments()
+  Line 327) getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 328) sb.append(" ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 329) sb.append(getName()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 329) getName() ==> com.github.javaparser.ast.body.MethodDeclaration.getName()
+  Line 330) sb.append("(") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 332) getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 336) sb.append(", ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 339) sb.append(param.toStringWithoutComments()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 339) param.toStringWithoutComments() ==> com.github.javaparser.ast.Node.toStringWithoutComments()
+  Line 341) sb.append(param.getElementType().toStringWithoutComments()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 341) param.getElementType().toStringWithoutComments() ==> com.github.javaparser.ast.Node.toStringWithoutComments()
+  Line 341) param.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 342) param.isVarArgs() ==> com.github.javaparser.ast.body.Parameter.isVarArgs()
+  Line 343) sb.append("...") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 347) sb.append(")") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 350) getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 353) sb.append(" throws ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 355) sb.append(", ") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 357) sb.append(thr.toStringWithoutComments()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 357) thr.toStringWithoutComments() ==> com.github.javaparser.ast.Node.toStringWithoutComments()
+  Line 360) sb.toString() ==> java.lang.StringBuilder.toString()
+  Line 365) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 366) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 375) ensureNotNull(arrayBracketPairsAfterType) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 382) setAsParentNodeOf(arrayBracketPairsAfterType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 390) ensureNotNull(arrayBracketPairsAfterParameterList) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 396) setAsParentNodeOf(arrayBracketPairsAfterParameterList) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_Parameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_Parameter.txt
new file mode 100644
index 0000000..9f579bc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_Parameter.txt
@@ -0,0 +1,32 @@
+  Line 56) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 68) setId(id) ==> com.github.javaparser.ast.body.Parameter.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 69) setElementType(elementType) ==> com.github.javaparser.ast.body.Parameter.setElementType(com.github.javaparser.ast.type.Type)
+  Line 86) setModifiers(modifiers) ==> com.github.javaparser.ast.body.Parameter.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 87) setId(id) ==> com.github.javaparser.ast.body.Parameter.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 88) setElementType(elementType) ==> com.github.javaparser.ast.body.Parameter.setElementType(com.github.javaparser.ast.type.Type)
+  Line 99) setModifiers(modifiers) ==> com.github.javaparser.ast.body.Parameter.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 100) setAnnotations(annotations) ==> com.github.javaparser.ast.body.Parameter.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 101) setId(id) ==> com.github.javaparser.ast.body.Parameter.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 102) setElementType(elementType) ==> com.github.javaparser.ast.body.Parameter.setElementType(com.github.javaparser.ast.type.Type)
+  Line 103) setVarArgs(isVarArgs) ==> com.github.javaparser.ast.body.Parameter.setVarArgs(boolean)
+  Line 104) setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType) ==> com.github.javaparser.ast.body.Parameter.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 109) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.Parameter, A)
+  Line 114) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.Parameter, A)
+  Line 119) wrapInArrayTypes(elementType, getArrayBracketPairsAfterElementType(), getId().getArrayBracketPairsAfterId()) ==> com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes(com.github.javaparser.ast.type.Type, java.util.List<com.github.javaparser.ast.ArrayBracketPair>...)
+  Line 120) getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.Parameter.getArrayBracketPairsAfterElementType()
+  Line 121) getId().getArrayBracketPairsAfterId() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()
+  Line 121) getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 130) ArrayType.unwrapArrayTypes(type) ==> com.github.javaparser.ast.type.ArrayType.unwrapArrayTypes(com.github.javaparser.ast.type.Type)
+  Line 131) setElementType(unwrapped.a) ==> com.github.javaparser.ast.body.Parameter.setElementType(com.github.javaparser.ast.type.Type)
+  Line 132) setArrayBracketPairsAfterElementType(unwrapped.b) ==> com.github.javaparser.ast.body.Parameter.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 133) getId().setArrayBracketPairsAfterId(null) ==> com.github.javaparser.ast.body.VariableDeclaratorId.setArrayBracketPairsAfterId(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 133) getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 146) ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 156) getId().getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 156) getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 163) id.setName(name) ==> com.github.javaparser.ast.body.VariableDeclaratorId.setName(java.lang.String)
+  Line 188) setAsParentNodeOf(this.annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 194) setAsParentNodeOf(this.id) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 212) setAsParentNodeOf(this.elementType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 217) ensureNotNull(arrayBracketPairsAfterType) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 224) setAsParentNodeOf(arrayBracketPairsAfterType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_TypeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_TypeDeclaration.txt
new file mode 100644
index 0000000..371b048
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_TypeDeclaration.txt
@@ -0,0 +1,21 @@
+  Line 49) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 57) setName(name) ==> com.github.javaparser.ast.body.TypeDeclaration.setName(java.lang.String)
+  Line 58) setModifiers(modifiers) ==> com.github.javaparser.ast.body.TypeDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 65) setName(name) ==> com.github.javaparser.ast.body.TypeDeclaration.setName(java.lang.String)
+  Line 66) setModifiers(modifiers) ==> com.github.javaparser.ast.body.TypeDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 67) setMembers(members) ==> com.github.javaparser.ast.body.TypeDeclaration.setMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>)
+  Line 74) setName(name) ==> com.github.javaparser.ast.body.TypeDeclaration.setName(java.lang.String)
+  Line 75) setModifiers(modifiers) ==> com.github.javaparser.ast.body.TypeDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 76) setMembers(members) ==> com.github.javaparser.ast.body.TypeDeclaration.setMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>)
+  Line 87) getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 88) isNullOrEmpty(members) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 90) setMembers(members) ==> com.github.javaparser.ast.body.TypeDeclaration.setMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>)
+  Line 92) members.add(decl) ==> java.util.List.add(E)
+  Line 93) decl.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 99) ensureNotNull(members) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 116) name.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 123) setAsParentNodeOf(this.members) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 137) setNameExpr(new NameExpr(name)) ==> com.github.javaparser.ast.body.TypeDeclaration.setNameExpr(com.github.javaparser.ast.expr.NameExpr)
+  Line 144) setAsParentNodeOf(this.name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 154) getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 155) getComment() ==> com.github.javaparser.ast.Node.getComment()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_VariableDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_VariableDeclarator.txt
new file mode 100644
index 0000000..e00b1dd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_VariableDeclarator.txt
@@ -0,0 +1,25 @@
+  Line 55) setId(id) ==> com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 59) setId(new VariableDeclaratorId(variableName)) ==> com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 71) setId(id) ==> com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 72) setInit(init) ==> com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)
+  Line 76) setId(new VariableDeclaratorId(variableName)) ==> com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 77) setInit(init) ==> com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)
+  Line 82) setId(id) ==> com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 83) setInit(init) ==> com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)
+  Line 88) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.VariableDeclarator, A)
+  Line 93) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.VariableDeclarator, A)
+  Line 106) setAsParentNodeOf(this.id) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 112) setAsParentNodeOf(this.init) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 121) setAsParentNodeOf(this.init) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 128) getParentNodeOfType(NodeWithElementType.class) ==> com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)
+  Line 130) wrapInArrayTypes(elementType.getElementType(), elementType.getArrayBracketPairsAfterElementType(), getId().getArrayBracketPairsAfterId()) ==> com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes(com.github.javaparser.ast.type.Type, java.util.List<com.github.javaparser.ast.ArrayBracketPair>...)
+  Line 130) elementType.getElementType() ==> com.github.javaparser.ast.nodeTypes.NodeWithElementType.getElementType()
+  Line 131) elementType.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.nodeTypes.NodeWithElementType.getArrayBracketPairsAfterElementType()
+  Line 132) getId().getArrayBracketPairsAfterId() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()
+  Line 132) getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 137) ArrayType.unwrapArrayTypes(type) ==> com.github.javaparser.ast.type.ArrayType.unwrapArrayTypes(com.github.javaparser.ast.type.Type)
+  Line 138) getParentNodeOfType(NodeWithElementType.class) ==> com.github.javaparser.ast.Node.getParentNodeOfType(java.lang.Class<T>)
+  Line 142) nodeWithElementType.setElementType(unwrapped.a) ==> com.github.javaparser.ast.nodeTypes.NodeWithElementType.setElementType(com.github.javaparser.ast.type.Type<?>)
+  Line 143) nodeWithElementType.setArrayBracketPairsAfterElementType(null) ==> com.github.javaparser.ast.nodeTypes.NodeWithElementType.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 144) getId().setArrayBracketPairsAfterId(unwrapped.b) ==> com.github.javaparser.ast.body.VariableDeclaratorId.setArrayBracketPairsAfterId(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 144) getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_VariableDeclaratorId.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_VariableDeclaratorId.txt
new file mode 100644
index 0000000..678ac65
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_body_VariableDeclaratorId.txt
@@ -0,0 +1,7 @@
+  Line 48) setName(name) ==> com.github.javaparser.ast.body.VariableDeclaratorId.setName(java.lang.String)
+  Line 53) setName(name) ==> com.github.javaparser.ast.body.VariableDeclaratorId.setName(java.lang.String)
+  Line 54) setArrayBracketPairsAfterId(arrayBracketPairsAfterId) ==> com.github.javaparser.ast.body.VariableDeclaratorId.setArrayBracketPairsAfterId(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 59) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.body.VariableDeclaratorId, A)
+  Line 64) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.body.VariableDeclaratorId, A)
+  Line 79) ensureNotNull(arrayBracketPairsAfterId) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 85) setAsParentNodeOf(arrayBracketPairsAfterId) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_BlockComment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_BlockComment.txt
new file mode 100644
index 0000000..95af184
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_BlockComment.txt
@@ -0,0 +1,2 @@
+  Line 52) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.comments.BlockComment, A)
+  Line 57) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.comments.BlockComment, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_Comment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_Comment.txt
new file mode 100644
index 0000000..1e4a7dd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_Comment.txt
@@ -0,0 +1 @@
+  Line 78) isLineComment() ==> com.github.javaparser.ast.comments.Comment.isLineComment()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_CommentsCollection.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_CommentsCollection.txt
new file mode 100644
index 0000000..833cc2f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_CommentsCollection.txt
@@ -0,0 +1,34 @@
+  Line 41) comments.addAll(commentsToCopy) ==> java.util.TreeSet.addAll(java.util.Collection<? extends E>)
+  Line 45) comments.stream().filter(comment -> comment instanceof LineComment).map(comment -> (LineComment) comment).collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 45) comments.stream().filter(comment -> comment instanceof LineComment).map(comment -> (LineComment) comment) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 45) comments.stream().filter(comment -> comment instanceof LineComment) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 45) comments.stream() ==> java.util.Collection.stream()
+  Line 48) Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 52) comments.stream().filter(comment -> comment instanceof BlockComment).map(comment -> (BlockComment) comment).collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 52) comments.stream().filter(comment -> comment instanceof BlockComment).map(comment -> (BlockComment) comment) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 52) comments.stream().filter(comment -> comment instanceof BlockComment) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 52) comments.stream() ==> java.util.Collection.stream()
+  Line 55) Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 59) comments.stream().filter(comment -> comment instanceof JavadocComment).map(comment -> (JavadocComment) comment).collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 59) comments.stream().filter(comment -> comment instanceof JavadocComment).map(comment -> (JavadocComment) comment) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 59) comments.stream().filter(comment -> comment instanceof JavadocComment) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 59) comments.stream() ==> java.util.Collection.stream()
+  Line 62) Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 66) comments.add(comment) ==> java.util.TreeSet.add(E)
+  Line 70) getComments() ==> com.github.javaparser.ast.comments.CommentsCollection.getComments()
+  Line 73) c.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 73) comment.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 74) c.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 74) comment.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 75) c.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 75) comment.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 76) Math.abs(c.getEnd().column - comment.getEnd().column) ==> java.lang.Math.abs(int)
+  Line 76) c.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 76) comment.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 88) comments.size() ==> java.util.TreeSet.size()
+  Line 93) result.comments.addAll(comments.stream().filter(comment -> !other.contains(comment)).collect(Collectors.toList())) ==> java.util.TreeSet.addAll(java.util.Collection<? extends E>)
+  Line 94) comments.stream().filter(comment -> !other.contains(comment)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 94) comments.stream().filter(comment -> !other.contains(comment)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 94) comments.stream() ==> java.util.Collection.stream()
+  Line 95) other.contains(comment) ==> com.github.javaparser.ast.comments.CommentsCollection.contains(com.github.javaparser.ast.comments.Comment)
+  Line 96) Collectors.toList() ==> java.util.stream.Collectors.toList()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_JavadocComment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_JavadocComment.txt
new file mode 100644
index 0000000..6f84f29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_JavadocComment.txt
@@ -0,0 +1,2 @@
+  Line 46) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.comments.JavadocComment, A)
+  Line 51) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.comments.JavadocComment, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_LineComment.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_LineComment.txt
new file mode 100644
index 0000000..dff8c7e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_comments_LineComment.txt
@@ -0,0 +1,2 @@
+  Line 51) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.comments.LineComment, A)
+  Line 56) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.comments.LineComment, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_AnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_AnnotationExpr.txt
new file mode 100644
index 0000000..8a22898
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_AnnotationExpr.txt
@@ -0,0 +1 @@
+  Line 45) setAsParentNodeOf(name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayAccessExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayAccessExpr.txt
new file mode 100644
index 0000000..664253b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayAccessExpr.txt
@@ -0,0 +1,8 @@
+  Line 41) setName(name) ==> com.github.javaparser.ast.expr.ArrayAccessExpr.setName(com.github.javaparser.ast.expr.Expression)
+  Line 42) setIndex(index) ==> com.github.javaparser.ast.expr.ArrayAccessExpr.setIndex(com.github.javaparser.ast.expr.Expression)
+  Line 47) setName(name) ==> com.github.javaparser.ast.expr.ArrayAccessExpr.setName(com.github.javaparser.ast.expr.Expression)
+  Line 48) setIndex(index) ==> com.github.javaparser.ast.expr.ArrayAccessExpr.setIndex(com.github.javaparser.ast.expr.Expression)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.ArrayAccessExpr, A)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.ArrayAccessExpr, A)
+  Line 71) setAsParentNodeOf(this.index) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 77) setAsParentNodeOf(this.name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayCreationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayCreationExpr.txt
new file mode 100644
index 0000000..e2a9fd0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayCreationExpr.txt
@@ -0,0 +1,16 @@
+  Line 50) setLevels(levels) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setLevels(java.util.List<com.github.javaparser.ast.ArrayCreationLevel>)
+  Line 51) setType(type) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 52) setInitializer(initializer) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setInitializer(com.github.javaparser.ast.expr.ArrayInitializerExpr)
+  Line 57) setLevels(levels) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setLevels(java.util.List<com.github.javaparser.ast.ArrayCreationLevel>)
+  Line 58) setType(type) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 59) setInitializer(initializer) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setInitializer(com.github.javaparser.ast.expr.ArrayInitializerExpr)
+  Line 63) setType(type) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 64) setInitializer(null) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setInitializer(com.github.javaparser.ast.expr.ArrayInitializerExpr)
+  Line 69) setType(type) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 70) setInitializer(null) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setInitializer(com.github.javaparser.ast.expr.ArrayInitializerExpr)
+  Line 75) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.ArrayCreationExpr, A)
+  Line 80) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.ArrayCreationExpr, A)
+  Line 94) setAsParentNodeOf(this.initializer) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 101) setAsParentNodeOf(this.type) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 106) ensureNotNull(levels) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 112) setAsParentNodeOf(levels) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayInitializerExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayInitializerExpr.txt
new file mode 100644
index 0000000..0190992
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ArrayInitializerExpr.txt
@@ -0,0 +1,6 @@
+  Line 43) setValues(values) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.setValues(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 48) setValues(values) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.setValues(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.ArrayInitializerExpr, A)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.ArrayInitializerExpr, A)
+  Line 62) ensureNotNull(values) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 68) setAsParentNodeOf(this.values) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_AssignExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_AssignExpr.txt
new file mode 100644
index 0000000..5063787
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_AssignExpr.txt
@@ -0,0 +1,10 @@
+  Line 58) setTarget(target) ==> com.github.javaparser.ast.expr.AssignExpr.setTarget(com.github.javaparser.ast.expr.Expression)
+  Line 59) setValue(value) ==> com.github.javaparser.ast.expr.AssignExpr.setValue(com.github.javaparser.ast.expr.Expression)
+  Line 60) setOperator(op) ==> com.github.javaparser.ast.expr.AssignExpr.setOperator(com.github.javaparser.ast.expr.AssignExpr.Operator)
+  Line 65) setTarget(target) ==> com.github.javaparser.ast.expr.AssignExpr.setTarget(com.github.javaparser.ast.expr.Expression)
+  Line 66) setValue(value) ==> com.github.javaparser.ast.expr.AssignExpr.setValue(com.github.javaparser.ast.expr.Expression)
+  Line 67) setOperator(op) ==> com.github.javaparser.ast.expr.AssignExpr.setOperator(com.github.javaparser.ast.expr.AssignExpr.Operator)
+  Line 72) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.AssignExpr, A)
+  Line 77) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.AssignExpr, A)
+  Line 99) setAsParentNodeOf(this.target) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 105) setAsParentNodeOf(this.value) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_BinaryExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_BinaryExpr.txt
new file mode 100644
index 0000000..3b6fce9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_BinaryExpr.txt
@@ -0,0 +1,10 @@
+  Line 65) setLeft(left) ==> com.github.javaparser.ast.expr.BinaryExpr.setLeft(com.github.javaparser.ast.expr.Expression)
+  Line 66) setRight(right) ==> com.github.javaparser.ast.expr.BinaryExpr.setRight(com.github.javaparser.ast.expr.Expression)
+  Line 67) setOperator(op) ==> com.github.javaparser.ast.expr.BinaryExpr.setOperator(com.github.javaparser.ast.expr.BinaryExpr.Operator)
+  Line 72) setLeft(left) ==> com.github.javaparser.ast.expr.BinaryExpr.setLeft(com.github.javaparser.ast.expr.Expression)
+  Line 73) setRight(right) ==> com.github.javaparser.ast.expr.BinaryExpr.setRight(com.github.javaparser.ast.expr.Expression)
+  Line 74) setOperator(op) ==> com.github.javaparser.ast.expr.BinaryExpr.setOperator(com.github.javaparser.ast.expr.BinaryExpr.Operator)
+  Line 79) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.BinaryExpr, A)
+  Line 84) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.BinaryExpr, A)
+  Line 101) setAsParentNodeOf(this.left) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 112) setAsParentNodeOf(this.right) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_BooleanLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_BooleanLiteralExpr.txt
new file mode 100644
index 0000000..3495ba4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_BooleanLiteralExpr.txt
@@ -0,0 +1,4 @@
+  Line 39) setValue(value) ==> com.github.javaparser.ast.expr.BooleanLiteralExpr.setValue(boolean)
+  Line 44) setValue(value) ==> com.github.javaparser.ast.expr.BooleanLiteralExpr.setValue(boolean)
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.BooleanLiteralExpr, A)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.BooleanLiteralExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_CastExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_CastExpr.txt
new file mode 100644
index 0000000..9936c29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_CastExpr.txt
@@ -0,0 +1,8 @@
+  Line 43) setType(type) ==> com.github.javaparser.ast.expr.CastExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 44) setExpr(expr) ==> com.github.javaparser.ast.expr.CastExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 49) setType(type) ==> com.github.javaparser.ast.expr.CastExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 50) setExpr(expr) ==> com.github.javaparser.ast.expr.CastExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 55) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.CastExpr, A)
+  Line 60) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.CastExpr, A)
+  Line 74) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 81) setAsParentNodeOf(this.type) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_CharLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_CharLiteralExpr.txt
new file mode 100644
index 0000000..f596b99
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_CharLiteralExpr.txt
@@ -0,0 +1,3 @@
+  Line 49) Utils.escapeEndOfLines(string) ==> com.github.javaparser.utils.Utils.escapeEndOfLines(java.lang.String)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.CharLiteralExpr, A)
+  Line 59) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.CharLiteralExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ClassExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ClassExpr.txt
new file mode 100644
index 0000000..8242ddb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ClassExpr.txt
@@ -0,0 +1,5 @@
+  Line 46) setType(type) ==> com.github.javaparser.ast.expr.ClassExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 51) setType(type) ==> com.github.javaparser.ast.expr.ClassExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 56) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.ClassExpr, A)
+  Line 61) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.ClassExpr, A)
+  Line 72) setAsParentNodeOf(this.type) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ConditionalExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ConditionalExpr.txt
new file mode 100644
index 0000000..adbfe9c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ConditionalExpr.txt
@@ -0,0 +1,11 @@
+  Line 43) setCondition(condition) ==> com.github.javaparser.ast.expr.ConditionalExpr.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 44) setThenExpr(thenExpr) ==> com.github.javaparser.ast.expr.ConditionalExpr.setThenExpr(com.github.javaparser.ast.expr.Expression)
+  Line 45) setElseExpr(elseExpr) ==> com.github.javaparser.ast.expr.ConditionalExpr.setElseExpr(com.github.javaparser.ast.expr.Expression)
+  Line 50) setCondition(condition) ==> com.github.javaparser.ast.expr.ConditionalExpr.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 51) setThenExpr(thenExpr) ==> com.github.javaparser.ast.expr.ConditionalExpr.setThenExpr(com.github.javaparser.ast.expr.Expression)
+  Line 52) setElseExpr(elseExpr) ==> com.github.javaparser.ast.expr.ConditionalExpr.setElseExpr(com.github.javaparser.ast.expr.Expression)
+  Line 57) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.ConditionalExpr, A)
+  Line 62) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.ConditionalExpr, A)
+  Line 79) setAsParentNodeOf(this.condition) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 85) setAsParentNodeOf(this.elseExpr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 91) setAsParentNodeOf(this.thenExpr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_DoubleLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_DoubleLiteralExpr.txt
new file mode 100644
index 0000000..e8fbc52
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_DoubleLiteralExpr.txt
@@ -0,0 +1,2 @@
+  Line 45) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.DoubleLiteralExpr, A)
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.DoubleLiteralExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_EnclosedExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_EnclosedExpr.txt
new file mode 100644
index 0000000..b3a375d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_EnclosedExpr.txt
@@ -0,0 +1,5 @@
+  Line 39) setInner(inner) ==> com.github.javaparser.ast.expr.EnclosedExpr.setInner(com.github.javaparser.ast.expr.Expression)
+  Line 44) setInner(inner) ==> com.github.javaparser.ast.expr.EnclosedExpr.setInner(com.github.javaparser.ast.expr.Expression)
+  Line 48) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.EnclosedExpr, A)
+  Line 52) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.EnclosedExpr, A)
+  Line 61) setAsParentNodeOf(this.inner) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_Expression.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_Expression.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_Expression.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_FieldAccessExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_FieldAccessExpr.txt
new file mode 100644
index 0000000..120a526
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_FieldAccessExpr.txt
@@ -0,0 +1,12 @@
+  Line 47) setScope(scope) ==> com.github.javaparser.ast.expr.FieldAccessExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 48) setField(field) ==> com.github.javaparser.ast.expr.FieldAccessExpr.setField(java.lang.String)
+  Line 53) setScope(scope) ==> com.github.javaparser.ast.expr.FieldAccessExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 54) setTypeArguments(typeArguments) ==> com.github.javaparser.ast.expr.FieldAccessExpr.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 55) setField(field) ==> com.github.javaparser.ast.expr.FieldAccessExpr.setField(java.lang.String)
+  Line 59) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.FieldAccessExpr, A)
+  Line 63) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.FieldAccessExpr, A)
+  Line 67) field.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 79) setFieldExpr(new NameExpr(field)) ==> com.github.javaparser.ast.expr.FieldAccessExpr.setFieldExpr(com.github.javaparser.ast.expr.NameExpr)
+  Line 85) setAsParentNodeOf(this.field) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 91) setAsParentNodeOf(this.scope) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 104) setAsParentNodeOf(this.typeArguments) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_InstanceOfExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_InstanceOfExpr.txt
new file mode 100644
index 0000000..daa8c24
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_InstanceOfExpr.txt
@@ -0,0 +1,8 @@
+  Line 43) setExpr(expr) ==> com.github.javaparser.ast.expr.InstanceOfExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 44) setType(type) ==> com.github.javaparser.ast.expr.InstanceOfExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 49) setExpr(expr) ==> com.github.javaparser.ast.expr.InstanceOfExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 50) setType(type) ==> com.github.javaparser.ast.expr.InstanceOfExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.InstanceOfExpr, A)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.InstanceOfExpr, A)
+  Line 72) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 79) setAsParentNodeOf(this.type) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_IntegerLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_IntegerLiteralExpr.txt
new file mode 100644
index 0000000..ec7b258
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_IntegerLiteralExpr.txt
@@ -0,0 +1,4 @@
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.IntegerLiteralExpr, A)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.IntegerLiteralExpr, A)
+  Line 58) value.length() ==> java.lang.String.length()
+  Line 59) value.equals(UNSIGNED_MIN_VALUE) ==> java.lang.String.equals(java.lang.Object)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_IntegerLiteralMinValueExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_IntegerLiteralMinValueExpr.txt
new file mode 100644
index 0000000..de33464
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_IntegerLiteralMinValueExpr.txt
@@ -0,0 +1,2 @@
+  Line 42) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr, A)
+  Line 46) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LambdaExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LambdaExpr.txt
new file mode 100644
index 0000000..ad577cf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LambdaExpr.txt
@@ -0,0 +1,8 @@
+  Line 54) setParameters(parameters) ==> com.github.javaparser.ast.expr.LambdaExpr.setParameters(java.util.List<com.github.javaparser.ast.body.Parameter>)
+  Line 55) setBody(body) ==> com.github.javaparser.ast.expr.LambdaExpr.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 56) setParametersEnclosed(parametersEnclosed) ==> com.github.javaparser.ast.expr.LambdaExpr.setParametersEnclosed(boolean)
+  Line 60) ensureNotNull(parameters) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 66) setAsParentNodeOf(this.parameters) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 76) setAsParentNodeOf(this.body) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 82) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.LambdaExpr, A)
+  Line 87) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.LambdaExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LiteralExpr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LiteralExpr.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LongLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LongLiteralExpr.txt
new file mode 100644
index 0000000..771c18e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LongLiteralExpr.txt
@@ -0,0 +1,7 @@
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.LongLiteralExpr, A)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.LongLiteralExpr, A)
+  Line 58) value.length() ==> java.lang.String.length()
+  Line 59) //
+value.startsWith(UNSIGNED_MIN_VALUE) ==> java.lang.String.startsWith(java.lang.String)
+  Line 60) value.charAt(19) ==> java.lang.String.charAt(int)
+  Line 60) value.charAt(19) ==> java.lang.String.charAt(int)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LongLiteralMinValueExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LongLiteralMinValueExpr.txt
new file mode 100644
index 0000000..e434383
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_LongLiteralMinValueExpr.txt
@@ -0,0 +1,2 @@
+  Line 42) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.LongLiteralMinValueExpr, A)
+  Line 46) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.LongLiteralMinValueExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MarkerAnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MarkerAnnotationExpr.txt
new file mode 100644
index 0000000..51048a2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MarkerAnnotationExpr.txt
@@ -0,0 +1,4 @@
+  Line 37) setName(name) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 42) setName(name) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 46) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.MarkerAnnotationExpr, A)
+  Line 50) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.MarkerAnnotationExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MemberValuePair.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MemberValuePair.txt
new file mode 100644
index 0000000..e7bc28a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MemberValuePair.txt
@@ -0,0 +1,7 @@
+  Line 43) setName(name) ==> com.github.javaparser.ast.expr.MemberValuePair.setName(java.lang.String)
+  Line 44) setValue(value) ==> com.github.javaparser.ast.expr.MemberValuePair.setValue(com.github.javaparser.ast.expr.Expression)
+  Line 49) setName(name) ==> com.github.javaparser.ast.expr.MemberValuePair.setName(java.lang.String)
+  Line 50) setValue(value) ==> com.github.javaparser.ast.expr.MemberValuePair.setValue(com.github.javaparser.ast.expr.Expression)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.MemberValuePair, A)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.MemberValuePair, A)
+  Line 78) setAsParentNodeOf(this.value) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MethodCallExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MethodCallExpr.txt
new file mode 100644
index 0000000..2c645ce
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MethodCallExpr.txt
@@ -0,0 +1,22 @@
+  Line 51) setScope(scope) ==> com.github.javaparser.ast.expr.MethodCallExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 52) setName(name) ==> com.github.javaparser.ast.expr.MethodCallExpr.setName(java.lang.String)
+  Line 56) setScope(scope) ==> com.github.javaparser.ast.expr.MethodCallExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 57) setName(name) ==> com.github.javaparser.ast.expr.MethodCallExpr.setName(java.lang.String)
+  Line 58) setArgs(args) ==> com.github.javaparser.ast.expr.MethodCallExpr.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 63) setScope(scope) ==> com.github.javaparser.ast.expr.MethodCallExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 64) setTypeArguments(typeArguments) ==> com.github.javaparser.ast.expr.MethodCallExpr.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 65) setName(name) ==> com.github.javaparser.ast.expr.MethodCallExpr.setName(java.lang.String)
+  Line 66) setArgs(args) ==> com.github.javaparser.ast.expr.MethodCallExpr.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 76) getArgs().add(arg) ==> java.util.List.add(E)
+  Line 76) getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 77) arg.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 82) addArgument(new NameExpr(arg)) ==> com.github.javaparser.ast.expr.MethodCallExpr.addArgument(com.github.javaparser.ast.expr.Expression)
+  Line 87) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.MethodCallExpr, A)
+  Line 92) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.MethodCallExpr, A)
+  Line 96) ensureNotNull(args) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 101) name.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 114) setAsParentNodeOf(this.args) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 118) setNameExpr(new NameExpr(name)) ==> com.github.javaparser.ast.expr.MethodCallExpr.setNameExpr(com.github.javaparser.ast.expr.NameExpr)
+  Line 124) setAsParentNodeOf(this.name) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 130) setAsParentNodeOf(this.scope) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 142) setAsParentNodeOf(this.typeArguments) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MethodReferenceExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MethodReferenceExpr.txt
new file mode 100644
index 0000000..2a91358
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_MethodReferenceExpr.txt
@@ -0,0 +1,7 @@
+  Line 58) setIdentifier(identifier) ==> com.github.javaparser.ast.expr.MethodReferenceExpr.setIdentifier(java.lang.String)
+  Line 59) setScope(scope) ==> com.github.javaparser.ast.expr.MethodReferenceExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 60) setTypeArguments(typeArguments) ==> com.github.javaparser.ast.expr.MethodReferenceExpr.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 66) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.MethodReferenceExpr, A)
+  Line 71) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.MethodReferenceExpr, A)
+  Line 80) setAsParentNodeOf(this.scope) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 92) setAsParentNodeOf(this.typeArguments) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NameExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NameExpr.txt
new file mode 100644
index 0000000..336aea1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NameExpr.txt
@@ -0,0 +1,3 @@
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.NameExpr, A)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.NameExpr, A)
+  Line 77) qualifiedName.split("\\.") ==> java.lang.String.split(java.lang.String)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NormalAnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NormalAnnotationExpr.txt
new file mode 100644
index 0000000..7b7c389
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NormalAnnotationExpr.txt
@@ -0,0 +1,13 @@
+  Line 48) setName(name) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 49) setPairs(pairs) ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.setPairs(java.util.List<com.github.javaparser.ast.expr.MemberValuePair>)
+  Line 54) setName(name) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 55) setPairs(pairs) ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.setPairs(java.util.List<com.github.javaparser.ast.expr.MemberValuePair>)
+  Line 60) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.NormalAnnotationExpr, A)
+  Line 65) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.NormalAnnotationExpr, A)
+  Line 69) ensureNotNull(pairs) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 75) setAsParentNodeOf(this.pairs) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 85) addPair(key, name(value)) ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.addPair(java.lang.String, com.github.javaparser.ast.expr.NameExpr)
+  Line 85) name(value) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 95) getPairs().add(memberValuePair) ==> java.util.List.add(E)
+  Line 95) getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 96) memberValuePair.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NullLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NullLiteralExpr.txt
new file mode 100644
index 0000000..9d3a14b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_NullLiteralExpr.txt
@@ -0,0 +1,2 @@
+  Line 41) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.NullLiteralExpr, A)
+  Line 45) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.NullLiteralExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ObjectCreationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ObjectCreationExpr.txt
new file mode 100644
index 0000000..6a3ddc6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ObjectCreationExpr.txt
@@ -0,0 +1,18 @@
+  Line 73) setScope(scope) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 74) setType(type) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setType(com.github.javaparser.ast.type.Type<?>)
+  Line 75) setArgs(args) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 82) setScope(scope) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 83) setType(type) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setType(com.github.javaparser.ast.type.Type<?>)
+  Line 84) setTypeArguments(typeArguments) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 85) setArgs(args) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 86) setAnonymousClassBody(anonymousBody) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setAnonymousClassBody(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>)
+  Line 91) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.ObjectCreationExpr, A)
+  Line 96) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.ObjectCreationExpr, A)
+  Line 109) anonymousClassBody.add(body) ==> java.util.List.add(E)
+  Line 110) body.setParentNode(this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 114) ensureNotNull(args) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 129) setAsParentNodeOf(this.anonymousClassBody) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 135) setAsParentNodeOf(this.args) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 141) setAsParentNodeOf(this.scope) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 150) setAsParentNodeOf(this.type) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 162) setAsParentNodeOf(this.typeArguments) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_QualifiedNameExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_QualifiedNameExpr.txt
new file mode 100644
index 0000000..3166cf7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_QualifiedNameExpr.txt
@@ -0,0 +1,5 @@
+  Line 40) setQualifier(scope) ==> com.github.javaparser.ast.expr.QualifiedNameExpr.setQualifier(com.github.javaparser.ast.expr.NameExpr)
+  Line 45) setQualifier(scope) ==> com.github.javaparser.ast.expr.QualifiedNameExpr.setQualifier(com.github.javaparser.ast.expr.NameExpr)
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.QualifiedNameExpr, A)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.QualifiedNameExpr, A)
+  Line 62) setAsParentNodeOf(this.qualifier) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_SingleMemberAnnotationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_SingleMemberAnnotationExpr.txt
new file mode 100644
index 0000000..fb6fae9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_SingleMemberAnnotationExpr.txt
@@ -0,0 +1,7 @@
+  Line 39) setName(name) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 40) setMemberValue(memberValue) ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.setMemberValue(com.github.javaparser.ast.expr.Expression)
+  Line 45) setName(name) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 46) setMemberValue(memberValue) ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.setMemberValue(com.github.javaparser.ast.expr.Expression)
+  Line 50) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.SingleMemberAnnotationExpr, A)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.SingleMemberAnnotationExpr, A)
+  Line 63) setAsParentNodeOf(this.memberValue) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_StringLiteralExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_StringLiteralExpr.txt
new file mode 100644
index 0000000..74816ac
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_StringLiteralExpr.txt
@@ -0,0 +1,5 @@
+  Line 42) value.contains("\n") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 42) value.contains("\r") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 52) Utils.escapeEndOfLines(string) ==> com.github.javaparser.utils.Utils.escapeEndOfLines(java.lang.String)
+  Line 61) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.StringLiteralExpr, A)
+  Line 65) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.StringLiteralExpr, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_SuperExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_SuperExpr.txt
new file mode 100644
index 0000000..df96d13
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_SuperExpr.txt
@@ -0,0 +1,5 @@
+  Line 39) setClassExpr(classExpr) ==> com.github.javaparser.ast.expr.SuperExpr.setClassExpr(com.github.javaparser.ast.expr.Expression)
+  Line 44) setClassExpr(classExpr) ==> com.github.javaparser.ast.expr.SuperExpr.setClassExpr(com.github.javaparser.ast.expr.Expression)
+  Line 48) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.SuperExpr, A)
+  Line 52) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.SuperExpr, A)
+  Line 61) setAsParentNodeOf(this.classExpr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ThisExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ThisExpr.txt
new file mode 100644
index 0000000..4b51370
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_ThisExpr.txt
@@ -0,0 +1,5 @@
+  Line 39) setClassExpr(classExpr) ==> com.github.javaparser.ast.expr.ThisExpr.setClassExpr(com.github.javaparser.ast.expr.Expression)
+  Line 44) setClassExpr(classExpr) ==> com.github.javaparser.ast.expr.ThisExpr.setClassExpr(com.github.javaparser.ast.expr.Expression)
+  Line 48) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.ThisExpr, A)
+  Line 52) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.ThisExpr, A)
+  Line 61) setAsParentNodeOf(this.classExpr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_TypeExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_TypeExpr.txt
new file mode 100644
index 0000000..e25acf5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_TypeExpr.txt
@@ -0,0 +1,4 @@
+  Line 43) setType(type) ==> com.github.javaparser.ast.expr.TypeExpr.setType(com.github.javaparser.ast.type.Type<?>)
+  Line 48) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.TypeExpr, A)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.TypeExpr, A)
+  Line 64) setAsParentNodeOf(this.type) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_UnaryExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_UnaryExpr.txt
new file mode 100644
index 0000000..b5d297c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_UnaryExpr.txt
@@ -0,0 +1,7 @@
+  Line 52) setExpr(expr) ==> com.github.javaparser.ast.expr.UnaryExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 53) setOperator(op) ==> com.github.javaparser.ast.expr.UnaryExpr.setOperator(com.github.javaparser.ast.expr.UnaryExpr.Operator)
+  Line 58) setExpr(expr) ==> com.github.javaparser.ast.expr.UnaryExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 59) setOperator(op) ==> com.github.javaparser.ast.expr.UnaryExpr.setOperator(com.github.javaparser.ast.expr.UnaryExpr.Operator)
+  Line 63) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.UnaryExpr, A)
+  Line 67) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.UnaryExpr, A)
+  Line 80) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_VariableDeclarationExpr.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_VariableDeclarationExpr.txt
new file mode 100644
index 0000000..b17f424
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_expr_VariableDeclarationExpr.txt
@@ -0,0 +1,42 @@
+  Line 53) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 67) setElementType(elementType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 68) setVariables(singletonList(new VariableDeclarator(variableName))) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 68) singletonList(new VariableDeclarator(variableName)) ==> java.util.Collections.singletonList(T)
+  Line 72) setElementType(elementType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 73) setVariables(singletonList(var)) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 73) singletonList(var) ==> java.util.Collections.singletonList(T)
+  Line 77) setElementType(elementType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 78) setVariables(singletonList(new VariableDeclarator(variableName))) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 78) singletonList(new VariableDeclarator(variableName)) ==> java.util.Collections.singletonList(T)
+  Line 79) setModifiers(Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)))) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 79) Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 79) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 80) Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 80) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 84) setElementType(elementType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 85) setVariables(singletonList(var)) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 85) singletonList(var) ==> java.util.Collections.singletonList(T)
+  Line 86) setModifiers(Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)))) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 86) Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 86) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 87) Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 87) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 91) setElementType(elementType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 92) setVariables(variables) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 97) setModifiers(modifiers) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 98) setElementType(elementType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 99) setVariables(variables) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 108) setModifiers(modifiers) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 109) setAnnotations(annotations) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 110) setElementType(elementType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 111) setVariables(variables) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setVariables(java.util.List<com.github.javaparser.ast.body.VariableDeclarator>)
+  Line 112) setArrayBracketPairsAfterElementType(arrayBracketPairsAfterType) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setArrayBracketPairsAfterElementType(java.util.List<com.github.javaparser.ast.ArrayBracketPair>)
+  Line 126) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.expr.VariableDeclarationExpr, A)
+  Line 131) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.expr.VariableDeclarationExpr, A)
+  Line 136) ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 158) ensureNotNull(variables) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 165) setAsParentNodeOf(this.annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 178) setAsParentNodeOf(this.elementType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 185) setAsParentNodeOf(this.variables) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 190) ensureNotNull(arrayBracketPairsAfterType) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 197) setAsParentNodeOf(arrayBracketPairsAfterType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithAnnotations.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithAnnotations.txt
new file mode 100644
index 0000000..9a98991
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithAnnotations.txt
@@ -0,0 +1,40 @@
+  Line 55) name(name) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 56) getAnnotations().add(normalAnnotationExpr) ==> java.util.List.add(E)
+  Line 56) getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 57) normalAnnotationExpr.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 68) ((Node) this).tryAddImportToParentCompilationUnit(clazz) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 69) addAnnotation(clazz.getSimpleName()) ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(java.lang.String)
+  Line 69) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 81) name(name) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 82) getAnnotations().add(markerAnnotationExpr) ==> java.util.List.add(E)
+  Line 82) getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 83) markerAnnotationExpr.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 94) ((Node) this).tryAddImportToParentCompilationUnit(clazz) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 95) addMarkerAnnotation(clazz.getSimpleName()) ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addMarkerAnnotation(java.lang.String)
+  Line 95) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 108) name(name) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 108) name(value) ==> com.github.javaparser.ast.expr.NameExpr.name(java.lang.String)
+  Line 109) getAnnotations().add(singleMemberAnnotationExpr) ==> java.util.List.add(E)
+  Line 109) getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 110) singleMemberAnnotationExpr.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 123) ((Node) this).tryAddImportToParentCompilationUnit(clazz) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 124) addSingleMemberAnnotation(clazz.getSimpleName(), value) ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addSingleMemberAnnotation(java.lang.String, java.lang.String)
+  Line 124) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 134) getAnnotations().stream().anyMatch(a -> a.getName().getName().equals(annotationName)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 134) getAnnotations().stream() ==> java.util.Collection.stream()
+  Line 134) getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 134) a.getName().getName().equals(annotationName) ==> java.lang.String.equals(java.lang.Object)
+  Line 134) a.getName().getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 134) a.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 144) isAnnotationPresent(annotationClass.getSimpleName()) ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.isAnnotationPresent(java.lang.String)
+  Line 144) annotationClass.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 154) getAnnotations().stream().filter(a -> a.getName().getName().equals(annotationName)).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 154) getAnnotations().stream().filter(a -> a.getName().getName().equals(annotationName)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 154) getAnnotations().stream().filter(a -> a.getName().getName().equals(annotationName)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 154) getAnnotations().stream() ==> java.util.Collection.stream()
+  Line 154) getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 154) a.getName().getName().equals(annotationName) ==> java.lang.String.equals(java.lang.Object)
+  Line 154) a.getName().getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 154) a.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 165) getAnnotationByName(annotationClass.getSimpleName()) ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotationByName(java.lang.String)
+  Line 165) annotationClass.getSimpleName() ==> java.lang.Class.getSimpleName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithBlockStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithBlockStmt.txt
new file mode 100644
index 0000000..37d6538
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithBlockStmt.txt
@@ -0,0 +1,2 @@
+  Line 13) setBody(block) ==> com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 14) block.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithBody.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithBody.txt
new file mode 100644
index 0000000..862d0d4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithBody.txt
@@ -0,0 +1,2 @@
+  Line 14) b.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 15) setBody(b) ==> com.github.javaparser.ast.nodeTypes.NodeWithBody.setBody(com.github.javaparser.ast.stmt.Statement)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithElementType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithElementType.txt
new file mode 100644
index 0000000..227beb6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithElementType.txt
@@ -0,0 +1,4 @@
+  Line 65) ((Node) this).tryAddImportToParentCompilationUnit(typeClass) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 66) setElementType(new ClassOrInterfaceType(typeClass.getSimpleName())) ==> com.github.javaparser.ast.nodeTypes.NodeWithElementType.setElementType(com.github.javaparser.ast.type.Type<?>)
+  Line 66) typeClass.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 71) setElementType(classOrInterfaceType) ==> com.github.javaparser.ast.nodeTypes.NodeWithElementType.setElementType(com.github.javaparser.ast.type.Type<?>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithExtends.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithExtends.txt
new file mode 100644
index 0000000..a42aae3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithExtends.txt
@@ -0,0 +1,6 @@
+  Line 20) ((Node) this).tryAddImportToParentCompilationUnit(clazz) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 21) addExtends(clazz.getSimpleName()) ==> com.github.javaparser.ast.nodeTypes.NodeWithExtends.addExtends(java.lang.String)
+  Line 21) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 33) getExtends().add(classOrInterfaceType) ==> java.util.List.add(E)
+  Line 33) getExtends() ==> com.github.javaparser.ast.nodeTypes.NodeWithExtends.getExtends()
+  Line 34) classOrInterfaceType.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithImplements.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithImplements.txt
new file mode 100644
index 0000000..766991c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithImplements.txt
@@ -0,0 +1,6 @@
+  Line 22) getImplements().add(classOrInterfaceType) ==> java.util.List.add(E)
+  Line 22) getImplements() ==> com.github.javaparser.ast.nodeTypes.NodeWithImplements.getImplements()
+  Line 23) classOrInterfaceType.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 34) ((Node) this).tryAddImportToParentCompilationUnit(clazz) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 35) addImplements(clazz.getSimpleName()) ==> com.github.javaparser.ast.nodeTypes.NodeWithImplements.addImplements(java.lang.String)
+  Line 35) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithJavaDoc.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithJavaDoc.txt
new file mode 100644
index 0000000..9b114d9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithJavaDoc.txt
@@ -0,0 +1 @@
+  Line 45) ((Node) this).setComment(new JavadocComment(comment)) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithMembers.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithMembers.txt
new file mode 100644
index 0000000..b56bed1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithMembers.txt
@@ -0,0 +1,116 @@
+  Line 49) ((Node) this).tryAddImportToParentCompilationUnit(typeClass) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 50) addField(typeClass.getSimpleName(), name, modifiers) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(java.lang.String, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 50) typeClass.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 62) addField(new ClassOrInterfaceType(type), name, modifiers) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(com.github.javaparser.ast.type.Type<?>, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 75) fieldDeclaration.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 77) fieldDeclaration.getVariables().add(variable) ==> java.util.List.add(E)
+  Line 77) fieldDeclaration.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 78) variable.setParentNode(fieldDeclaration) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 79) fieldDeclaration.setModifiers(Arrays.stream(modifiers).collect(toCollection(() -> EnumSet.noneOf(Modifier.class)))) ==> com.github.javaparser.ast.body.FieldDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 79) Arrays.stream(modifiers).collect(toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 79) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 80) toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 80) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 81) variable.setType(type) ==> com.github.javaparser.ast.body.VariableDeclarator.setType(com.github.javaparser.ast.type.Type)
+  Line 82) getMembers().add(fieldDeclaration) ==> java.util.List.add(E)
+  Line 82) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 94) addField(typeClass, name, Modifier.PRIVATE) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(java.lang.Class<?>, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 106) addField(type, name, Modifier.PRIVATE) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(java.lang.String, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 117) addField(typeClass, name, Modifier.PUBLIC) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(java.lang.Class<?>, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 129) addField(type, name, Modifier.PUBLIC) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(java.lang.String, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 140) addField(typeClass, name, Modifier.PROTECTED) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(java.lang.Class<?>, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 152) addField(type, name, Modifier.PROTECTED) ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.addField(java.lang.String, java.lang.String, com.github.javaparser.ast.Modifier...)
+  Line 164) methodDeclaration.setName(methodName) ==> com.github.javaparser.ast.body.MethodDeclaration.setName(java.lang.String)
+  Line 165) methodDeclaration.setType(VOID_TYPE) ==> com.github.javaparser.ast.body.MethodDeclaration.setType(com.github.javaparser.ast.type.Type)
+  Line 166) methodDeclaration.setModifiers(Arrays.stream(modifiers).collect(toCollection(() -> EnumSet.noneOf(Modifier.class)))) ==> com.github.javaparser.ast.body.MethodDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 166) Arrays.stream(modifiers).collect(toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 166) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 167) toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 167) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 168) getMembers().add(methodDeclaration) ==> java.util.List.add(E)
+  Line 168) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 169) methodDeclaration.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 181) constructorDeclaration.setModifiers(Arrays.stream(modifiers).collect(toCollection(() -> EnumSet.noneOf(Modifier.class)))) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 181) Arrays.stream(modifiers).collect(toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 181) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 182) toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 182) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 183) constructorDeclaration.setName(((TypeDeclaration<?>) this).getName()) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setName(java.lang.String)
+  Line 183) ((TypeDeclaration<?>) this).getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 184) getMembers().add(constructorDeclaration) ==> java.util.List.add(E)
+  Line 184) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 185) constructorDeclaration.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 192) getMembers().add(initializerDeclaration) ==> java.util.List.add(E)
+  Line 192) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 193) initializerDeclaration.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 200) getMembers().add(initializerDeclaration) ==> java.util.List.add(E)
+  Line 200) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 201) initializerDeclaration.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 212) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getName().equals(name)).map(m -> (MethodDeclaration) m).collect(toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 212) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getName().equals(name)).map(m -> (MethodDeclaration) m) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 212) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 212) getMembers().stream() ==> java.util.Collection.stream()
+  Line 212) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 213) ((MethodDeclaration) m).getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 213) ((MethodDeclaration) m).getName() ==> com.github.javaparser.ast.body.MethodDeclaration.getName()
+  Line 214) toList() ==> java.util.stream.Collectors.toList()
+  Line 223) unmodifiableList(getMembers().stream().filter(m -> m instanceof MethodDeclaration).map(m -> (MethodDeclaration) m).collect(toList())) ==> java.util.Collections.unmodifiableList(java.util.List<? extends T>)
+  Line 223) getMembers().stream().filter(m -> m instanceof MethodDeclaration).map(m -> (MethodDeclaration) m).collect(toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 223) getMembers().stream().filter(m -> m instanceof MethodDeclaration).map(m -> (MethodDeclaration) m) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 223) getMembers().stream().filter(m -> m instanceof MethodDeclaration) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 223) getMembers().stream() ==> java.util.Collection.stream()
+  Line 223) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 226) toList() ==> java.util.stream.Collectors.toList()
+  Line 237) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).collect(toSet()))).map(m -> (MethodDeclaration) m).collect(toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 237) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).collect(toSet()))).map(m -> (MethodDeclaration) m) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 237) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).collect(toSet()))) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 237) getMembers().stream() ==> java.util.Collection.stream()
+  Line 237) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 239) ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).collect(toSet())) ==> java.util.Set.equals(java.lang.Object)
+  Line 239) ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 239) ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 239) ((MethodDeclaration) m).getParameters().stream() ==> java.util.Collection.stream()
+  Line 239) ((MethodDeclaration) m).getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 239) p.getType().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 239) p.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 240) toSet() ==> java.util.stream.Collectors.toSet()
+  Line 240) Stream.of(paramTypes).collect(toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 240) Stream.of(paramTypes) ==> java.util.stream.Stream.of(T...)
+  Line 240) toSet() ==> java.util.stream.Collectors.toSet()
+  Line 241) toList() ==> java.util.stream.Collectors.toList()
+  Line 252) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).map(Class::getSimpleName).collect(toSet()))).map(m -> (MethodDeclaration) m).collect(toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 252) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).map(Class::getSimpleName).collect(toSet()))).map(m -> (MethodDeclaration) m) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 252) getMembers().stream().filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).map(Class::getSimpleName).collect(toSet()))) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 252) getMembers().stream() ==> java.util.Collection.stream()
+  Line 252) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 254) ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()).equals(Stream.of(paramTypes).map(Class::getSimpleName).collect(toSet())) ==> java.util.Set.equals(java.lang.Object)
+  Line 254) ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()).collect(toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 254) ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString()) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 254) ((MethodDeclaration) m).getParameters().stream() ==> java.util.Collection.stream()
+  Line 254) ((MethodDeclaration) m).getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 254) p.getType().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 254) p.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 255) toSet() ==> java.util.stream.Collectors.toSet()
+  Line 256) Stream.of(paramTypes).map(Class::getSimpleName).collect(toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 256) Stream.of(paramTypes).map(Class::getSimpleName) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 256) Stream.of(paramTypes) ==> java.util.stream.Stream.of(T...)
+  Line 256) toSet() ==> java.util.stream.Collectors.toSet()
+  Line 257) toList() ==> java.util.stream.Collectors.toList()
+  Line 267) getMembers().stream().filter(m -> m instanceof FieldDeclaration && ((FieldDeclaration) m).getVariables().stream().anyMatch(var -> var.getId().getName().equals(name))).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 267) getMembers().stream().filter(m -> m instanceof FieldDeclaration && ((FieldDeclaration) m).getVariables().stream().anyMatch(var -> var.getId().getName().equals(name))).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 267) getMembers().stream().filter(m -> m instanceof FieldDeclaration && ((FieldDeclaration) m).getVariables().stream().anyMatch(var -> var.getId().getName().equals(name))) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 267) getMembers().stream() ==> java.util.Collection.stream()
+  Line 267) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 268) ((FieldDeclaration) m).getVariables().stream().anyMatch(var -> var.getId().getName().equals(name)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 268) ((FieldDeclaration) m).getVariables().stream() ==> java.util.Collection.stream()
+  Line 268) ((FieldDeclaration) m).getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 269) var.getId().getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 269) var.getId().getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 269) var.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 279) unmodifiableList(getMembers().stream().filter(m -> m instanceof FieldDeclaration).map(m -> (FieldDeclaration) m).collect(toList())) ==> java.util.Collections.unmodifiableList(java.util.List<? extends T>)
+  Line 279) getMembers().stream().filter(m -> m instanceof FieldDeclaration).map(m -> (FieldDeclaration) m).collect(toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 279) getMembers().stream().filter(m -> m instanceof FieldDeclaration).map(m -> (FieldDeclaration) m) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 279) getMembers().stream().filter(m -> m instanceof FieldDeclaration) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 279) getMembers().stream() ==> java.util.Collection.stream()
+  Line 279) getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 282) toList() ==> java.util.stream.Collectors.toList()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithModifiers.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithModifiers.txt
new file mode 100644
index 0000000..5199ad4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithModifiers.txt
@@ -0,0 +1,28 @@
+  Line 25) getModifiers().addAll(Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)))) ==> java.util.AbstractCollection.addAll(java.util.Collection<? extends E>)
+  Line 25) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 25) Arrays.stream(modifiers).collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 25) Arrays.stream(modifiers) ==> java.util.Arrays.stream(T[])
+  Line 26) Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class)) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
+  Line 26) EnumSet.noneOf(Modifier.class) ==> java.util.EnumSet.noneOf(java.lang.Class<E>)
+  Line 31) getModifiers().contains(Modifier.STATIC) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 31) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 35) getModifiers().contains(Modifier.ABSTRACT) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 35) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 39) getModifiers().contains(Modifier.FINAL) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 39) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 43) getModifiers().contains(Modifier.NATIVE) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 43) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 47) getModifiers().contains(Modifier.PRIVATE) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 47) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 51) getModifiers().contains(Modifier.PROTECTED) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 51) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 55) getModifiers().contains(Modifier.PUBLIC) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 55) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 59) getModifiers().contains(Modifier.STRICTFP) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 59) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 63) getModifiers().contains(Modifier.SYNCHRONIZED) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 63) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 67) getModifiers().contains(Modifier.TRANSIENT) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 67) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
+  Line 71) getModifiers().contains(Modifier.VOLATILE) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 71) getModifiers() ==> com.github.javaparser.ast.nodeTypes.NodeWithModifiers.getModifiers()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithName.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithName.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithName.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithParameters.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithParameters.txt
new file mode 100644
index 0000000..de256fd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithParameters.txt
@@ -0,0 +1,40 @@
+  Line 17) addParameter(new Parameter(type, new VariableDeclaratorId(name))) ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.body.Parameter)
+  Line 21) ((Node) this).tryAddImportToParentCompilationUnit(paramClass) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 22) addParameter(new ClassOrInterfaceType(paramClass.getSimpleName()), name) ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.type.Type, java.lang.String)
+  Line 22) paramClass.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 32) addParameter(new ClassOrInterfaceType(className), name) ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.addParameter(com.github.javaparser.ast.type.Type, java.lang.String)
+  Line 37) getParameters().add(parameter) ==> java.util.List.add(E)
+  Line 37) getParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameters()
+  Line 38) parameter.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 43) addAndGetParameter(new Parameter(type, new VariableDeclaratorId(name))) ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.body.Parameter)
+  Line 47) ((Node) this).tryAddImportToParentCompilationUnit(paramClass) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 48) addAndGetParameter(new ClassOrInterfaceType(paramClass.getSimpleName()), name) ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.type.Type, java.lang.String)
+  Line 48) paramClass.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 59) addAndGetParameter(new ClassOrInterfaceType(className), name) ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.addAndGetParameter(com.github.javaparser.ast.type.Type, java.lang.String)
+  Line 63) getParameters().add(parameter) ==> java.util.List.add(E)
+  Line 63) getParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameters()
+  Line 64) parameter.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 75) getParameters().stream().filter(p -> p.getName().equals(name)).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 75) getParameters().stream().filter(p -> p.getName().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 75) getParameters().stream().filter(p -> p.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 75) getParameters().stream() ==> java.util.Collection.stream()
+  Line 75) getParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameters()
+  Line 76) p.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 76) p.getName() ==> com.github.javaparser.ast.body.Parameter.getName()
+  Line 86) getParameters().stream().filter(p -> p.getType().toString().equals(type)).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 86) getParameters().stream().filter(p -> p.getType().toString().equals(type)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 86) getParameters().stream().filter(p -> p.getType().toString().equals(type)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 86) getParameters().stream() ==> java.util.Collection.stream()
+  Line 86) getParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameters()
+  Line 87) p.getType().toString().equals(type) ==> java.lang.String.equals(java.lang.Object)
+  Line 87) p.getType().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 87) p.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 97) getParameters().stream().filter(p -> p.getType().toString().equals(type.getSimpleName())).findFirst().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 97) getParameters().stream().filter(p -> p.getType().toString().equals(type.getSimpleName())).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 97) getParameters().stream().filter(p -> p.getType().toString().equals(type.getSimpleName())) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 97) getParameters().stream() ==> java.util.Collection.stream()
+  Line 97) getParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameters()
+  Line 98) p.getType().toString().equals(type.getSimpleName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 98) p.getType().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 98) p.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 98) type.getSimpleName() ==> java.lang.Class.getSimpleName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithStatements.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithStatements.txt
new file mode 100644
index 0000000..48bdc75
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithStatements.txt
@@ -0,0 +1,11 @@
+  Line 18) getStmts().add(statement) ==> java.util.List.add(E)
+  Line 18) getStmts() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStmts()
+  Line 19) statement.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 25) getStmts().add(index, statement) ==> java.util.List.add(int, E)
+  Line 25) getStmts() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStmts()
+  Line 26) statement.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 32) expr.setParentNode(statement) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 33) addStatement(statement) ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.addStatement(com.github.javaparser.ast.stmt.Statement)
+  Line 37) addStatement(new NameExpr(statement)) ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.addStatement(com.github.javaparser.ast.expr.Expression)
+  Line 42) expr.setParentNode(stmt) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 43) addStatement(index, stmt) ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.addStatement(int, com.github.javaparser.ast.stmt.Statement)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithThrowable.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithThrowable.txt
new file mode 100644
index 0000000..bbf27d9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithThrowable.txt
@@ -0,0 +1,13 @@
+  Line 22) getThrows().add(throwType) ==> java.util.List.add(E)
+  Line 22) getThrows() ==> com.github.javaparser.ast.nodeTypes.NodeWithThrowable.getThrows()
+  Line 23) throwType.setParentNode((Node) this) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 34) ((Node) this).tryAddImportToParentCompilationUnit(clazz) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 35) addThrows(new ClassOrInterfaceType(clazz.getSimpleName())) ==> com.github.javaparser.ast.nodeTypes.NodeWithThrowable.addThrows(com.github.javaparser.ast.type.ReferenceType)
+  Line 35) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 45) isThrows(clazz.getSimpleName()) ==> com.github.javaparser.ast.nodeTypes.NodeWithThrowable.isThrows(java.lang.String)
+  Line 45) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 55) getThrows().stream().anyMatch(t -> t.toString().equals(throwableName)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 55) getThrows().stream() ==> java.util.Collection.stream()
+  Line 55) getThrows() ==> com.github.javaparser.ast.nodeTypes.NodeWithThrowable.getThrows()
+  Line 55) t.toString().equals(throwableName) ==> java.lang.String.equals(java.lang.Object)
+  Line 55) t.toString() ==> com.github.javaparser.ast.Node.toString()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithType.txt
new file mode 100644
index 0000000..f1460c1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithType.txt
@@ -0,0 +1,4 @@
+  Line 60) ((Node) this).tryAddImportToParentCompilationUnit(typeClass) ==> com.github.javaparser.ast.Node.tryAddImportToParentCompilationUnit(java.lang.Class<?>)
+  Line 61) setType(new ClassOrInterfaceType(typeClass.getSimpleName())) ==> com.github.javaparser.ast.nodeTypes.NodeWithType.setType(com.github.javaparser.ast.type.Type<?>)
+  Line 61) typeClass.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 66) setType(classOrInterfaceType) ==> com.github.javaparser.ast.nodeTypes.NodeWithType.setType(com.github.javaparser.ast.type.Type<?>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithTypeArguments.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithTypeArguments.txt
new file mode 100644
index 0000000..b32d94c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithTypeArguments.txt
@@ -0,0 +1,7 @@
+  Line 54) getTypeArguments() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.getTypeArguments()
+  Line 57) getTypeArguments().isEmpty() ==> java.util.List.isEmpty()
+  Line 57) getTypeArguments() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.getTypeArguments()
+  Line 65) setTypeArguments(empty) ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 73) setTypeArguments((List<Type<?>>) null) ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 78) setTypeArguments(arrayToList(typeArguments)) ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 78) arrayToList(typeArguments) ==> com.github.javaparser.utils.Utils.arrayToList(T[])
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithVariables.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithVariables.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_nodeTypes_NodeWithVariables.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_AssertStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_AssertStmt.txt
new file mode 100644
index 0000000..a119c29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_AssertStmt.txt
@@ -0,0 +1,9 @@
+  Line 42) setCheck(check) ==> com.github.javaparser.ast.stmt.AssertStmt.setCheck(com.github.javaparser.ast.expr.Expression)
+  Line 46) setCheck(check) ==> com.github.javaparser.ast.stmt.AssertStmt.setCheck(com.github.javaparser.ast.expr.Expression)
+  Line 47) setMessage(msg) ==> com.github.javaparser.ast.stmt.AssertStmt.setMessage(com.github.javaparser.ast.expr.Expression)
+  Line 53) setCheck(check) ==> com.github.javaparser.ast.stmt.AssertStmt.setCheck(com.github.javaparser.ast.expr.Expression)
+  Line 54) setMessage(msg) ==> com.github.javaparser.ast.stmt.AssertStmt.setMessage(com.github.javaparser.ast.expr.Expression)
+  Line 59) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.AssertStmt, A)
+  Line 63) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.AssertStmt, A)
+  Line 76) setAsParentNodeOf(this.check) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 82) setAsParentNodeOf(this.msg) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_BlockStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_BlockStmt.txt
new file mode 100644
index 0000000..74c7737
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_BlockStmt.txt
@@ -0,0 +1,6 @@
+  Line 44) setStmts(stmts) ==> com.github.javaparser.ast.stmt.BlockStmt.setStmts(java.util.List<com.github.javaparser.ast.stmt.Statement>)
+  Line 49) setStmts(stmts) ==> com.github.javaparser.ast.stmt.BlockStmt.setStmts(java.util.List<com.github.javaparser.ast.stmt.Statement>)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.BlockStmt, A)
+  Line 59) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.BlockStmt, A)
+  Line 64) ensureNotNull(stmts) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 71) setAsParentNodeOf(this.stmts) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_BreakStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_BreakStmt.txt
new file mode 100644
index 0000000..ebb98af
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_BreakStmt.txt
@@ -0,0 +1,2 @@
+  Line 48) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.BreakStmt, A)
+  Line 52) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.BreakStmt, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_CatchClause.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_CatchClause.txt
new file mode 100644
index 0000000..70c12d2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_CatchClause.txt
@@ -0,0 +1,9 @@
+  Line 52) setParam(param) ==> com.github.javaparser.ast.stmt.CatchClause.setParam(com.github.javaparser.ast.body.Parameter)
+  Line 53) setBody(catchBlock) ==> com.github.javaparser.ast.stmt.CatchClause.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 63) setParam(new Parameter(range, exceptModifier, exceptAnnotations, exceptType, null, false, exceptId)) ==> com.github.javaparser.ast.stmt.CatchClause.setParam(com.github.javaparser.ast.body.Parameter)
+  Line 64) setBody(catchBlock) ==> com.github.javaparser.ast.stmt.CatchClause.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 68) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.CatchClause, A)
+  Line 72) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.CatchClause, A)
+  Line 99) setAsParentNodeOf(this.catchBlock) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 105) setAsParentNodeOf(this.param) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 117) setAsParentNodeOf(this.catchBlock) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ContinueStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ContinueStmt.txt
new file mode 100644
index 0000000..a50717a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ContinueStmt.txt
@@ -0,0 +1,2 @@
+  Line 48) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.ContinueStmt, A)
+  Line 52) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.ContinueStmt, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_DoStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_DoStmt.txt
new file mode 100644
index 0000000..0aeadac
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_DoStmt.txt
@@ -0,0 +1,8 @@
+  Line 43) setBody(body) ==> com.github.javaparser.ast.stmt.DoStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 44) setCondition(condition) ==> com.github.javaparser.ast.stmt.DoStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 49) setBody(body) ==> com.github.javaparser.ast.stmt.DoStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 50) setCondition(condition) ==> com.github.javaparser.ast.stmt.DoStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.DoStmt, A)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.DoStmt, A)
+  Line 73) setAsParentNodeOf(this.body) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 79) setAsParentNodeOf(this.condition) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_EmptyStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_EmptyStmt.txt
new file mode 100644
index 0000000..c0157e7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_EmptyStmt.txt
@@ -0,0 +1,2 @@
+  Line 41) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.EmptyStmt, A)
+  Line 45) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.EmptyStmt, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ExplicitConstructorInvocationStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ExplicitConstructorInvocationStmt.txt
new file mode 100644
index 0000000..3188c7f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ExplicitConstructorInvocationStmt.txt
@@ -0,0 +1,13 @@
+  Line 53) setThis(isThis) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setThis(boolean)
+  Line 54) setExpr(expr) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 55) setArgs(args) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 62) setTypeArguments(typeArguments) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 63) setThis(isThis) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setThis(boolean)
+  Line 64) setExpr(expr) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 65) setArgs(args) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setArgs(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 70) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt, A)
+  Line 75) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt, A)
+  Line 79) ensureNotNull(args) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 93) setAsParentNodeOf(this.args) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 99) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 116) setAsParentNodeOf(this.typeArguments) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ExpressionStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ExpressionStmt.txt
new file mode 100644
index 0000000..0d24152
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ExpressionStmt.txt
@@ -0,0 +1,5 @@
+  Line 40) setExpression(expr) ==> com.github.javaparser.ast.stmt.ExpressionStmt.setExpression(com.github.javaparser.ast.expr.Expression)
+  Line 46) setExpression(expr) ==> com.github.javaparser.ast.stmt.ExpressionStmt.setExpression(com.github.javaparser.ast.expr.Expression)
+  Line 50) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.ExpressionStmt, A)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.ExpressionStmt, A)
+  Line 63) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ForStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ForStmt.txt
new file mode 100644
index 0000000..beb78e0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ForStmt.txt
@@ -0,0 +1,16 @@
+  Line 52) setCompare(compare) ==> com.github.javaparser.ast.stmt.ForStmt.setCompare(com.github.javaparser.ast.expr.Expression)
+  Line 53) setInit(init) ==> com.github.javaparser.ast.stmt.ForStmt.setInit(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 54) setUpdate(update) ==> com.github.javaparser.ast.stmt.ForStmt.setUpdate(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 55) setBody(body) ==> com.github.javaparser.ast.stmt.ForStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 62) setCompare(compare) ==> com.github.javaparser.ast.stmt.ForStmt.setCompare(com.github.javaparser.ast.expr.Expression)
+  Line 63) setInit(init) ==> com.github.javaparser.ast.stmt.ForStmt.setInit(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 64) setUpdate(update) ==> com.github.javaparser.ast.stmt.ForStmt.setUpdate(java.util.List<com.github.javaparser.ast.expr.Expression>)
+  Line 65) setBody(body) ==> com.github.javaparser.ast.stmt.ForStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 70) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.ForStmt, A)
+  Line 75) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.ForStmt, A)
+  Line 88) ensureNotNull(init) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 93) ensureNotNull(update) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 100) setAsParentNodeOf(this.body) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 106) setAsParentNodeOf(this.compare) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 112) setAsParentNodeOf(this.init) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 118) setAsParentNodeOf(this.update) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ForeachStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ForeachStmt.txt
new file mode 100644
index 0000000..8ade8fa
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ForeachStmt.txt
@@ -0,0 +1,14 @@
+  Line 48) setVariable(var) ==> com.github.javaparser.ast.stmt.ForeachStmt.setVariable(com.github.javaparser.ast.expr.VariableDeclarationExpr)
+  Line 49) setIterable(iterable) ==> com.github.javaparser.ast.stmt.ForeachStmt.setIterable(com.github.javaparser.ast.expr.Expression)
+  Line 50) setBody(body) ==> com.github.javaparser.ast.stmt.ForeachStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 57) setVariable(var) ==> com.github.javaparser.ast.stmt.ForeachStmt.setVariable(com.github.javaparser.ast.expr.VariableDeclarationExpr)
+  Line 58) setIterable(iterable) ==> com.github.javaparser.ast.stmt.ForeachStmt.setIterable(com.github.javaparser.ast.expr.Expression)
+  Line 59) setBody(body) ==> com.github.javaparser.ast.stmt.ForeachStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 70) setVariable(var) ==> com.github.javaparser.ast.stmt.ForeachStmt.setVariable(com.github.javaparser.ast.expr.VariableDeclarationExpr)
+  Line 71) setIterable(new NameExpr(iterable)) ==> com.github.javaparser.ast.stmt.ForeachStmt.setIterable(com.github.javaparser.ast.expr.Expression)
+  Line 72) setBody(body) ==> com.github.javaparser.ast.stmt.ForeachStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 77) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.ForeachStmt, A)
+  Line 82) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.ForeachStmt, A)
+  Line 101) setAsParentNodeOf(this.body) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 107) setAsParentNodeOf(this.iterable) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 113) setAsParentNodeOf(this.var) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_IfStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_IfStmt.txt
new file mode 100644
index 0000000..8c9672b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_IfStmt.txt
@@ -0,0 +1,11 @@
+  Line 44) setCondition(condition) ==> com.github.javaparser.ast.stmt.IfStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 45) setThenStmt(thenStmt) ==> com.github.javaparser.ast.stmt.IfStmt.setThenStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 46) setElseStmt(elseStmt) ==> com.github.javaparser.ast.stmt.IfStmt.setElseStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 52) setCondition(condition) ==> com.github.javaparser.ast.stmt.IfStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 53) setThenStmt(thenStmt) ==> com.github.javaparser.ast.stmt.IfStmt.setThenStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 54) setElseStmt(elseStmt) ==> com.github.javaparser.ast.stmt.IfStmt.setElseStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.IfStmt, A)
+  Line 62) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.IfStmt, A)
+  Line 79) setAsParentNodeOf(this.condition) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 85) setAsParentNodeOf(this.elseStmt) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 91) setAsParentNodeOf(this.thenStmt) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_LabeledStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_LabeledStmt.txt
new file mode 100644
index 0000000..e2f3e28
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_LabeledStmt.txt
@@ -0,0 +1,7 @@
+  Line 41) setLabel(label) ==> com.github.javaparser.ast.stmt.LabeledStmt.setLabel(java.lang.String)
+  Line 42) setStmt(stmt) ==> com.github.javaparser.ast.stmt.LabeledStmt.setStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 47) setLabel(label) ==> com.github.javaparser.ast.stmt.LabeledStmt.setLabel(java.lang.String)
+  Line 48) setStmt(stmt) ==> com.github.javaparser.ast.stmt.LabeledStmt.setStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 52) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.LabeledStmt, A)
+  Line 56) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.LabeledStmt, A)
+  Line 74) setAsParentNodeOf(this.stmt) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ReturnStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ReturnStmt.txt
new file mode 100644
index 0000000..8df9374
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ReturnStmt.txt
@@ -0,0 +1,6 @@
+  Line 41) setExpr(expr) ==> com.github.javaparser.ast.stmt.ReturnStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 46) setExpr(expr) ==> com.github.javaparser.ast.stmt.ReturnStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 55) setExpr(new NameExpr(expr)) ==> com.github.javaparser.ast.stmt.ReturnStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 60) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.ReturnStmt, A)
+  Line 64) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.ReturnStmt, A)
+  Line 73) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_Statement.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_Statement.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_Statement.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SwitchEntryStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SwitchEntryStmt.txt
new file mode 100644
index 0000000..f77d3bd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SwitchEntryStmt.txt
@@ -0,0 +1,9 @@
+  Line 47) setLabel(label) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.setLabel(com.github.javaparser.ast.expr.Expression)
+  Line 48) setStmts(stmts) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.setStmts(java.util.List<com.github.javaparser.ast.stmt.Statement>)
+  Line 54) setLabel(label) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.setLabel(com.github.javaparser.ast.expr.Expression)
+  Line 55) setStmts(stmts) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.setStmts(java.util.List<com.github.javaparser.ast.stmt.Statement>)
+  Line 60) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.SwitchEntryStmt, A)
+  Line 65) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.SwitchEntryStmt, A)
+  Line 74) ensureNotNull(stmts) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 80) setAsParentNodeOf(this.label) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 87) setAsParentNodeOf(this.stmts) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SwitchStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SwitchStmt.txt
new file mode 100644
index 0000000..6203389
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SwitchStmt.txt
@@ -0,0 +1,9 @@
+  Line 47) setSelector(selector) ==> com.github.javaparser.ast.stmt.SwitchStmt.setSelector(com.github.javaparser.ast.expr.Expression)
+  Line 48) setEntries(entries) ==> com.github.javaparser.ast.stmt.SwitchStmt.setEntries(java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>)
+  Line 54) setSelector(selector) ==> com.github.javaparser.ast.stmt.SwitchStmt.setSelector(com.github.javaparser.ast.expr.Expression)
+  Line 55) setEntries(entries) ==> com.github.javaparser.ast.stmt.SwitchStmt.setEntries(java.util.List<com.github.javaparser.ast.stmt.SwitchEntryStmt>)
+  Line 60) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.SwitchStmt, A)
+  Line 65) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.SwitchStmt, A)
+  Line 69) ensureNotNull(entries) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 79) setAsParentNodeOf(this.entries) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 85) setAsParentNodeOf(this.selector) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SynchronizedStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SynchronizedStmt.txt
new file mode 100644
index 0000000..bf73a33
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_SynchronizedStmt.txt
@@ -0,0 +1,9 @@
+  Line 43) setExpr(expr) ==> com.github.javaparser.ast.stmt.SynchronizedStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 44) setBlock(block) ==> com.github.javaparser.ast.stmt.SynchronizedStmt.setBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 50) setExpr(expr) ==> com.github.javaparser.ast.stmt.SynchronizedStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 51) setBlock(block) ==> com.github.javaparser.ast.stmt.SynchronizedStmt.setBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 56) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.SynchronizedStmt, A)
+  Line 61) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.SynchronizedStmt, A)
+  Line 84) setAsParentNodeOf(this.block) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 90) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 102) setAsParentNodeOf(this.block) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ThrowStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ThrowStmt.txt
new file mode 100644
index 0000000..fc65737
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_ThrowStmt.txt
@@ -0,0 +1,5 @@
+  Line 40) setExpr(expr) ==> com.github.javaparser.ast.stmt.ThrowStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 45) setExpr(expr) ==> com.github.javaparser.ast.stmt.ThrowStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.ThrowStmt, A)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.ThrowStmt, A)
+  Line 62) setAsParentNodeOf(this.expr) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_TryStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_TryStmt.txt
new file mode 100644
index 0000000..8182522
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_TryStmt.txt
@@ -0,0 +1,15 @@
+  Line 51) setTryBlock(tryBlock) ==> com.github.javaparser.ast.stmt.TryStmt.setTryBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 52) setCatchs(catchs) ==> com.github.javaparser.ast.stmt.TryStmt.setCatchs(java.util.List<com.github.javaparser.ast.stmt.CatchClause>)
+  Line 53) setFinallyBlock(finallyBlock) ==> com.github.javaparser.ast.stmt.TryStmt.setFinallyBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 59) setResources(resources) ==> com.github.javaparser.ast.stmt.TryStmt.setResources(java.util.List<com.github.javaparser.ast.expr.VariableDeclarationExpr>)
+  Line 60) setTryBlock(tryBlock) ==> com.github.javaparser.ast.stmt.TryStmt.setTryBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 61) setCatchs(catchs) ==> com.github.javaparser.ast.stmt.TryStmt.setCatchs(java.util.List<com.github.javaparser.ast.stmt.CatchClause>)
+  Line 62) setFinallyBlock(finallyBlock) ==> com.github.javaparser.ast.stmt.TryStmt.setFinallyBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 67) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.TryStmt, A)
+  Line 72) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.TryStmt, A)
+  Line 76) ensureNotNull(catchs) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 89) ensureNotNull(resources) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 95) setAsParentNodeOf(this.catchs) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 101) setAsParentNodeOf(this.finallyBlock) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 107) setAsParentNodeOf(this.tryBlock) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 113) setAsParentNodeOf(this.resources) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_TypeDeclarationStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_TypeDeclarationStmt.txt
new file mode 100644
index 0000000..4eadbca
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_TypeDeclarationStmt.txt
@@ -0,0 +1,5 @@
+  Line 40) setTypeDeclaration(typeDecl) ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.setTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration)
+  Line 45) setTypeDeclaration(typeDecl) ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.setTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration)
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.TypeDeclarationStmt, A)
+  Line 53) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.TypeDeclarationStmt, A)
+  Line 62) setAsParentNodeOf(this.typeDecl) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_WhileStmt.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_WhileStmt.txt
new file mode 100644
index 0000000..74f0cdd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_stmt_WhileStmt.txt
@@ -0,0 +1,8 @@
+  Line 43) setCondition(condition) ==> com.github.javaparser.ast.stmt.WhileStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 44) setBody(body) ==> com.github.javaparser.ast.stmt.WhileStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 49) setCondition(condition) ==> com.github.javaparser.ast.stmt.WhileStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 50) setBody(body) ==> com.github.javaparser.ast.stmt.WhileStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 54) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.stmt.WhileStmt, A)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.stmt.WhileStmt, A)
+  Line 73) setAsParentNodeOf(this.body) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 79) setAsParentNodeOf(this.condition) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ArrayType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ArrayType.txt
new file mode 100644
index 0000000..32d5df4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ArrayType.txt
@@ -0,0 +1,14 @@
+  Line 23) setComponentType(componentType) ==> com.github.javaparser.ast.type.ArrayType.setComponentType(com.github.javaparser.ast.type.Type)
+  Line 24) setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 29) setComponentType(componentType) ==> com.github.javaparser.ast.type.ArrayType.setComponentType(com.github.javaparser.ast.type.Type)
+  Line 30) setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 34) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.ArrayType, A)
+  Line 38) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.ArrayType, A)
+  Line 47) setAsParentNodeOf(this.componentType) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 60) arrayBracketPairList.size() ==> java.util.List.size()
+  Line 61) arrayBracketPairList.get(j).getAnnotations() ==> com.github.javaparser.ast.ArrayBracketPair.getAnnotations()
+  Line 61) arrayBracketPairList.get(j) ==> java.util.List.get(int)
+  Line 77) arrayBracketPairs.add(new ArrayBracketPair(Range.UNKNOWN, arrayType.getAnnotations())) ==> java.util.List.add(E)
+  Line 77) arrayType.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 78) arrayType.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 84) Arrays.asList(annotations) ==> java.util.Arrays.asList(T...)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ClassOrInterfaceType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ClassOrInterfaceType.txt
new file mode 100644
index 0000000..92ee275
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ClassOrInterfaceType.txt
@@ -0,0 +1,13 @@
+  Line 53) setName(name) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.setName(java.lang.String)
+  Line 57) setScope(scope) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.setScope(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 58) setName(name) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.setName(java.lang.String)
+  Line 63) setScope(scope) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.setScope(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 64) setName(name) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.setName(java.lang.String)
+  Line 65) setTypeArguments(typeArguments) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.setTypeArguments(java.util.List<com.github.javaparser.ast.type.Type<?>>)
+  Line 69) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.ClassOrInterfaceType, A)
+  Line 73) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.ClassOrInterfaceType, A)
+  Line 86) PrimitiveType.unboxMap.containsKey(name) ==> java.util.HashMap.containsKey(java.lang.Object)
+  Line 90) isBoxedType() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.isBoxedType()
+  Line 93) PrimitiveType.unboxMap.get(name) ==> java.util.HashMap.get(java.lang.Object)
+  Line 104) setAsParentNodeOf(this.scope) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 116) setAsParentNodeOf(this.typeArguments) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_IntersectionType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_IntersectionType.txt
new file mode 100644
index 0000000..ba562aa
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_IntersectionType.txt
@@ -0,0 +1,6 @@
+  Line 28) setElements(elements) ==> com.github.javaparser.ast.type.IntersectionType.setElements(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 33) setElements(elements) ==> com.github.javaparser.ast.type.IntersectionType.setElements(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 38) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.IntersectionType, A)
+  Line 43) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.IntersectionType, A)
+  Line 53) element.setParentNode(null) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 57) setAsParentNodeOf(this.elements) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_PrimitiveType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_PrimitiveType.txt
new file mode 100644
index 0000000..d2527c2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_PrimitiveType.txt
@@ -0,0 +1,6 @@
+  Line 77) Primitive.values() ==> com.github.javaparser.ast.type.PrimitiveType.Primitive.values()
+  Line 78) unboxMap.put(unboxedType.nameOfBoxedType, unboxedType) ==> java.util.HashMap.put(K, V)
+  Line 93) setType(type) ==> com.github.javaparser.ast.type.PrimitiveType.setType(com.github.javaparser.ast.type.PrimitiveType.Primitive)
+  Line 97) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.PrimitiveType, A)
+  Line 101) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.PrimitiveType, A)
+  Line 109) type.toBoxedType() ==> com.github.javaparser.ast.type.PrimitiveType.Primitive.toBoxedType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ReferenceType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ReferenceType.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_ReferenceType.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_Type.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_Type.txt
new file mode 100644
index 0000000..e3ffee4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_Type.txt
@@ -0,0 +1,3 @@
+  Line 53) setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 57) ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 62) setAsParentNodeOf(annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_TypeParameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_TypeParameter.txt
new file mode 100644
index 0000000..8e2ddb4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_TypeParameter.txt
@@ -0,0 +1,12 @@
+  Line 59) setName(name) ==> com.github.javaparser.ast.type.TypeParameter.setName(java.lang.String)
+  Line 60) setTypeBound(typeBound) ==> com.github.javaparser.ast.type.TypeParameter.setTypeBound(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 65) setName(name) ==> com.github.javaparser.ast.type.TypeParameter.setName(java.lang.String)
+  Line 66) setTypeBound(typeBound) ==> com.github.javaparser.ast.type.TypeParameter.setTypeBound(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 71) setTypeBound(typeBound) ==> com.github.javaparser.ast.type.TypeParameter.setTypeBound(java.util.List<com.github.javaparser.ast.type.ClassOrInterfaceType>)
+  Line 72) setAnnotations(annotations) ==> com.github.javaparser.ast.type.TypeParameter.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 76) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.TypeParameter, A)
+  Line 80) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.TypeParameter, A)
+  Line 100) ensureNotNull(typeBound) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 124) setAsParentNodeOf(typeBound) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 129) ensureNotNull(annotations) ==> com.github.javaparser.utils.Utils.ensureNotNull(java.util.List<T>)
+  Line 135) setAsParentNodeOf(this.annotations) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_UnionType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_UnionType.txt
new file mode 100644
index 0000000..14e6644
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_UnionType.txt
@@ -0,0 +1,6 @@
+  Line 20) setElements(elements) ==> com.github.javaparser.ast.type.UnionType.setElements(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 25) setElements(elements) ==> com.github.javaparser.ast.type.UnionType.setElements(java.util.List<com.github.javaparser.ast.type.ReferenceType>)
+  Line 35) element.setParentNode(null) ==> com.github.javaparser.ast.Node.setParentNode(com.github.javaparser.ast.Node)
+  Line 39) setAsParentNodeOf(this.elements) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(java.util.List<? extends com.github.javaparser.ast.Node>)
+  Line 45) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.UnionType, A)
+  Line 50) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.UnionType, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_UnknownType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_UnknownType.txt
new file mode 100644
index 0000000..012f4dc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_UnknownType.txt
@@ -0,0 +1,2 @@
+  Line 44) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.UnknownType, A)
+  Line 49) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.UnknownType, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_VoidType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_VoidType.txt
new file mode 100644
index 0000000..a18fc53
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_VoidType.txt
@@ -0,0 +1,2 @@
+  Line 44) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.VoidType, A)
+  Line 48) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.VoidType, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_WildcardType.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_WildcardType.txt
new file mode 100644
index 0000000..adee3ad
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_type_WildcardType.txt
@@ -0,0 +1,9 @@
+  Line 42) setExtends(ext) ==> com.github.javaparser.ast.type.WildcardType.setExtends(com.github.javaparser.ast.type.ReferenceType)
+  Line 46) setExtends(ext) ==> com.github.javaparser.ast.type.WildcardType.setExtends(com.github.javaparser.ast.type.ReferenceType)
+  Line 47) setSuper(sup) ==> com.github.javaparser.ast.type.WildcardType.setSuper(com.github.javaparser.ast.type.ReferenceType)
+  Line 53) setExtends(ext) ==> com.github.javaparser.ast.type.WildcardType.setExtends(com.github.javaparser.ast.type.ReferenceType)
+  Line 54) setSuper(sup) ==> com.github.javaparser.ast.type.WildcardType.setSuper(com.github.javaparser.ast.type.ReferenceType)
+  Line 58) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.GenericVisitor.visit(com.github.javaparser.ast.type.WildcardType, A)
+  Line 62) v.visit(this, arg) ==> com.github.javaparser.ast.visitor.VoidVisitor.visit(com.github.javaparser.ast.type.WildcardType, A)
+  Line 75) setAsParentNodeOf(this.ext) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
+  Line 81) setAsParentNodeOf(this.sup) ==> com.github.javaparser.ast.Node.setAsParentNodeOf(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_CloneVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_CloneVisitor.txt
new file mode 100644
index 0000000..110f55a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_CloneVisitor.txt
@@ -0,0 +1,690 @@
+  Line 114) cloneNodes(_n.getPackage(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 114) _n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 115) visit(_n.getImports(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 115) _n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 116) visit(_n.getTypes(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 116) _n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 119) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 126) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 126) _n.getAnnotations() ==> com.github.javaparser.ast.PackageDeclaration.getAnnotations()
+  Line 127) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 127) _n.getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 128) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 128) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 131) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 134) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 140) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 140) _n.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 141) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 141) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 144) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 145) _n.isStatic() ==> com.github.javaparser.ast.ImportDeclaration.isStatic()
+  Line 145) _n.isAsterisk() ==> com.github.javaparser.ast.ImportDeclaration.isAsterisk()
+  Line 147) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 153) visit(_n.getTypeBound(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 153) _n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 155) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 155) _n.getAnnotations() ==> com.github.javaparser.ast.type.TypeParameter.getAnnotations()
+  Line 156) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 157) _n.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 159) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 159) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 160) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 166) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 166) _n.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 171) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 171) _n.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 176) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 176) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 177) visit(_n.getTypeParameters(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 177) _n.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 178) visit(_n.getExtends(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 178) _n.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 179) visit(_n.getImplements(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 179) _n.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 180) visit(_n.getMembers(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 180) _n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 181) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 181) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 184) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 185) _n.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 185) _n.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 185) _n.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 187) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 193) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 193) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 194) visit(_n.getImplements(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 194) _n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 195) visit(_n.getEntries(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 195) _n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 196) visit(_n.getMembers(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 196) _n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 197) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 197) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 200) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 201) _n.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 201) _n.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 203) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 209) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 209) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 212) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 214) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 220) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 220) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 221) visit(_n.getArgs(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 221) _n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 222) visit(_n.getClassBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 222) _n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 223) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 223) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 226) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 227) _n.getName() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getName()
+  Line 229) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 235) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 235) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 236) visit(_n.getMembers(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 236) _n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 237) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 237) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 240) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 241) _n.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 241) _n.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 243) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 249) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 249) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 250) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 250) _n.getType() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getType()
+  Line 251) cloneNodes(_n.getDefaultValue(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 251) _n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 252) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 252) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 255) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 256) _n.getModifiers() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getModifiers()
+  Line 256) _n.getName() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getName()
+  Line 258) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 264) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 264) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 265) cloneNodes(_n.getElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 265) _n.getElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getElementType()
+  Line 266) visit(_n.getVariables(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 266) _n.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 267) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 267) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 268) visit(_n.getArrayBracketPairsAfterElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 268) _n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getArrayBracketPairsAfterElementType()
+  Line 271) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 272) _n.getModifiers() ==> com.github.javaparser.ast.body.FieldDeclaration.getModifiers()
+  Line 279) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 285) cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 285) _n.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 286) cloneNodes(_n.getInit(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 286) _n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 287) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 287) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 290) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 293) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 299) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 299) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 300) visit(_n.getArrayBracketPairsAfterId(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 300) _n.getArrayBracketPairsAfterId() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()
+  Line 303) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 304) _n.getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 307) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 313) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 313) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 314) visit(_n.getTypeParameters(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 314) _n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 315) visit(_n.getParameters(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 315) _n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 316) visit(_n.getThrows(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 316) _n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 317) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 317) _n.getBody() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getBody()
+  Line 318) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 318) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 321) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 322) _n.getModifiers() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()
+  Line 322) _n.getName() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getName()
+  Line 324) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 330) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 330) _n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 331) visit(_n.getTypeParameters(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 331) _n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 332) cloneNodes(_n.getElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 332) _n.getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 333) cloneNodes(_n.getNameExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 333) _n.getNameExpr() ==> com.github.javaparser.ast.body.MethodDeclaration.getNameExpr()
+  Line 334) visit(_n.getParameters(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 334) _n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 335) visit(_n.getThrows(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 335) _n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 336) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 336) _n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 337) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 337) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 338) visit(_n.getArrayBracketPairsAfterElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 338) _n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterElementType()
+  Line 339) visit(_n.getArrayBracketPairsAfterParameterList(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 339) _n.getArrayBracketPairsAfterParameterList() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterParameterList()
+  Line 342) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 343) _n.getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 354) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 360) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 360) _n.getAnnotations() ==> com.github.javaparser.ast.body.Parameter.getAnnotations()
+  Line 361) cloneNodes(_n.getElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 361) _n.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 362) cloneNodes(_n.getId(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 362) _n.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 363) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 363) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 364) visit(_n.getArrayBracketPairsAfterElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 364) _n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.Parameter.getArrayBracketPairsAfterElementType()
+  Line 367) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 368) _n.getModifiers() ==> com.github.javaparser.ast.body.Parameter.getModifiers()
+  Line 372) _n.isVarArgs() ==> com.github.javaparser.ast.body.Parameter.isVarArgs()
+  Line 375) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 381) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 381) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 384) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 386) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 392) cloneNodes(_n.getBlock(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 392) _n.getBlock() ==> com.github.javaparser.ast.body.InitializerDeclaration.getBlock()
+  Line 393) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 393) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 396) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 397) _n.isStatic() ==> com.github.javaparser.ast.body.InitializerDeclaration.isStatic()
+  Line 399) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 405) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 405) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 407) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 408) _n.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 410) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 416) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 416) _n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 417) visit(_n.getTypeArguments(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 417) _n.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 418) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 418) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 421) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 423) _n.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 424) _n.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 426) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 432) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 432) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 433) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 433) _n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 436) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 437) _n.getType() ==> com.github.javaparser.ast.type.PrimitiveType.getType()
+  Line 439) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 440) r.setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 446) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 446) _n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 447) cloneNodes(_n.getComponentType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 447) _n.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 449) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 450) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 450) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 451) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 457) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 457) _n.getAnnotations() ==> com.github.javaparser.ast.ArrayCreationLevel.getAnnotations()
+  Line 458) cloneNodes(_n.getDimension(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 458) _n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 460) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 462) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 462) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 463) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 469) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 469) _n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 470) visit(_n.getElements(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 470) _n.getElements() ==> com.github.javaparser.ast.type.IntersectionType.getElements()
+  Line 472) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 473) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 473) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 474) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 475) r.setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 481) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 481) _n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 482) visit(_n.getElements(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 482) _n.getElements() ==> com.github.javaparser.ast.type.UnionType.getElements()
+  Line 484) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 486) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 486) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 487) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 488) r.setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 494) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 494) _n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 495) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 495) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 497) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 498) r.setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 499) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 505) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 505) _n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 506) cloneNodes(_n.getExtends(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 506) _n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 507) cloneNodes(_n.getSuper(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 507) _n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 508) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 508) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 511) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 514) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 515) r.setAnnotations(annotations) ==> com.github.javaparser.ast.type.Type.setAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>)
+  Line 521) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 521) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 524) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 530) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 530) _n.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 531) cloneNodes(_n.getIndex(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 531) _n.getIndex() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getIndex()
+  Line 532) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 532) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 535) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 538) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 544) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 544) _n.getType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getType()
+  Line 545) visit(_n.getLevels(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 545) _n.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 546) cloneNodes(_n.getInitializer(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 546) _n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 548) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 550) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 550) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 551) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 557) visit(_n.getValues(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 557) _n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 558) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 558) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 561) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 564) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 570) cloneNodes(_n.getTarget(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 570) _n.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 571) cloneNodes(_n.getValue(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 571) _n.getValue() ==> com.github.javaparser.ast.expr.AssignExpr.getValue()
+  Line 572) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 572) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 575) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 576) _n.getOperator() ==> com.github.javaparser.ast.expr.AssignExpr.getOperator()
+  Line 577) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 583) cloneNodes(_n.getLeft(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 583) _n.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 584) cloneNodes(_n.getRight(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 584) _n.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 585) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 585) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 588) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 589) _n.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 591) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 597) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 597) _n.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 598) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 598) _n.getExpr() ==> com.github.javaparser.ast.expr.CastExpr.getExpr()
+  Line 599) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 599) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 602) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 605) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 611) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 611) _n.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 612) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 612) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 615) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 618) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 624) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 624) _n.getCondition() ==> com.github.javaparser.ast.expr.ConditionalExpr.getCondition()
+  Line 625) cloneNodes(_n.getThenExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 625) _n.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 626) cloneNodes(_n.getElseExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 626) _n.getElseExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getElseExpr()
+  Line 627) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 627) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 630) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 633) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 639) cloneNodes(_n.getInner(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 639) _n.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 640) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 640) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 643) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 646) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 652) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 652) _n.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 653) visit(_n.getTypeArguments(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 653) _n.getTypeArguments() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getTypeArguments()
+  Line 654) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 654) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 657) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 660) _n.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 662) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 668) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 668) _n.getExpr() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getExpr()
+  Line 669) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 669) _n.getType() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getType()
+  Line 670) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 670) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 673) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 676) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 682) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 682) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 684) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 685) _n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 687) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 693) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 693) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 696) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 697) _n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 699) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 705) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 705) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 708) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 709) _n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 711) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 717) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 717) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 719) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 720) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 726) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 726) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 728) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 729) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 735) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 735) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 738) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 739) _n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 741) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 747) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 747) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 750) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 751) _n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 753) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 759) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 759) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 762) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 763) _n.getValue() ==> com.github.javaparser.ast.expr.BooleanLiteralExpr.getValue()
+  Line 765) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 771) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 771) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 773) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 774) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 780) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 780) _n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 781) visit(_n.getTypeArguments(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 781) _n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 782) visit(_n.getArgs(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 782) _n.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 783) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 783) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 786) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 789) _n.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 792) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 798) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 798) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 801) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 802) _n.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 804) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 810) cloneNodes(_n.getScope(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 810) _n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 811) cloneNodes(_n.getType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 811) _n.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 812) visit(_n.getTypeArguments(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 812) _n.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 813) visit(_n.getArgs(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 813) _n.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 814) visit(_n.getAnonymousClassBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 814) _n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 815) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 815) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 818) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 821) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 827) cloneNodes(_n.getQualifier(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 827) _n.getQualifier() ==> com.github.javaparser.ast.expr.QualifiedNameExpr.getQualifier()
+  Line 828) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 828) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 831) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 832) _n.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 834) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 840) cloneNodes(_n.getClassExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 840) _n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 841) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 841) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 844) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 847) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 853) cloneNodes(_n.getClassExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 853) _n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 854) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 854) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 857) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 860) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 866) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 866) _n.getExpr() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpr()
+  Line 867) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 867) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 870) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 871) _n.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 873) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 879) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 879) _n.getAnnotations() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getAnnotations()
+  Line 880) cloneNodes(_n.getElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 880) _n.getElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getElementType()
+  Line 881) visit(_n.getVariables(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 881) _n.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 882) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 882) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 883) visit(_n.getArrayBracketPairsAfterElementType(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 883) _n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getArrayBracketPairsAfterElementType()
+  Line 886) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 887) _n.getModifiers() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getModifiers()
+  Line 893) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 899) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 899) _n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 900) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 900) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 903) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 906) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 912) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 912) _n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 913) cloneNodes(_n.getMemberValue(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 913) _n.getMemberValue() ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.getMemberValue()
+  Line 914) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 914) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 917) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 920) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 926) cloneNodes(_n.getName(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 926) _n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 927) visit(_n.getPairs(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 927) _n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 928) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 928) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 931) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 934) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 940) cloneNodes(_n.getValue(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 940) _n.getValue() ==> com.github.javaparser.ast.expr.MemberValuePair.getValue()
+  Line 941) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 941) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 944) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 945) _n.getName() ==> com.github.javaparser.ast.expr.MemberValuePair.getName()
+  Line 947) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 953) visit(_n.getTypeArguments(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 953) _n.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 954) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 954) _n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 955) visit(_n.getArgs(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 955) _n.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 956) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 956) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 959) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 961) _n.isThis() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.isThis()
+  Line 965) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 971) cloneNodes(_n.getTypeDeclaration(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 971) _n.getTypeDeclaration() ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.getTypeDeclaration()
+  Line 972) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 972) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 975) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 978) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 984) cloneNodes(_n.getCheck(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 984) _n.getCheck() ==> com.github.javaparser.ast.stmt.AssertStmt.getCheck()
+  Line 985) cloneNodes(_n.getMessage(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 985) _n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 986) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 986) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 989) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 992) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 998) visit(_n.getStmts(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 998) _n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 999) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 999) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1002) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1005) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1011) cloneNodes(_n.getStmt(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1011) _n.getStmt() ==> com.github.javaparser.ast.stmt.LabeledStmt.getStmt()
+  Line 1012) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1012) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1015) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1016) _n.getLabel() ==> com.github.javaparser.ast.stmt.LabeledStmt.getLabel()
+  Line 1018) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1024) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1024) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1026) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1027) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1033) cloneNodes(_n.getExpression(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1033) _n.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 1034) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1034) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1037) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1040) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1046) cloneNodes(_n.getSelector(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1046) _n.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 1047) visit(_n.getEntries(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1047) _n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 1048) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1048) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1051) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1054) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1060) cloneNodes(_n.getLabel(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1060) _n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 1061) visit(_n.getStmts(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1061) _n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 1062) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1062) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1065) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1068) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1074) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1074) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1077) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1078) _n.getId() ==> com.github.javaparser.ast.stmt.BreakStmt.getId()
+  Line 1080) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1086) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1086) _n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 1087) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1087) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1090) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1093) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1099) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1099) _n.getCondition() ==> com.github.javaparser.ast.stmt.IfStmt.getCondition()
+  Line 1100) cloneNodes(_n.getThenStmt(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1100) _n.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 1101) cloneNodes(_n.getElseStmt(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1101) _n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 1102) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1102) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1105) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1108) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1114) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1114) _n.getCondition() ==> com.github.javaparser.ast.stmt.WhileStmt.getCondition()
+  Line 1115) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1115) _n.getBody() ==> com.github.javaparser.ast.stmt.WhileStmt.getBody()
+  Line 1116) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1116) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1119) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1122) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1128) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1128) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1131) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1132) _n.getId() ==> com.github.javaparser.ast.stmt.ContinueStmt.getId()
+  Line 1134) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1140) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1140) _n.getBody() ==> com.github.javaparser.ast.stmt.DoStmt.getBody()
+  Line 1141) cloneNodes(_n.getCondition(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1141) _n.getCondition() ==> com.github.javaparser.ast.stmt.DoStmt.getCondition()
+  Line 1142) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1142) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1145) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1148) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1154) cloneNodes(_n.getVariable(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1154) _n.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 1155) cloneNodes(_n.getIterable(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1155) _n.getIterable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getIterable()
+  Line 1156) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1156) _n.getBody() ==> com.github.javaparser.ast.stmt.ForeachStmt.getBody()
+  Line 1157) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1157) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1160) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1163) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1169) visit(_n.getInit(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1169) _n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 1170) cloneNodes(_n.getCompare(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1170) _n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 1171) visit(_n.getUpdate(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1171) _n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 1172) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1172) _n.getBody() ==> com.github.javaparser.ast.stmt.ForStmt.getBody()
+  Line 1173) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1173) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1176) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1179) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1185) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1185) _n.getExpr() ==> com.github.javaparser.ast.stmt.ThrowStmt.getExpr()
+  Line 1186) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1186) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1189) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1192) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1198) cloneNodes(_n.getExpr(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1198) _n.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 1199) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1199) _n.getBody() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getBody()
+  Line 1200) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1200) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1203) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1206) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1212) visit(_n.getResources(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1212) _n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1213) cloneNodes(_n.getTryBlock(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1213) _n.getTryBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getTryBlock()
+  Line 1214) visit(_n.getCatchs(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1214) _n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 1215) cloneNodes(_n.getFinallyBlock(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1215) _n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 1216) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1216) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1219) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1222) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1228) cloneNodes(_n.getParam(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1228) _n.getParam() ==> com.github.javaparser.ast.stmt.CatchClause.getParam()
+  Line 1229) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1229) _n.getBody() ==> com.github.javaparser.ast.stmt.CatchClause.getBody()
+  Line 1230) cloneNodes(_n.getComment(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1230) _n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1233) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1234) param.getModifiers() ==> com.github.javaparser.ast.body.Parameter.getModifiers()
+  Line 1234) param.getAnnotations() ==> com.github.javaparser.ast.body.Parameter.getAnnotations()
+  Line 1234) param.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 1234) param.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 1236) r.setComment(comment) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1243) visit(_n.getParameters(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1243) _n.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 1245) cloneNodes(_n.getBody(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1245) _n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1247) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1248) _n.isParametersEnclosed() ==> com.github.javaparser.ast.expr.LambdaExpr.isParametersEnclosed()
+  Line 1254) cloneNodes(_n.getScope(), arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1254) _n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1256) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1257) _n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1257) _n.getIdentifier() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getIdentifier()
+  Line 1263) cloneNodes(n.getType(), arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1263) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1265) n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1270) visit(_n.getAnnotations(), _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.visit(java.util.List<T>, java.lang.Object)
+  Line 1270) _n.getAnnotations() ==> com.github.javaparser.ast.ArrayBracketPair.getAnnotations()
+  Line 1272) _n.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 1278) _nodes.size() ==> java.util.List.size()
+  Line 1280) cloneNodes(n, _arg) ==> com.github.javaparser.ast.visitor.CloneVisitor.cloneNodes(T, java.lang.Object)
+  Line 1282) r.add(rN) ==> java.util.List.add(E)
+  Line 1291) _node.accept(this, _arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_DumpVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_DumpVisitor.txt
new file mode 100644
index 0000000..3101758
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_DumpVisitor.txt
@@ -0,0 +1,1066 @@
+  Line 86) buf.append(indentation) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 92) makeIndent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.makeIndent()
+  Line 95) buf.append(arg) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 99) print(arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 100) printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 104) buf.append(EOL) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 109) buf.toString() ==> java.lang.StringBuilder.toString()
+  Line 114) getSource() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.getSource()
+  Line 118) createSourcePrinter() ==> com.github.javaparser.ast.visitor.DumpVisitor.createSourcePrinter()
+  Line 125) printer.getSource() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.getSource()
+  Line 129) modifiers.size() ==> java.util.AbstractCollection.size()
+  Line 130) printer.print(modifiers.stream().map(Modifier::getLib).collect(Collectors.joining(" ")) + " ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 130) modifiers.stream().map(Modifier::getLib).collect(Collectors.joining(" ")) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 130) modifiers.stream().map(Modifier::getLib) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 130) modifiers.stream() ==> java.util.Collection.stream()
+  Line 130) Collectors.joining(" ") ==> java.util.stream.Collectors.joining(java.lang.CharSequence)
+  Line 135) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 136) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 137) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 142) isNullOrEmpty(annotations) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 144) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 145) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 151) isNullOrEmpty(annotations) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 153) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 156) annotation.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 157) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 163) nodeWithTypeArguments.getTypeArguments() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.getTypeArguments()
+  Line 164) isNullOrEmpty(typeArguments) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 165) printer.print("<") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 166) typeArguments.iterator() ==> java.util.List.iterator()
+  Line 166) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 167) i.next() ==> java.util.Iterator.next()
+  Line 168) t.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 169) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 170) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 173) printer.print(">") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 178) isNullOrEmpty(args) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 179) printer.print("<") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 180) args.iterator() ==> java.util.List.iterator()
+  Line 180) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 181) i.next() ==> java.util.Iterator.next()
+  Line 182) t.accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 183) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 184) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 187) printer.print(">") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 192) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 193) isNullOrEmpty(args) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 194) args.iterator() ==> java.util.List.iterator()
+  Line 194) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 195) i.next() ==> java.util.Iterator.next()
+  Line 196) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 197) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 198) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 202) printer.print(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 207) javacomment.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 213) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 213) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 215) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 216) n.getPackage().accept(this, arg) ==> com.github.javaparser.ast.PackageDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 216) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 219) isNullOrEmpty(n.getImports()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 219) n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 220) n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 221) i.accept(this, arg) ==> com.github.javaparser.ast.ImportDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 223) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 226) isNullOrEmpty(n.getTypes()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 226) n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 227) n.getTypes().iterator() ==> java.util.List.iterator()
+  Line 227) n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 227) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 228) i.next().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 228) i.next() ==> java.util.Iterator.next()
+  Line 229) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 230) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 231) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 236) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 241) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 241) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 242) printAnnotations(n.getAnnotations(), false, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 242) n.getAnnotations() ==> com.github.javaparser.ast.PackageDeclaration.getAnnotations()
+  Line 243) printer.print("package ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 244) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 244) n.getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 245) printer.printLn(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 246) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 248) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 253) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 253) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 254) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 254) n.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 256) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 261) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 261) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 262) n.getQualifier().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 262) n.getQualifier() ==> com.github.javaparser.ast.expr.QualifiedNameExpr.getQualifier()
+  Line 263) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 264) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 264) n.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 266) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 271) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 271) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 272) n.isEmptyImportDeclaration() ==> com.github.javaparser.ast.ImportDeclaration.isEmptyImportDeclaration()
+  Line 273) printer.print("import ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 274) n.isStatic() ==> com.github.javaparser.ast.ImportDeclaration.isStatic()
+  Line 275) printer.print("static ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 277) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 277) n.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 278) n.isAsterisk() ==> com.github.javaparser.ast.ImportDeclaration.isAsterisk()
+  Line 279) printer.print(".*") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 282) printer.printLn(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 284) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 289) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 289) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 290) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 290) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 291) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 291) n.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 293) n.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 294) printer.print("interface ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 296) printer.print("class ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 299) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 299) n.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 301) printTypeParameters(n.getTypeParameters(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.Object)
+  Line 301) n.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 303) isNullOrEmpty(n.getExtends()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 303) n.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 304) printer.print(" extends ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 305) n.getExtends().iterator() ==> java.util.List.iterator()
+  Line 305) n.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 305) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 306) i.next() ==> java.util.Iterator.next()
+  Line 307) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 308) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 309) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 314) isNullOrEmpty(n.getImplements()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 314) n.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 315) printer.print(" implements ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 316) n.getImplements().iterator() ==> java.util.List.iterator()
+  Line 316) n.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 316) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 317) i.next() ==> java.util.Iterator.next()
+  Line 318) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 319) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 320) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 325) printer.printLn(" {") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 326) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 327) isNullOrEmpty(n.getMembers()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 327) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 328) printMembers(n.getMembers(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>, java.lang.Object)
+  Line 328) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 331) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 333) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 334) printer.print("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 339) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 339) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 340) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 342) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 347) printer.print("/**") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 348) printer.print(n.getContent()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 348) n.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 349) printer.printLn("*/") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 354) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 354) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 356) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 357) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 357) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 358) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 360) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 361) ae.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 362) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 365) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 365) n.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 367) n.isUsingDiamondOperator() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.isUsingDiamondOperator()
+  Line 368) printer.print("<>") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 370) printTypeArgs(n, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeArgs(com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments<?>, java.lang.Object)
+  Line 376) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 376) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 377) n.getAnnotations() ==> com.github.javaparser.ast.type.TypeParameter.getAnnotations()
+  Line 378) ann.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 379) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 381) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 381) n.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 382) isNullOrEmpty(n.getTypeBound()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 382) n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 383) printer.print(" extends ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 384) n.getTypeBound().iterator() ==> java.util.List.iterator()
+  Line 384) n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 384) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 385) i.next() ==> java.util.Iterator.next()
+  Line 386) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 387) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 388) printer.print(" & ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 396) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 396) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 397) printAnnotations(n.getAnnotations(), true, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 397) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 398) n.getType() ==> com.github.javaparser.ast.type.PrimitiveType.getType()
+  Line 400) printer.print("boolean") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 403) printer.print("byte") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 406) printer.print("char") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 409) printer.print("double") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 412) printer.print("float") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 415) printer.print("int") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 418) printer.print("long") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 421) printer.print("short") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 432) arrayTypeBuffer.add(arrayType) ==> java.util.List.add(E)
+  Line 433) arrayType.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 436) type.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 438) printAnnotations(arrayType.getAnnotations(), true, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 438) arrayType.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 439) printer.print("[]") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 445) printAnnotations(n.getAnnotations(), true, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 445) n.getAnnotations() ==> com.github.javaparser.ast.ArrayCreationLevel.getAnnotations()
+  Line 446) printer.print("[") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 447) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 448) n.getDimension().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 448) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 450) printer.print("]") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 455) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 455) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 456) printAnnotations(n.getAnnotations(), false, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 456) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 458) n.getElements() ==> com.github.javaparser.ast.type.IntersectionType.getElements()
+  Line 459) element.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 463) printer.print(" & ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 469) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 469) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 470) printAnnotations(n.getAnnotations(), true, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 470) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 472) n.getElements() ==> com.github.javaparser.ast.type.UnionType.getElements()
+  Line 476) printer.print(" | ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 478) element.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 485) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 485) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 486) printAnnotations(n.getAnnotations(), false, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 486) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 487) printer.print("?") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 488) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 489) printer.print(" extends ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 490) n.getExtends().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 490) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 492) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 493) printer.print(" super ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 494) n.getSuper().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 494) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 505) printOrphanCommentsBeforeThisChildNode(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsBeforeThisChildNode(com.github.javaparser.ast.Node)
+  Line 507) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 507) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 508) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 508) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 509) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 509) n.getModifiers() ==> com.github.javaparser.ast.body.FieldDeclaration.getModifiers()
+  Line 510) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 510) n.getElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getElementType()
+  Line 511) n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getArrayBracketPairsAfterElementType()
+  Line 512) pair.accept(this, arg) ==> com.github.javaparser.ast.ArrayBracketPair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 515) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 516) n.getVariables().iterator() ==> java.util.List.iterator()
+  Line 516) n.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 516) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 517) i.next() ==> java.util.Iterator.next()
+  Line 518) var.accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 519) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 520) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 524) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 529) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 529) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 530) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 530) n.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 531) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 532) printer.print(" = ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 533) n.getInit().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 533) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 539) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 539) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 540) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 540) n.getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 541) n.getArrayBracketPairsAfterId() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()
+  Line 542) pair.accept(this, arg) ==> com.github.javaparser.ast.ArrayBracketPair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 548) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 548) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 549) printer.print("{") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 550) isNullOrEmpty(n.getValues()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 550) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 551) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 552) n.getValues().iterator() ==> java.util.List.iterator()
+  Line 552) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 552) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 553) i.next() ==> java.util.Iterator.next()
+  Line 554) expr.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 555) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 556) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 559) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 561) printer.print("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 566) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 566) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 567) printAnnotations(n.getAnnotations(), false, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 567) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 568) printer.print("void") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 573) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 573) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 574) n.getName().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 574) n.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 575) printer.print("[") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 576) n.getIndex().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 576) n.getIndex() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getIndex()
+  Line 577) printer.print("]") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 582) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 582) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 583) printer.print("new ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 584) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 584) n.getType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getType()
+  Line 585) n.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 586) level.accept(this, arg) ==> com.github.javaparser.ast.ArrayCreationLevel.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 588) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 589) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 590) n.getInitializer().accept(this, arg) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 590) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 596) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 596) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 597) n.getTarget().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 597) n.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 598) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 599) n.getOperator() ==> com.github.javaparser.ast.expr.AssignExpr.getOperator()
+  Line 601) printer.print("=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 604) printer.print("&=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 607) printer.print("|=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 610) printer.print("^=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 613) printer.print("+=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 616) printer.print("-=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 619) printer.print("%=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 622) printer.print("/=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 625) printer.print("*=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 628) printer.print("<<=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 631) printer.print(">>=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 634) printer.print(">>>=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 637) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 638) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 638) n.getValue() ==> com.github.javaparser.ast.expr.AssignExpr.getValue()
+  Line 643) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 643) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 644) n.getLeft().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 644) n.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 645) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 646) n.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 648) printer.print("||") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 651) printer.print("&&") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 654) printer.print("|") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 657) printer.print("&") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 660) printer.print("^") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 663) printer.print("==") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 666) printer.print("!=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 669) printer.print("<") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 672) printer.print(">") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 675) printer.print("<=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 678) printer.print(">=") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 681) printer.print("<<") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 684) printer.print(">>") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 687) printer.print(">>>") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 690) printer.print("+") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 693) printer.print("-") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 696) printer.print("*") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 699) printer.print("/") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 702) printer.print("%") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 705) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 706) n.getRight().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 706) n.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 711) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 711) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 712) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 713) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 713) n.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 714) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 715) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 715) n.getExpr() ==> com.github.javaparser.ast.expr.CastExpr.getExpr()
+  Line 720) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 720) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 721) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 721) n.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 722) printer.print(".class") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 727) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 727) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 728) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 728) n.getCondition() ==> com.github.javaparser.ast.expr.ConditionalExpr.getCondition()
+  Line 729) printer.print(" ? ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 730) n.getThenExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 730) n.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 731) printer.print(" : ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 732) n.getElseExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 732) n.getElseExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getElseExpr()
+  Line 737) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 737) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 738) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 739) n.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 740) n.getInner().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 740) n.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 742) printer.print(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 747) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 747) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 748) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 748) n.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 749) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 750) printer.print(n.getField()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 750) n.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 755) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 755) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 756) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 756) n.getExpr() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getExpr()
+  Line 757) printer.print(" instanceof ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 758) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 758) n.getType() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getType()
+  Line 763) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 763) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 764) printer.print("'") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 765) printer.print(n.getValue()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 765) n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 766) printer.print("'") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 771) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 771) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 772) printer.print(n.getValue()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 772) n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 777) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 777) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 778) printer.print(n.getValue()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 778) n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 783) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 783) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 784) printer.print(n.getValue()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 784) n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 789) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 789) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 790) printer.print(n.getValue()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 790) n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 795) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 795) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 796) printer.print(n.getValue()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 796) n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 801) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 801) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 802) printer.print("\"") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 803) printer.print(n.getValue()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 803) n.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 804) printer.print("\"") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 809) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 809) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 810) printer.print(String.valueOf(n.getValue())) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 810) String.valueOf(n.getValue()) ==> java.lang.String.valueOf(boolean)
+  Line 810) n.getValue() ==> com.github.javaparser.ast.expr.BooleanLiteralExpr.getValue()
+  Line 815) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 815) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 816) printer.print("null") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 821) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 821) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 822) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 823) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 823) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 824) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 826) printer.print("this") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 831) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 831) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 832) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 833) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 833) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 834) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 836) printer.print("super") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 841) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 841) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 842) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 843) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 843) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 844) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 846) printTypeArgs(n, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeArgs(com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments<?>, java.lang.Object)
+  Line 847) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 847) n.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 848) printArguments(n.getArgs(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printArguments(java.util.List<com.github.javaparser.ast.expr.Expression>, java.lang.Object)
+  Line 848) n.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 853) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 853) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 854) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 855) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 855) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 856) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 859) printer.print("new ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 861) printTypeArgs(n, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeArgs(com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments<?>, java.lang.Object)
+  Line 862) isNullOrEmpty(n.getTypeArguments()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 862) n.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 863) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 866) n.getType().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 866) n.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 868) printArguments(n.getArgs(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printArguments(java.util.List<com.github.javaparser.ast.expr.Expression>, java.lang.Object)
+  Line 868) n.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 870) n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 871) printer.printLn(" {") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 872) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 873) printMembers(n.getAnonymousClassBody(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>, java.lang.Object)
+  Line 873) n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 874) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 875) printer.print("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 881) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 881) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 882) n.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 884) printer.print("+") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 887) printer.print("-") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 890) printer.print("~") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 893) printer.print("!") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 896) printer.print("++") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 899) printer.print("--") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 904) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 904) n.getExpr() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpr()
+  Line 906) n.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 908) printer.print("++") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 911) printer.print("--") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 919) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 919) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 920) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 920) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 921) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 921) n.getModifiers() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()
+  Line 923) printTypeParameters(n.getTypeParameters(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.Object)
+  Line 923) n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 924) n.getTypeParameters().isEmpty() ==> java.util.List.isEmpty()
+  Line 924) n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 925) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 927) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 927) n.getName() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getName()
+  Line 929) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 930) n.getParameters().isEmpty() ==> java.util.List.isEmpty()
+  Line 930) n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 931) n.getParameters().iterator() ==> java.util.List.iterator()
+  Line 931) n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 931) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 932) i.next() ==> java.util.Iterator.next()
+  Line 933) p.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 934) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 935) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 939) printer.print(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 941) isNullOrEmpty(n.getThrows()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 941) n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 942) printer.print(" throws ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 943) n.getThrows().iterator() ==> java.util.List.iterator()
+  Line 943) n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 943) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 944) i.next() ==> java.util.Iterator.next()
+  Line 945) name.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 946) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 947) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 951) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 952) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 952) n.getBody() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getBody()
+  Line 957) printOrphanCommentsBeforeThisChildNode(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsBeforeThisChildNode(com.github.javaparser.ast.Node)
+  Line 959) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 959) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 960) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 960) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 961) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 961) n.getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 962) n.isDefault() ==> com.github.javaparser.ast.body.MethodDeclaration.isDefault()
+  Line 963) printer.print("default ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 965) printTypeParameters(n.getTypeParameters(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeParameters(java.util.List<com.github.javaparser.ast.type.TypeParameter>, java.lang.Object)
+  Line 965) n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 966) isNullOrEmpty(n.getTypeParameters()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 966) n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 967) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 970) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 970) n.getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 971) n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterElementType()
+  Line 972) pair.accept(this, arg) ==> com.github.javaparser.ast.ArrayBracketPair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 974) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 975) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 975) n.getName() ==> com.github.javaparser.ast.body.MethodDeclaration.getName()
+  Line 977) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 978) isNullOrEmpty(n.getParameters()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 978) n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 979) n.getParameters().iterator() ==> java.util.List.iterator()
+  Line 979) n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 979) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 980) i.next() ==> java.util.Iterator.next()
+  Line 981) p.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 982) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 983) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 987) printer.print(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 989) n.getArrayBracketPairsAfterParameterList() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterParameterList()
+  Line 990) pair.accept(this, arg) ==> com.github.javaparser.ast.ArrayBracketPair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 993) isNullOrEmpty(n.getThrows()) ==> com.github.javaparser.utils.Utils.isNullOrEmpty(java.util.Collection<E>)
+  Line 993) n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 994) printer.print(" throws ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 995) n.getThrows().iterator() ==> java.util.List.iterator()
+  Line 995) n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 995) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 996) i.next() ==> java.util.Iterator.next()
+  Line 997) name.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 998) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 999) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1003) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 1004) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1006) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1007) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1007) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 1013) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1013) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1014) printAnnotations(n.getAnnotations(), false, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 1014) n.getAnnotations() ==> com.github.javaparser.ast.body.Parameter.getAnnotations()
+  Line 1015) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 1015) n.getModifiers() ==> com.github.javaparser.ast.body.Parameter.getModifiers()
+  Line 1016) n.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 1017) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1017) n.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 1019) n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.Parameter.getArrayBracketPairsAfterElementType()
+  Line 1020) pair.accept(this, arg) ==> com.github.javaparser.ast.ArrayBracketPair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1022) n.isVarArgs() ==> com.github.javaparser.ast.body.Parameter.isVarArgs()
+  Line 1023) printer.print("...") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1025) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1026) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1026) n.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 1031) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1031) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1032) n.isThis() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.isThis()
+  Line 1033) printTypeArgs(n, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeArgs(com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments<?>, java.lang.Object)
+  Line 1034) printer.print("this") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1036) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 1037) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1037) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 1038) printer.print(".") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1040) printTypeArgs(n, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeArgs(com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments<?>, java.lang.Object)
+  Line 1041) printer.print("super") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1043) printArguments(n.getArgs(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printArguments(java.util.List<com.github.javaparser.ast.expr.Expression>, java.lang.Object)
+  Line 1043) n.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 1044) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1049) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1049) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1050) printAnnotations(n.getAnnotations(), false, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 1050) n.getAnnotations() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getAnnotations()
+  Line 1051) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 1051) n.getModifiers() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getModifiers()
+  Line 1053) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1053) n.getElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getElementType()
+  Line 1054) n.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getArrayBracketPairsAfterElementType()
+  Line 1055) pair.accept(this, arg) ==> com.github.javaparser.ast.ArrayBracketPair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1057) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1059) n.getVariables().iterator() ==> java.util.List.iterator()
+  Line 1059) n.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 1059) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1060) i.next() ==> java.util.Iterator.next()
+  Line 1061) v.accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1062) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1063) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1070) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1070) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1071) n.getTypeDeclaration().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1071) n.getTypeDeclaration() ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.getTypeDeclaration()
+  Line 1076) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1076) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1077) printer.print("assert ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1078) n.getCheck().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1078) n.getCheck() ==> com.github.javaparser.ast.stmt.AssertStmt.getCheck()
+  Line 1079) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 1080) printer.print(" : ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1081) n.getMessage().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1081) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 1083) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1088) printOrphanCommentsBeforeThisChildNode(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsBeforeThisChildNode(com.github.javaparser.ast.Node)
+  Line 1089) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1089) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1090) printer.printLn("{") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1091) n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 1092) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1093) n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 1094) s.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1095) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 1097) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1099) printOrphanCommentsEnding(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsEnding(com.github.javaparser.ast.Node)
+  Line 1100) printer.print("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1106) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1106) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1107) printer.print(n.getLabel()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1107) n.getLabel() ==> com.github.javaparser.ast.stmt.LabeledStmt.getLabel()
+  Line 1108) printer.print(": ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1109) n.getStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1109) n.getStmt() ==> com.github.javaparser.ast.stmt.LabeledStmt.getStmt()
+  Line 1114) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1114) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1115) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1120) printOrphanCommentsBeforeThisChildNode(n) ==> com.github.javaparser.ast.visitor.DumpVisitor.printOrphanCommentsBeforeThisChildNode(com.github.javaparser.ast.Node)
+  Line 1121) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1121) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1122) n.getExpression().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1122) n.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 1123) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1128) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1128) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1129) printer.print("switch(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1130) n.getSelector().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1130) n.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 1131) printer.printLn(") {") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1132) n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 1133) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1134) n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 1135) e.accept(this, arg) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1137) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1139) printer.print("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1145) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1145) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1146) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 1147) printer.print("case ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1148) n.getLabel().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1148) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 1149) printer.print(":") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1151) printer.print("default:") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1153) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 1154) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1155) n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 1156) n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 1157) s.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1158) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 1161) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1166) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1166) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1167) printer.print("break") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1168) n.getId() ==> com.github.javaparser.ast.stmt.BreakStmt.getId()
+  Line 1169) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1170) printer.print(n.getId()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1170) n.getId() ==> com.github.javaparser.ast.stmt.BreakStmt.getId()
+  Line 1172) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1177) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1177) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1178) printer.print("return") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1179) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 1180) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1181) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1181) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 1183) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1188) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1188) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1189) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 1189) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 1190) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 1190) n.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 1192) printer.print("enum ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1193) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1193) n.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 1195) n.getImplements().isEmpty() ==> java.util.List.isEmpty()
+  Line 1195) n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 1196) printer.print(" implements ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1197) n.getImplements().iterator() ==> java.util.List.iterator()
+  Line 1197) n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 1197) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1198) i.next() ==> java.util.Iterator.next()
+  Line 1199) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1200) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1201) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1206) printer.printLn(" {") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1207) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1208) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 1209) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 1210) n.getEntries().iterator() ==> java.util.List.iterator()
+  Line 1210) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 1210) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1211) i.next() ==> java.util.Iterator.next()
+  Line 1212) e.accept(this, arg) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1213) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1214) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1218) n.getMembers().isEmpty() ==> java.util.List.isEmpty()
+  Line 1218) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 1219) printer.printLn(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1220) printMembers(n.getMembers(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>, java.lang.Object)
+  Line 1220) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 1222) n.getEntries().isEmpty() ==> java.util.List.isEmpty()
+  Line 1222) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 1223) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 1226) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1227) printer.print("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1232) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1232) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1233) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 1233) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 1234) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1234) n.getName() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getName()
+  Line 1236) n.getArgs().isEmpty() ==> java.util.List.isEmpty()
+  Line 1236) n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 1237) printArguments(n.getArgs(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printArguments(java.util.List<com.github.javaparser.ast.expr.Expression>, java.lang.Object)
+  Line 1237) n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 1240) n.getClassBody().isEmpty() ==> java.util.List.isEmpty()
+  Line 1240) n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 1241) printer.printLn(" {") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1242) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1243) printMembers(n.getClassBody(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>, java.lang.Object)
+  Line 1243) n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 1244) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1245) printer.printLn("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1251) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1251) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1252) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1257) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1257) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1258) n.isStatic() ==> com.github.javaparser.ast.body.InitializerDeclaration.isStatic()
+  Line 1259) printer.print("static ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1261) n.getBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1261) n.getBlock() ==> com.github.javaparser.ast.body.InitializerDeclaration.getBlock()
+  Line 1266) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1266) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1267) printer.print("if (") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1268) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1268) n.getCondition() ==> com.github.javaparser.ast.stmt.IfStmt.getCondition()
+  Line 1269) n.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 1271) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1273) printer.printLn(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1274) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1276) n.getThenStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1276) n.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 1278) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1279) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 1281) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1283) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 1284) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 1285) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 1287) printer.print("else ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1289) printer.printLn("else") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1290) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1292) n.getElseStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1292) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 1294) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1300) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1300) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1301) printer.print("while (") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1302) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1302) n.getCondition() ==> com.github.javaparser.ast.stmt.WhileStmt.getCondition()
+  Line 1303) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1304) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1304) n.getBody() ==> com.github.javaparser.ast.stmt.WhileStmt.getBody()
+  Line 1309) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1309) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1310) printer.print("continue") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1311) n.getId() ==> com.github.javaparser.ast.stmt.ContinueStmt.getId()
+  Line 1312) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1313) printer.print(n.getId()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1313) n.getId() ==> com.github.javaparser.ast.stmt.ContinueStmt.getId()
+  Line 1315) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1320) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1320) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1321) printer.print("do ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1322) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1322) n.getBody() ==> com.github.javaparser.ast.stmt.DoStmt.getBody()
+  Line 1323) printer.print(" while (") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1324) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1324) n.getCondition() ==> com.github.javaparser.ast.stmt.DoStmt.getCondition()
+  Line 1325) printer.print(");") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1330) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1330) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1331) printer.print("for (") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1332) n.getVariable().accept(this, arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1332) n.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 1333) printer.print(" : ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1334) n.getIterable().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1334) n.getIterable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getIterable()
+  Line 1335) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1336) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1336) n.getBody() ==> com.github.javaparser.ast.stmt.ForeachStmt.getBody()
+  Line 1341) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1341) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1342) printer.print("for (") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1343) n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 1344) n.getInit().iterator() ==> java.util.List.iterator()
+  Line 1344) n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 1344) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1345) i.next() ==> java.util.Iterator.next()
+  Line 1346) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1347) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1348) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1352) printer.print("; ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1353) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 1354) n.getCompare().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1354) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 1356) printer.print("; ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1357) n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 1358) n.getUpdate().iterator() ==> java.util.List.iterator()
+  Line 1358) n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 1358) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1359) i.next() ==> java.util.Iterator.next()
+  Line 1360) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1361) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1362) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1366) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1367) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1367) n.getBody() ==> com.github.javaparser.ast.stmt.ForStmt.getBody()
+  Line 1372) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1372) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1373) printer.print("throw ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1374) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1374) n.getExpr() ==> com.github.javaparser.ast.stmt.ThrowStmt.getExpr()
+  Line 1375) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1380) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1380) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1381) printer.print("synchronized (") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1382) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1382) n.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 1383) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1384) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1384) n.getBody() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getBody()
+  Line 1389) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1389) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1390) printer.print("try ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1391) n.getResources().isEmpty() ==> java.util.List.isEmpty()
+  Line 1391) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1392) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1393) n.getResources().iterator() ==> java.util.List.iterator()
+  Line 1393) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1395) resources.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1396) visit(resources.next(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.visit(com.github.javaparser.ast.expr.VariableDeclarationExpr, java.lang.Object)
+  Line 1396) resources.next() ==> java.util.Iterator.next()
+  Line 1397) resources.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1398) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1399) printer.printLn() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn()
+  Line 1401) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1406) n.getResources().size() ==> java.util.List.size()
+  Line 1406) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1407) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1409) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1411) n.getTryBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1411) n.getTryBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getTryBlock()
+  Line 1412) n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 1413) n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 1414) c.accept(this, arg) ==> com.github.javaparser.ast.stmt.CatchClause.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1417) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 1418) printer.print(" finally ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1419) n.getFinallyBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1419) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 1425) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1425) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1426) printer.print(" catch (") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1427) n.getParam().accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1427) n.getParam() ==> com.github.javaparser.ast.stmt.CatchClause.getParam()
+  Line 1428) printer.print(") ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1429) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1429) n.getBody() ==> com.github.javaparser.ast.stmt.CatchClause.getBody()
+  Line 1435) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1435) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1436) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 1436) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 1437) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 1437) n.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 1439) printer.print("@interface ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1440) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1440) n.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 1441) printer.printLn(" {") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1442) printer.indent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.indent()
+  Line 1443) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 1444) printMembers(n.getMembers(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMembers(java.util.List<com.github.javaparser.ast.body.BodyDeclaration<?>>, java.lang.Object)
+  Line 1444) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 1446) printer.unindent() ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.unindent()
+  Line 1447) printer.print("}") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1452) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1452) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1453) printMemberAnnotations(n.getAnnotations(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printMemberAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, java.lang.Object)
+  Line 1453) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 1454) printModifiers(n.getModifiers()) ==> com.github.javaparser.ast.visitor.DumpVisitor.printModifiers(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 1454) n.getModifiers() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getModifiers()
+  Line 1456) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1456) n.getType() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getType()
+  Line 1457) printer.print(" ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1458) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1458) n.getName() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getName()
+  Line 1459) printer.print("()") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1460) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 1461) printer.print(" default ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1462) n.getDefaultValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1462) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 1464) printer.print(";") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1469) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1469) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1470) printer.print("@") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1471) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1471) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1476) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1476) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1477) printer.print("@") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1478) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1478) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1479) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1480) n.getMemberValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1480) n.getMemberValue() ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.getMemberValue()
+  Line 1481) printer.print(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1486) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1486) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1487) printer.print("@") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1488) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1488) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1489) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1490) n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 1491) n.getPairs().iterator() ==> java.util.List.iterator()
+  Line 1491) n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 1491) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1492) i.next() ==> java.util.Iterator.next()
+  Line 1493) m.accept(this, arg) ==> com.github.javaparser.ast.expr.MemberValuePair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1494) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1495) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1499) printer.print(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1504) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1504) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1505) printer.print(n.getName()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1505) n.getName() ==> com.github.javaparser.ast.expr.MemberValuePair.getName()
+  Line 1506) printer.print(" = ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1507) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1507) n.getValue() ==> com.github.javaparser.ast.expr.MemberValuePair.getValue()
+  Line 1515) printer.print("//") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1516) n.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 1517) tmp.replace('\r', ' ') ==> java.lang.String.replace(char, char)
+  Line 1518) tmp.replace('\n', ' ') ==> java.lang.String.replace(char, char)
+  Line 1519) printer.printLn(tmp) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1527) printer.print("/*") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1528) printer.print(n.getContent()) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1528) n.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 1529) printer.printLn("*/") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.printLn(java.lang.String)
+  Line 1534) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1534) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1536) n.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 1537) n.isParametersEnclosed() ==> com.github.javaparser.ast.expr.LambdaExpr.isParametersEnclosed()
+  Line 1540) printer.print("(") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1543) parameters.iterator() ==> java.util.List.iterator()
+  Line 1543) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1544) i.next() ==> java.util.Iterator.next()
+  Line 1545) p.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1546) i.hasNext() ==> java.util.Iterator.hasNext()
+  Line 1547) printer.print(", ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1552) printer.print(")") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1555) printer.print(" -> ") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1556) n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1559) ((ExpressionStmt) body).getExpression().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1559) ((ExpressionStmt) body).getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 1561) body.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1568) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1568) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1569) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1570) n.getIdentifier() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getIdentifier()
+  Line 1572) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1572) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1575) printer.print("::") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1576) printTypeArgs(n, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printTypeArgs(com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments<?>, java.lang.Object)
+  Line 1578) printer.print(identifier) ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1585) printJavaComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printJavaComment(com.github.javaparser.ast.comments.Comment, java.lang.Object)
+  Line 1585) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1586) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1587) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1587) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1593) printAnnotations(arrayBracketPair.getAnnotations(), true, arg) ==> com.github.javaparser.ast.visitor.DumpVisitor.printAnnotations(java.util.List<com.github.javaparser.ast.expr.AnnotationExpr>, boolean, java.lang.Object)
+  Line 1593) arrayBracketPair.getAnnotations() ==> com.github.javaparser.ast.ArrayBracketPair.getAnnotations()
+  Line 1594) printer.print("[]") ==> com.github.javaparser.ast.visitor.DumpVisitor.SourcePrinter.print(java.lang.String)
+  Line 1600) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 1603) everything.addAll(parent.getChildrenNodes()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 1603) parent.getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 1604) sortByBeginPosition(everything) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>)
+  Line 1606) everything.size() ==> java.util.List.size()
+  Line 1607) everything.get(i) ==> java.util.List.get(int)
+  Line 1612) everything.get(i) ==> java.util.List.get(int)
+  Line 1615) everything.get(i) ==> java.util.List.get(int)
+  Line 1617) nodeToPrint.getClass() ==> java.lang.Object.getClass()
+  Line 1618) nodeToPrint.accept(this, null) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1625) everything.addAll(node.getChildrenNodes()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 1625) node.getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 1626) sortByBeginPosition(everything) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>)
+  Line 1627) everything.isEmpty() ==> java.util.List.isEmpty()
+  Line 1633) everything.size() ==> java.util.List.size()
+  Line 1634) everything.get(everything.size() - 1 - commentsAtEnd) ==> java.util.List.get(int)
+  Line 1634) everything.size() ==> java.util.List.size()
+  Line 1641) everything.get(everything.size() - commentsAtEnd + i).accept(this, null) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 1641) everything.get(everything.size() - commentsAtEnd + i) ==> java.util.List.get(int)
+  Line 1641) everything.size() ==> java.util.List.size()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_EqualsVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_EqualsVisitor.txt
new file mode 100644
index 0000000..1b5dfcf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_EqualsVisitor.txt
@@ -0,0 +1,619 @@
+  Line 111) SINGLETON.nodeEquals(n1, n2) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 123) nodeEquals(n1.getComment(), n2.getComment()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 123) n1.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 123) n2.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 126) nodesEquals(n1.getOrphanComments(), n2.getOrphanComments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 126) n1.getOrphanComments() ==> com.github.javaparser.ast.Node.getOrphanComments()
+  Line 126) n2.getOrphanComments() ==> com.github.javaparser.ast.Node.getOrphanComments()
+  Line 135) nodes1.size() ==> java.util.List.size()
+  Line 135) nodes2.size() ==> java.util.List.size()
+  Line 138) nodes1.size() ==> java.util.List.size()
+  Line 139) nodeEquals(nodes1.get(i), nodes2.get(i)) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 139) nodes1.get(i) ==> java.util.List.get(int)
+  Line 139) nodes2.get(i) ==> java.util.List.get(int)
+  Line 153) n1.getClass() ==> java.lang.Object.getClass()
+  Line 153) n2.getClass() ==> java.lang.Object.getClass()
+  Line 156) commonNodeEquality(n1, n2) ==> com.github.javaparser.ast.visitor.EqualsVisitor.commonNodeEquality(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node)
+  Line 159) n1.accept(this, n2) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 169) n1.equals(n2) ==> java.lang.Object.equals(java.lang.Object)
+  Line 175) nodeEquals(n1.getPackage(), n2.getPackage()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 175) n1.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 175) n2.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 179) nodesEquals(n1.getImports(), n2.getImports()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 179) n1.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 179) n2.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 183) nodesEquals(n1.getTypes(), n2.getTypes()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 183) n1.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 183) n2.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 187) nodesEquals(n1.getComments(), n2.getComments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 187) n1.getComments() ==> com.github.javaparser.ast.CompilationUnit.getComments()
+  Line 187) n2.getComments() ==> com.github.javaparser.ast.CompilationUnit.getComments()
+  Line 197) nodeEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 197) n1.getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 197) n2.getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 201) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 201) n1.getAnnotations() ==> com.github.javaparser.ast.PackageDeclaration.getAnnotations()
+  Line 201) n2.getAnnotations() ==> com.github.javaparser.ast.PackageDeclaration.getAnnotations()
+  Line 211) nodeEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 211) n1.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 211) n2.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 221) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 221) n1.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 221) n2.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 225) nodesEquals(n1.getTypeBound(), n2.getTypeBound()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 225) n1.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 225) n2.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 228) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 228) n1.getAnnotations() ==> com.github.javaparser.ast.type.TypeParameter.getAnnotations()
+  Line 228) n2.getAnnotations() ==> com.github.javaparser.ast.type.TypeParameter.getAnnotations()
+  Line 237) objEquals(n1.getContent(), n2.getContent()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 237) n1.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 237) n2.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 241) objEquals(n1.getBegin().line, n2.getBegin().line) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 241) n1.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 241) n2.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 251) objEquals(n1.getContent(), n2.getContent()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 251) n1.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 251) n2.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 255) objEquals(n1.getBegin().line, n2.getBegin().line) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 255) n1.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 255) n2.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 267) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 267) n1.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 267) n2.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 271) n1.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 271) n2.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 275) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 275) n1.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 275) n2.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 279) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 279) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 279) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 283) nodesEquals(n1.getTypeParameters(), n2.getTypeParameters()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 283) n1.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 283) n2.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 287) nodesEquals(n1.getExtends(), n2.getExtends()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 287) n1.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 287) n2.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 291) nodesEquals(n1.getImplements(), n2.getImplements()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 291) n1.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 291) n2.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 295) nodesEquals(n1.getMembers(), n2.getMembers()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 295) n1.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 295) n2.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 307) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 307) n1.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 307) n2.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 311) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 311) n1.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 311) n2.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 315) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 315) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 315) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 319) nodesEquals(n1.getImplements(), n2.getImplements()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 319) n1.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 319) n2.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 323) nodesEquals(n1.getEntries(), n2.getEntries()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 323) n1.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 323) n2.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 327) nodesEquals(n1.getMembers(), n2.getMembers()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 327) n1.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 327) n2.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 343) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 343) n1.getName() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getName()
+  Line 343) n2.getName() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getName()
+  Line 347) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 347) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 347) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 351) nodesEquals(n1.getArgs(), n2.getArgs()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 351) n1.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 351) n2.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 355) nodesEquals(n1.getClassBody(), n2.getClassBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 355) n1.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 355) n2.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 367) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 367) n1.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 367) n2.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 371) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 371) n1.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 371) n2.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 375) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 375) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 375) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 379) nodesEquals(n1.getMembers(), n2.getMembers()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 379) n1.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 379) n2.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 391) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 391) n1.getModifiers() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getModifiers()
+  Line 391) n2.getModifiers() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getModifiers()
+  Line 395) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 395) n1.getName() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getName()
+  Line 395) n2.getName() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getName()
+  Line 399) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 399) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 399) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 403) nodeEquals(n1.getDefaultValue(), n2.getDefaultValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 403) n1.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 403) n2.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 407) nodeEquals(n1.getType(), n2.getType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 407) n1.getType() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getType()
+  Line 407) n2.getType() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getType()
+  Line 419) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 419) n1.getModifiers() ==> com.github.javaparser.ast.body.FieldDeclaration.getModifiers()
+  Line 419) n2.getModifiers() ==> com.github.javaparser.ast.body.FieldDeclaration.getModifiers()
+  Line 423) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 423) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 423) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 427) nodeEquals(n1.getElementType(), n2.getElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 427) n1.getElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getElementType()
+  Line 427) n2.getElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getElementType()
+  Line 431) nodesEquals(n1.getVariables(), n2.getVariables()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 431) n1.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 431) n2.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 435) nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 435) n1.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getArrayBracketPairsAfterElementType()
+  Line 435) n2.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getArrayBracketPairsAfterElementType()
+  Line 445) nodeEquals(n1.getId(), n2.getId()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 445) n1.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 445) n2.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 449) nodeEquals(n1.getInit(), n2.getInit()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 449) n1.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 449) n2.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 459) nodesEquals(n1.getArrayBracketPairsAfterId(), n2.getArrayBracketPairsAfterId()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 459) n1.getArrayBracketPairsAfterId() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()
+  Line 459) n2.getArrayBracketPairsAfterId() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getArrayBracketPairsAfterId()
+  Line 463) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 463) n1.getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 463) n2.getName() ==> com.github.javaparser.ast.body.VariableDeclaratorId.getName()
+  Line 475) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 475) n1.getModifiers() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()
+  Line 475) n2.getModifiers() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getModifiers()
+  Line 479) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 479) n1.getName() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getName()
+  Line 479) n2.getName() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getName()
+  Line 483) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 483) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 483) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 487) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 487) n1.getBody() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getBody()
+  Line 487) n2.getBody() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getBody()
+  Line 491) nodesEquals(n1.getParameters(), n2.getParameters()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 491) n1.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 491) n2.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 495) nodesEquals(n1.getThrows(), n2.getThrows()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 495) n1.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 495) n2.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 499) nodesEquals(n1.getTypeParameters(), n2.getTypeParameters()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 499) n1.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 499) n2.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 511) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 511) n1.getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 511) n2.getModifiers() ==> com.github.javaparser.ast.body.MethodDeclaration.getModifiers()
+  Line 515) nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 515) n1.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterElementType()
+  Line 515) n2.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterElementType()
+  Line 519) nodesEquals(n1.getArrayBracketPairsAfterParameterList(), n2.getArrayBracketPairsAfterParameterList()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 519) n1.getArrayBracketPairsAfterParameterList() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterParameterList()
+  Line 519) n2.getArrayBracketPairsAfterParameterList() ==> com.github.javaparser.ast.body.MethodDeclaration.getArrayBracketPairsAfterParameterList()
+  Line 523) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 523) n1.getName() ==> com.github.javaparser.ast.body.MethodDeclaration.getName()
+  Line 523) n2.getName() ==> com.github.javaparser.ast.body.MethodDeclaration.getName()
+  Line 527) nodeEquals(n1.getElementType(), n2.getElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 527) n1.getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 527) n2.getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 531) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 531) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 531) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 535) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 535) n1.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 535) n2.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 539) nodesEquals(n1.getParameters(), n2.getParameters()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 539) n1.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 539) n2.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 543) nodesEquals(n1.getThrows(), n2.getThrows()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 543) n1.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 543) n2.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 547) nodesEquals(n1.getTypeParameters(), n2.getTypeParameters()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 547) n1.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 547) n2.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 550) n1.isDefault() ==> com.github.javaparser.ast.body.MethodDeclaration.isDefault()
+  Line 550) n2.isDefault() ==> com.github.javaparser.ast.body.MethodDeclaration.isDefault()
+  Line 558) nodeEquals(n1.getElementType(), n2.getElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 558) n1.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 558) n2.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 562) nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 562) n1.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.Parameter.getArrayBracketPairsAfterElementType()
+  Line 562) n2.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.body.Parameter.getArrayBracketPairsAfterElementType()
+  Line 566) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 566) n1.getModifiers() ==> com.github.javaparser.ast.body.Parameter.getModifiers()
+  Line 566) n2.getModifiers() ==> com.github.javaparser.ast.body.Parameter.getModifiers()
+  Line 570) nodeEquals(n1.getId(), n2.getId()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 570) n1.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 570) n2.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 574) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 574) n1.getAnnotations() ==> com.github.javaparser.ast.body.Parameter.getAnnotations()
+  Line 574) n2.getAnnotations() ==> com.github.javaparser.ast.body.Parameter.getAnnotations()
+  Line 588) nodeEquals(n1.getBlock(), n2.getBlock()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 588) n1.getBlock() ==> com.github.javaparser.ast.body.InitializerDeclaration.getBlock()
+  Line 588) n2.getBlock() ==> com.github.javaparser.ast.body.InitializerDeclaration.getBlock()
+  Line 592) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 592) n1.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 592) n2.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 602) objEquals(n1.getContent(), n2.getContent()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 602) n1.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 602) n2.getContent() ==> com.github.javaparser.ast.comments.Comment.getContent()
+  Line 612) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 612) n1.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 612) n2.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 616) nodeEquals(n1.getScope(), n2.getScope()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 616) n1.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 616) n2.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 620) nodesEquals(n1.getTypeArguments(), n2.getTypeArguments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 620) n1.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 620) n2.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 624) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 624) n1.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 624) n2.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 634) n1.getType() ==> com.github.javaparser.ast.type.PrimitiveType.getType()
+  Line 634) n2.getType() ==> com.github.javaparser.ast.type.PrimitiveType.getType()
+  Line 637) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 637) n1.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 637) n2.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 647) nodeEquals(n1.getComponentType(), n2.getComponentType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 647) n1.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 647) n2.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 650) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 650) n1.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 650) n2.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 660) nodeEquals(n1.getDimension(), n2.getDimension()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 660) n1.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 660) n2.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 663) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 663) n1.getAnnotations() ==> com.github.javaparser.ast.ArrayCreationLevel.getAnnotations()
+  Line 663) n2.getAnnotations() ==> com.github.javaparser.ast.ArrayCreationLevel.getAnnotations()
+  Line 672) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 672) n1.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 672) n2.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 676) n1.getElements() ==> com.github.javaparser.ast.type.IntersectionType.getElements()
+  Line 677) n2.getElements() ==> com.github.javaparser.ast.type.IntersectionType.getElements()
+  Line 680) n1Elements.size() ==> java.util.List.size()
+  Line 680) n2Elements.size() ==> java.util.List.size()
+  Line 686) aux.accept(this, n2Elements.get(i)) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 686) n2Elements.get(i) ==> java.util.List.get(int)
+  Line 701) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 701) n1.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 701) n2.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 705) n1.getElements() ==> com.github.javaparser.ast.type.UnionType.getElements()
+  Line 706) n2.getElements() ==> com.github.javaparser.ast.type.UnionType.getElements()
+  Line 709) n1Elements.size() ==> java.util.List.size()
+  Line 709) n2Elements.size() ==> java.util.List.size()
+  Line 715) aux.accept(this, n2Elements.get(i)) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 715) n2Elements.get(i) ==> java.util.List.get(int)
+  Line 730) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 730) n1.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 730) n2.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 739) nodeEquals(n1.getExtends(), n2.getExtends()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 739) n1.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 739) n2.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 743) nodeEquals(n1.getSuper(), n2.getSuper()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 743) n1.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 743) n2.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 746) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 746) n1.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 746) n2.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 759) nodeEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 759) n1.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 759) n2.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 763) nodeEquals(n1.getIndex(), n2.getIndex()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 763) n1.getIndex() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getIndex()
+  Line 763) n2.getIndex() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getIndex()
+  Line 773) nodeEquals(n1.getType(), n2.getType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 773) n1.getType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getType()
+  Line 773) n2.getType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getType()
+  Line 777) nodesEquals(n1.getLevels(), n2.getLevels()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 777) n1.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 777) n2.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 781) nodeEquals(n1.getInitializer(), n2.getInitializer()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 781) n1.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 781) n2.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 791) nodesEquals(n1.getValues(), n2.getValues()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 791) n1.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 791) n2.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 801) n1.getOperator() ==> com.github.javaparser.ast.expr.AssignExpr.getOperator()
+  Line 801) n2.getOperator() ==> com.github.javaparser.ast.expr.AssignExpr.getOperator()
+  Line 805) nodeEquals(n1.getTarget(), n2.getTarget()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 805) n1.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 805) n2.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 809) nodeEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 809) n1.getValue() ==> com.github.javaparser.ast.expr.AssignExpr.getValue()
+  Line 809) n2.getValue() ==> com.github.javaparser.ast.expr.AssignExpr.getValue()
+  Line 819) n1.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 819) n2.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 823) nodeEquals(n1.getLeft(), n2.getLeft()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 823) n1.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 823) n2.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 827) nodeEquals(n1.getRight(), n2.getRight()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 827) n1.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 827) n2.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 837) nodeEquals(n1.getType(), n2.getType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 837) n1.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 837) n2.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 841) nodeEquals(n1.getExpr(), n2.getExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 841) n1.getExpr() ==> com.github.javaparser.ast.expr.CastExpr.getExpr()
+  Line 841) n2.getExpr() ==> com.github.javaparser.ast.expr.CastExpr.getExpr()
+  Line 851) nodeEquals(n1.getType(), n2.getType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 851) n1.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 851) n2.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 861) nodeEquals(n1.getCondition(), n2.getCondition()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 861) n1.getCondition() ==> com.github.javaparser.ast.expr.ConditionalExpr.getCondition()
+  Line 861) n2.getCondition() ==> com.github.javaparser.ast.expr.ConditionalExpr.getCondition()
+  Line 865) nodeEquals(n1.getThenExpr(), n2.getThenExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 865) n1.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 865) n2.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 869) nodeEquals(n1.getElseExpr(), n2.getElseExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 869) n1.getElseExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getElseExpr()
+  Line 869) n2.getElseExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getElseExpr()
+  Line 879) nodeEquals(n1.getInner(), n2.getInner()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 879) n1.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 879) n2.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 889) nodeEquals(n1.getScope(), n2.getScope()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 889) n1.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 889) n2.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 893) objEquals(n1.getField(), n2.getField()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 893) n1.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 893) n2.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 897) nodesEquals(n1.getTypeArguments(), n2.getTypeArguments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 897) n1.getTypeArguments() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getTypeArguments()
+  Line 897) n2.getTypeArguments() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getTypeArguments()
+  Line 907) nodeEquals(n1.getExpr(), n2.getExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 907) n1.getExpr() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getExpr()
+  Line 907) n2.getExpr() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getExpr()
+  Line 911) nodeEquals(n1.getType(), n2.getType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 911) n1.getType() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getType()
+  Line 911) n2.getType() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getType()
+  Line 921) objEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 921) n1.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 921) n2.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 931) objEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 931) n1.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 931) n2.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 941) objEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 941) n1.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 941) n2.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 951) objEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 951) n1.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 951) n2.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 961) objEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 961) n1.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 961) n2.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 971) objEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 971) n1.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 971) n2.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 981) objEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 981) n1.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 981) n2.getValue() ==> com.github.javaparser.ast.expr.StringLiteralExpr.getValue()
+  Line 991) n1.getValue() ==> com.github.javaparser.ast.expr.BooleanLiteralExpr.getValue()
+  Line 991) n2.getValue() ==> com.github.javaparser.ast.expr.BooleanLiteralExpr.getValue()
+  Line 1005) nodeEquals(n1.getScope(), n2.getScope()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1005) n1.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 1005) n2.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 1009) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 1009) n1.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 1009) n2.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 1013) nodesEquals(n1.getArgs(), n2.getArgs()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1013) n1.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 1013) n2.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 1017) nodesEquals(n1.getTypeArguments(), n2.getTypeArguments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1017) n1.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 1017) n2.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 1027) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 1027) n1.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 1027) n2.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 1037) nodeEquals(n1.getScope(), n2.getScope()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1037) n1.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 1037) n2.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 1041) nodeEquals(n1.getType(), n2.getType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1041) n1.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 1041) n2.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 1045) nodesEquals(n1.getAnonymousClassBody(), n2.getAnonymousClassBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1045) n1.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 1045) n2.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 1049) nodesEquals(n1.getArgs(), n2.getArgs()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1049) n1.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 1049) n2.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 1053) nodesEquals(n1.getTypeArguments(), n2.getTypeArguments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1053) n1.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 1053) n2.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 1063) nodeEquals(n1.getQualifier(), n2.getQualifier()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1063) n1.getQualifier() ==> com.github.javaparser.ast.expr.QualifiedNameExpr.getQualifier()
+  Line 1063) n2.getQualifier() ==> com.github.javaparser.ast.expr.QualifiedNameExpr.getQualifier()
+  Line 1067) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 1067) n1.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 1067) n2.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 1077) nodeEquals(n1.getClassExpr(), n2.getClassExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1077) n1.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 1077) n2.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 1087) nodeEquals(n1.getClassExpr(), n2.getClassExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1087) n1.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 1087) n2.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 1097) n1.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 1097) n2.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 1101) nodeEquals(n1.getExpr(), n2.getExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1101) n1.getExpr() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpr()
+  Line 1101) n2.getExpr() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpr()
+  Line 1111) n1.getModifiers().equals(n2.getModifiers()) ==> java.util.AbstractSet.equals(java.lang.Object)
+  Line 1111) n1.getModifiers() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getModifiers()
+  Line 1111) n2.getModifiers() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getModifiers()
+  Line 1115) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1115) n1.getAnnotations() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getAnnotations()
+  Line 1115) n2.getAnnotations() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getAnnotations()
+  Line 1119) nodeEquals(n1.getElementType(), n2.getElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1119) n1.getElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getElementType()
+  Line 1119) n2.getElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getElementType()
+  Line 1123) nodesEquals(n1.getVariables(), n2.getVariables()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1123) n1.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 1123) n2.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 1127) nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1127) n1.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getArrayBracketPairsAfterElementType()
+  Line 1127) n2.getArrayBracketPairsAfterElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getArrayBracketPairsAfterElementType()
+  Line 1137) nodeEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1137) n1.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1137) n2.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1147) nodeEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1147) n1.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1147) n2.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1151) nodeEquals(n1.getMemberValue(), n2.getMemberValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1151) n1.getMemberValue() ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.getMemberValue()
+  Line 1151) n2.getMemberValue() ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.getMemberValue()
+  Line 1161) nodeEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1161) n1.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1161) n2.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1165) nodesEquals(n1.getPairs(), n2.getPairs()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1165) n1.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 1165) n2.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 1175) objEquals(n1.getName(), n2.getName()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 1175) n1.getName() ==> com.github.javaparser.ast.expr.MemberValuePair.getName()
+  Line 1175) n2.getName() ==> com.github.javaparser.ast.expr.MemberValuePair.getName()
+  Line 1179) nodeEquals(n1.getValue(), n2.getValue()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1179) n1.getValue() ==> com.github.javaparser.ast.expr.MemberValuePair.getValue()
+  Line 1179) n2.getValue() ==> com.github.javaparser.ast.expr.MemberValuePair.getValue()
+  Line 1189) nodeEquals(n1.getExpr(), n2.getExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1189) n1.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 1189) n2.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 1193) nodesEquals(n1.getArgs(), n2.getArgs()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1193) n1.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 1193) n2.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 1197) nodesEquals(n1.getTypeArguments(), n2.getTypeArguments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1197) n1.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 1197) n2.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 1207) nodeEquals(n1.getTypeDeclaration(), n2.getTypeDeclaration()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1207) n1.getTypeDeclaration() ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.getTypeDeclaration()
+  Line 1207) n2.getTypeDeclaration() ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.getTypeDeclaration()
+  Line 1217) nodeEquals(n1.getCheck(), n2.getCheck()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1217) n1.getCheck() ==> com.github.javaparser.ast.stmt.AssertStmt.getCheck()
+  Line 1217) n2.getCheck() ==> com.github.javaparser.ast.stmt.AssertStmt.getCheck()
+  Line 1221) nodeEquals(n1.getMessage(), n2.getMessage()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1221) n1.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 1221) n2.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 1231) nodesEquals(n1.getStmts(), n2.getStmts()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1231) n1.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 1231) n2.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 1241) nodeEquals(n1.getStmt(), n2.getStmt()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1241) n1.getStmt() ==> com.github.javaparser.ast.stmt.LabeledStmt.getStmt()
+  Line 1241) n2.getStmt() ==> com.github.javaparser.ast.stmt.LabeledStmt.getStmt()
+  Line 1255) nodeEquals(n1.getExpression(), n2.getExpression()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1255) n1.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 1255) n2.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 1265) nodeEquals(n1.getSelector(), n2.getSelector()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1265) n1.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 1265) n2.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 1269) nodesEquals(n1.getEntries(), n2.getEntries()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1269) n1.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 1269) n2.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 1279) nodeEquals(n1.getLabel(), n2.getLabel()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1279) n1.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 1279) n2.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 1283) nodesEquals(n1.getStmts(), n2.getStmts()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1283) n1.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 1283) n2.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 1293) objEquals(n1.getId(), n2.getId()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 1293) n1.getId() ==> com.github.javaparser.ast.stmt.BreakStmt.getId()
+  Line 1293) n2.getId() ==> com.github.javaparser.ast.stmt.BreakStmt.getId()
+  Line 1303) nodeEquals(n1.getExpr(), n2.getExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1303) n1.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 1303) n2.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 1313) nodeEquals(n1.getCondition(), n2.getCondition()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1313) n1.getCondition() ==> com.github.javaparser.ast.stmt.IfStmt.getCondition()
+  Line 1313) n2.getCondition() ==> com.github.javaparser.ast.stmt.IfStmt.getCondition()
+  Line 1317) nodeEquals(n1.getThenStmt(), n2.getThenStmt()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1317) n1.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 1317) n2.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 1321) nodeEquals(n1.getElseStmt(), n2.getElseStmt()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1321) n1.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 1321) n2.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 1331) nodeEquals(n1.getCondition(), n2.getCondition()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1331) n1.getCondition() ==> com.github.javaparser.ast.stmt.WhileStmt.getCondition()
+  Line 1331) n2.getCondition() ==> com.github.javaparser.ast.stmt.WhileStmt.getCondition()
+  Line 1335) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1335) n1.getBody() ==> com.github.javaparser.ast.stmt.WhileStmt.getBody()
+  Line 1335) n2.getBody() ==> com.github.javaparser.ast.stmt.WhileStmt.getBody()
+  Line 1345) objEquals(n1.getId(), n2.getId()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 1345) n1.getId() ==> com.github.javaparser.ast.stmt.ContinueStmt.getId()
+  Line 1345) n2.getId() ==> com.github.javaparser.ast.stmt.ContinueStmt.getId()
+  Line 1355) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1355) n1.getBody() ==> com.github.javaparser.ast.stmt.DoStmt.getBody()
+  Line 1355) n2.getBody() ==> com.github.javaparser.ast.stmt.DoStmt.getBody()
+  Line 1359) nodeEquals(n1.getCondition(), n2.getCondition()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1359) n1.getCondition() ==> com.github.javaparser.ast.stmt.DoStmt.getCondition()
+  Line 1359) n2.getCondition() ==> com.github.javaparser.ast.stmt.DoStmt.getCondition()
+  Line 1369) nodeEquals(n1.getVariable(), n2.getVariable()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1369) n1.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 1369) n2.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 1373) nodeEquals(n1.getIterable(), n2.getIterable()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1373) n1.getIterable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getIterable()
+  Line 1373) n2.getIterable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getIterable()
+  Line 1377) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1377) n1.getBody() ==> com.github.javaparser.ast.stmt.ForeachStmt.getBody()
+  Line 1377) n2.getBody() ==> com.github.javaparser.ast.stmt.ForeachStmt.getBody()
+  Line 1387) nodesEquals(n1.getInit(), n2.getInit()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1387) n1.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 1387) n2.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 1391) nodeEquals(n1.getCompare(), n2.getCompare()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1391) n1.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 1391) n2.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 1395) nodesEquals(n1.getUpdate(), n2.getUpdate()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1395) n1.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 1395) n2.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 1399) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1399) n1.getBody() ==> com.github.javaparser.ast.stmt.ForStmt.getBody()
+  Line 1399) n2.getBody() ==> com.github.javaparser.ast.stmt.ForStmt.getBody()
+  Line 1409) nodeEquals(n1.getExpr(), n2.getExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1409) n1.getExpr() ==> com.github.javaparser.ast.stmt.ThrowStmt.getExpr()
+  Line 1409) n2.getExpr() ==> com.github.javaparser.ast.stmt.ThrowStmt.getExpr()
+  Line 1419) nodeEquals(n1.getExpr(), n2.getExpr()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1419) n1.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 1419) n2.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 1423) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1423) n1.getBody() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getBody()
+  Line 1423) n2.getBody() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getBody()
+  Line 1433) nodeEquals(n1.getTryBlock(), n2.getTryBlock()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1433) n1.getTryBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getTryBlock()
+  Line 1433) n2.getTryBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getTryBlock()
+  Line 1437) nodesEquals(n1.getCatchs(), n2.getCatchs()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1437) n1.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 1437) n2.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 1441) nodesEquals(n1.getResources(), n2.getResources()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1441) n1.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1441) n2.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1445) nodeEquals(n1.getFinallyBlock(), n2.getFinallyBlock()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1445) n1.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 1445) n2.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 1455) nodeEquals(n1.getParam(), n2.getParam()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1455) n1.getParam() ==> com.github.javaparser.ast.stmt.CatchClause.getParam()
+  Line 1455) n2.getParam() ==> com.github.javaparser.ast.stmt.CatchClause.getParam()
+  Line 1459) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1459) n1.getBody() ==> com.github.javaparser.ast.stmt.CatchClause.getBody()
+  Line 1459) n2.getBody() ==> com.github.javaparser.ast.stmt.CatchClause.getBody()
+  Line 1469) nodesEquals(n1.getParameters(), n2.getParameters()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1469) n1.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 1469) n2.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 1472) n1.isParametersEnclosed() ==> com.github.javaparser.ast.expr.LambdaExpr.isParametersEnclosed()
+  Line 1472) n2.isParametersEnclosed() ==> com.github.javaparser.ast.expr.LambdaExpr.isParametersEnclosed()
+  Line 1475) nodeEquals(n1.getBody(), n2.getBody()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1475) n1.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1475) n2.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1484) nodeEquals(n1.getScope(), n2.getScope()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1484) n1.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1484) n2.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1487) nodesEquals(n1.getTypeArguments(), n2.getTypeArguments()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1487) n1.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1487) n2.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1490) objEquals(n1.getIdentifier(), n2.getIdentifier()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.objEquals(java.lang.Object, java.lang.Object)
+  Line 1490) n1.getIdentifier() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getIdentifier()
+  Line 1490) n2.getIdentifier() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getIdentifier()
+  Line 1499) nodeEquals(n.getType(), n2.getType()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodeEquals(T, T)
+  Line 1499) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1499) n2.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1508) nodesEquals(n1.getAnnotations(), n2.getAnnotations()) ==> com.github.javaparser.ast.visitor.EqualsVisitor.nodesEquals(java.util.List<T>, java.util.List<T>)
+  Line 1508) n1.getAnnotations() ==> com.github.javaparser.ast.ArrayBracketPair.getAnnotations()
+  Line 1508) n2.getAnnotations() ==> com.github.javaparser.ast.ArrayBracketPair.getAnnotations()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_GenericVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_GenericVisitor.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_GenericVisitor.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_GenericVisitorAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_GenericVisitorAdapter.txt
new file mode 100644
index 0000000..beee864
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_GenericVisitorAdapter.txt
@@ -0,0 +1,451 @@
+  Line 43) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 44) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 45) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 47) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 54) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 55) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 57) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 69) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 70) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 71) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 73) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 81) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 81) n.getType() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getType()
+  Line 86) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 88) n.getDefaultValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 88) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 99) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 101) n.getName().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 101) n.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 107) n.getIndex().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 107) n.getIndex() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getIndex()
+  Line 117) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 119) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 119) n.getType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getType()
+  Line 124) n.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 125) level.accept(this, arg) ==> com.github.javaparser.ast.ArrayCreationLevel.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 130) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 131) n.getInitializer().accept(this, arg) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 131) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 141) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 142) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 143) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 145) expr.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 157) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 159) n.getCheck().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 159) n.getCheck() ==> com.github.javaparser.ast.stmt.AssertStmt.getCheck()
+  Line 164) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 166) n.getMessage().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 166) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 177) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 179) n.getTarget().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 179) n.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 185) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 185) n.getValue() ==> com.github.javaparser.ast.expr.AssignExpr.getValue()
+  Line 195) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 197) n.getLeft().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 197) n.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 203) n.getRight().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 203) n.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 213) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 214) n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 215) n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 217) s.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 230) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 236) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 242) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 244) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 244) n.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 250) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 250) n.getExpr() ==> com.github.javaparser.ast.expr.CastExpr.getExpr()
+  Line 260) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 262) n.getParam().accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 262) n.getParam() ==> com.github.javaparser.ast.stmt.CatchClause.getParam()
+  Line 268) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 268) n.getBody() ==> com.github.javaparser.ast.stmt.CatchClause.getBody()
+  Line 279) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 285) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 287) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 287) n.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 297) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 298) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 299) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 301) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 308) n.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 309) n.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 311) t.accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 318) n.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 319) n.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 321) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 329) n.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 330) n.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 332) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 339) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 340) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 342) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 354) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 355) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 356) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 361) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 363) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 363) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 369) n.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 370) n.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 371) type.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 382) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 383) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 385) n.getPackage().accept(this, arg) ==> com.github.javaparser.ast.PackageDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 385) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 391) n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 392) n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 394) i.accept(this, arg) ==> com.github.javaparser.ast.ImportDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 401) n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 402) n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 404) typeDeclaration.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 416) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 418) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 418) n.getCondition() ==> com.github.javaparser.ast.expr.ConditionalExpr.getCondition()
+  Line 424) n.getThenExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 424) n.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 430) n.getElseExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 430) n.getElseExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getElseExpr()
+  Line 440) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 441) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 442) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 444) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 451) n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 452) n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 454) t.accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 461) n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 462) n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 464) p.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 471) n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 472) n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 474) name.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 482) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 482) n.getBody() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getBody()
+  Line 492) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 498) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 500) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 500) n.getBody() ==> com.github.javaparser.ast.stmt.DoStmt.getBody()
+  Line 506) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 506) n.getCondition() ==> com.github.javaparser.ast.stmt.DoStmt.getCondition()
+  Line 516) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 522) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 528) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 534) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 540) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 542) n.getInner().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 542) n.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 552) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 553) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 554) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 556) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 563) n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 564) n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 566) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 573) n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 574) n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 576) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 588) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 589) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 590) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 592) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 599) n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 600) n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 602) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 609) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 610) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 612) e.accept(this, arg) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 619) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 620) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 622) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 634) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 635) n.isThis() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.isThis()
+  Line 635) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 637) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 637) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 643) n.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 644) n.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 645) type.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 651) n.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 652) n.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 654) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 666) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 668) n.getExpression().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 668) n.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 678) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 680) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 680) n.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 686) n.getTypeArguments() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getTypeArguments()
+  Line 687) n.getTypeArguments() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getTypeArguments()
+  Line 688) type.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 700) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 701) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 702) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 704) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 712) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 712) n.getElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getElementType()
+  Line 717) n.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 719) var.accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 730) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 732) n.getVariable().accept(this, arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 732) n.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 738) n.getIterable().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 738) n.getIterable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getIterable()
+  Line 744) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 744) n.getBody() ==> com.github.javaparser.ast.stmt.ForeachStmt.getBody()
+  Line 754) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 755) n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 756) n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 758) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 765) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 767) n.getCompare().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 767) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 773) n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 774) n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 776) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 784) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 784) n.getBody() ==> com.github.javaparser.ast.stmt.ForStmt.getBody()
+  Line 794) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 796) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 796) n.getCondition() ==> com.github.javaparser.ast.stmt.IfStmt.getCondition()
+  Line 802) n.getThenStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 802) n.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 807) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 809) n.getElseStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 809) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 820) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 822) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 822) n.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 832) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 834) n.getBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 834) n.getBlock() ==> com.github.javaparser.ast.body.InitializerDeclaration.getBlock()
+  Line 844) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 846) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 846) n.getExpr() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getExpr()
+  Line 852) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 852) n.getType() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getType()
+  Line 862) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 868) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 879) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 881) n.getStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 881) n.getStmt() ==> com.github.javaparser.ast.stmt.LabeledStmt.getStmt()
+  Line 891) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 897) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 903) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 905) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 905) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 915) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 917) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 917) n.getValue() ==> com.github.javaparser.ast.expr.MemberValuePair.getValue()
+  Line 927) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 928) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 930) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 930) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 936) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 937) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 938) type.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 944) n.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 945) n.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 947) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 959) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 960) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 961) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 963) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 970) n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 971) n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 973) t.accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 981) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 981) n.getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 986) n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 987) n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 989) p.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 996) n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 997) n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 999) name.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1006) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 1008) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1008) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 1019) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1025) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1027) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1027) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1032) n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 1033) n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 1035) m.accept(this, arg) ==> com.github.javaparser.ast.expr.MemberValuePair.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1047) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1053) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1054) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 1056) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1056) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 1062) n.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 1063) n.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 1064) type.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1071) n.getType().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1071) n.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 1076) n.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 1077) n.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 1079) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1086) n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 1087) n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 1089) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1101) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1102) n.getAnnotations() ==> com.github.javaparser.ast.PackageDeclaration.getAnnotations()
+  Line 1103) n.getAnnotations() ==> com.github.javaparser.ast.PackageDeclaration.getAnnotations()
+  Line 1105) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1113) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1113) n.getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 1123) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1124) n.getAnnotations() ==> com.github.javaparser.ast.body.Parameter.getAnnotations()
+  Line 1125) n.getAnnotations() ==> com.github.javaparser.ast.body.Parameter.getAnnotations()
+  Line 1127) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1135) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1135) n.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 1141) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1141) n.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 1151) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1152) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 1153) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1163) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1165) n.getQualifier().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1165) n.getQualifier() ==> com.github.javaparser.ast.expr.QualifiedNameExpr.getQualifier()
+  Line 1175) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1176) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 1177) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1183) n.getComponentType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1183) n.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 1193) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1194) n.getAnnotations() ==> com.github.javaparser.ast.ArrayCreationLevel.getAnnotations()
+  Line 1195) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1201) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 1202) n.getDimension().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1202) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 1213) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1214) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 1215) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1221) n.getElements() ==> com.github.javaparser.ast.type.IntersectionType.getElements()
+  Line 1222) element.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1233) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1234) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 1235) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1241) n.getElements() ==> com.github.javaparser.ast.type.UnionType.getElements()
+  Line 1242) element.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1253) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1254) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 1256) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1256) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 1267) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1269) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1269) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 1275) n.getMemberValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1275) n.getMemberValue() ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.getMemberValue()
+  Line 1285) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1291) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1292) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 1294) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1294) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 1305) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1306) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 1308) n.getLabel().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1308) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 1314) n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 1315) n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 1317) s.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1329) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1331) n.getSelector().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1331) n.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 1336) n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 1337) n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 1339) e.accept(this, arg) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1352) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1354) n.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 1355) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1355) n.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 1362) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1362) n.getBody() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getBody()
+  Line 1372) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1373) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 1375) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1375) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 1386) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1388) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1388) n.getExpr() ==> com.github.javaparser.ast.stmt.ThrowStmt.getExpr()
+  Line 1398) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1399) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1400) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 1402) v.accept(this, arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1410) n.getTryBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1410) n.getTryBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getTryBlock()
+  Line 1415) n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 1416) n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 1418) c.accept(this, arg) ==> com.github.javaparser.ast.stmt.CatchClause.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1425) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 1427) n.getFinallyBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1427) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 1438) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1440) n.getTypeDeclaration().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1440) n.getTypeDeclaration() ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.getTypeDeclaration()
+  Line 1450) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1451) n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 1452) n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 1454) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1466) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1468) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1468) n.getExpr() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpr()
+  Line 1478) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1484) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1485) n.getAnnotations() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getAnnotations()
+  Line 1486) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1492) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1492) n.getElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getElementType()
+  Line 1497) n.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 1499) v.accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1510) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1512) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1512) n.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 1517) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 1519) n.getInit().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1519) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 1530) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1536) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1537) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 1538) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1548) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1550) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1550) n.getCondition() ==> com.github.javaparser.ast.stmt.WhileStmt.getCondition()
+  Line 1556) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1556) n.getBody() ==> com.github.javaparser.ast.stmt.WhileStmt.getBody()
+  Line 1566) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1567) n.getAnnotations() ==> com.github.javaparser.ast.type.Type.getAnnotations()
+  Line 1568) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1573) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 1575) n.getExtends().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1575) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 1581) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 1583) n.getSuper().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1583) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 1594) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1595) n.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 1596) n.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 1597) a.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1603) n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1604) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1604) n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1614) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1616) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1617) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1618) type.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1625) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1626) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1626) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1636) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.GenericVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1637) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1638) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1638) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1648) n.getAnnotations() ==> com.github.javaparser.ast.ArrayBracketPair.getAnnotations()
+  Line 1650) a.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1670) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1671) n.getComment().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1671) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1673) n.setComment(result) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_ModifierVisitorAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_ModifierVisitorAdapter.txt
new file mode 100644
index 0000000..b5ff373
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_ModifierVisitorAdapter.txt
@@ -0,0 +1,685 @@
+  Line 120) list.size() ==> java.util.List.size()
+  Line 121) list.get(i) ==> java.util.List.get(int)
+  Line 122) list.remove(i) ==> java.util.List.remove(int)
+  Line 128) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 129) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 130) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 132) members.size() ==> java.util.List.size()
+  Line 133) members.set(i, (BodyDeclaration<?>) members.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 133) members.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 133) members.get(i) ==> java.util.List.get(int)
+  Line 135) removeNulls(members) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 141) n.getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 143) annotations.size() ==> java.util.List.size()
+  Line 144) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 144) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 144) annotations.get(i) ==> java.util.List.get(int)
+  Line 146) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 151) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 152) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 154) annotations.size() ==> java.util.List.size()
+  Line 155) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 155) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 155) annotations.get(i) ==> java.util.List.get(int)
+  Line 157) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 159) n.setType((Type) n.getType().accept(this, arg)) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setType(com.github.javaparser.ast.type.Type)
+  Line 159) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 159) n.getType() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getType()
+  Line 160) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 161) n.setDefaultValue((Expression) n.getDefaultValue().accept(this, arg)) ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.setDefaultValue(com.github.javaparser.ast.expr.Expression)
+  Line 161) n.getDefaultValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 161) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 167) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 168) n.setName((Expression) n.getName().accept(this, arg)) ==> com.github.javaparser.ast.expr.ArrayAccessExpr.setName(com.github.javaparser.ast.expr.Expression)
+  Line 168) n.getName().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 168) n.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 169) n.setIndex((Expression) n.getIndex().accept(this, arg)) ==> com.github.javaparser.ast.expr.ArrayAccessExpr.setIndex(com.github.javaparser.ast.expr.Expression)
+  Line 169) n.getIndex().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 169) n.getIndex() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getIndex()
+  Line 174) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 175) n.setType((Type) n.getType().accept(this, arg)) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 175) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 175) n.getType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getType()
+  Line 177) n.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 178) values.size() ==> java.util.List.size()
+  Line 179) values.set(i, (ArrayCreationLevel) values.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 179) values.get(i).accept(this, arg) ==> com.github.javaparser.ast.ArrayCreationLevel.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 179) values.get(i) ==> java.util.List.get(int)
+  Line 181) removeNulls(values) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 183) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 184) n.setInitializer((ArrayInitializerExpr) n.getInitializer().accept(this, arg)) ==> com.github.javaparser.ast.expr.ArrayCreationExpr.setInitializer(com.github.javaparser.ast.expr.ArrayInitializerExpr)
+  Line 184) n.getInitializer().accept(this, arg) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 184) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 190) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 191) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 192) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 194) values.size() ==> java.util.List.size()
+  Line 195) values.set(i, (Expression) values.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 195) values.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 195) values.get(i) ==> java.util.List.get(int)
+  Line 197) removeNulls(values) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 204) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 205) n.setCheck((Expression) n.getCheck().accept(this, arg)) ==> com.github.javaparser.ast.stmt.AssertStmt.setCheck(com.github.javaparser.ast.expr.Expression)
+  Line 205) n.getCheck().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 205) n.getCheck() ==> com.github.javaparser.ast.stmt.AssertStmt.getCheck()
+  Line 206) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 207) n.setMessage((Expression) n.getMessage().accept(this, arg)) ==> com.github.javaparser.ast.stmt.AssertStmt.setMessage(com.github.javaparser.ast.expr.Expression)
+  Line 207) n.getMessage().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 207) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 213) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 214) n.getTarget().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 214) n.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 218) n.setTarget(target) ==> com.github.javaparser.ast.expr.AssignExpr.setTarget(com.github.javaparser.ast.expr.Expression)
+  Line 220) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 220) n.getValue() ==> com.github.javaparser.ast.expr.AssignExpr.getValue()
+  Line 224) n.setValue(value) ==> com.github.javaparser.ast.expr.AssignExpr.setValue(com.github.javaparser.ast.expr.Expression)
+  Line 230) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 231) n.getLeft().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 231) n.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 232) n.getRight().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 232) n.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 239) n.setLeft(left) ==> com.github.javaparser.ast.expr.BinaryExpr.setLeft(com.github.javaparser.ast.expr.Expression)
+  Line 240) n.setRight(right) ==> com.github.javaparser.ast.expr.BinaryExpr.setRight(com.github.javaparser.ast.expr.Expression)
+  Line 245) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 246) n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 248) stmts.size() ==> java.util.List.size()
+  Line 249) stmts.set(i, (Statement) stmts.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 249) stmts.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 249) stmts.get(i) ==> java.util.List.get(int)
+  Line 251) removeNulls(stmts) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 257) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 262) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 267) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 268) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 268) n.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 269) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 269) n.getExpr() ==> com.github.javaparser.ast.expr.CastExpr.getExpr()
+  Line 276) n.setType(type) ==> com.github.javaparser.ast.expr.CastExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 277) n.setExpr(expr) ==> com.github.javaparser.ast.expr.CastExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 282) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 283) n.setParam((Parameter) n.getParam().accept(this, arg)) ==> com.github.javaparser.ast.stmt.CatchClause.setParam(com.github.javaparser.ast.body.Parameter)
+  Line 283) n.getParam().accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 283) n.getParam() ==> com.github.javaparser.ast.stmt.CatchClause.getParam()
+  Line 284) n.setBody((BlockStmt) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.stmt.CatchClause.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 284) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 284) n.getBody() ==> com.github.javaparser.ast.stmt.CatchClause.getBody()
+  Line 290) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 295) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 296) n.setType((Type) n.getType().accept(this, arg)) ==> com.github.javaparser.ast.expr.ClassExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 296) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 296) n.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 301) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 302) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 303) n.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 305) typeParameters.size() ==> java.util.List.size()
+  Line 306) typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 306) typeParameters.get(i).accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 306) typeParameters.get(i) ==> java.util.List.get(int)
+  Line 308) removeNulls(typeParameters) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 310) n.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 312) extendz.size() ==> java.util.List.size()
+  Line 313) extendz.set(i, (ClassOrInterfaceType) extendz.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 313) extendz.get(i).accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 313) extendz.get(i) ==> java.util.List.get(int)
+  Line 315) removeNulls(extendz) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 317) n.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 319) implementz.size() ==> java.util.List.size()
+  Line 320) implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 320) implementz.get(i).accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 320) implementz.get(i) ==> java.util.List.get(int)
+  Line 322) removeNulls(implementz) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 324) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 326) members.size() ==> java.util.List.size()
+  Line 327) members.set(i, (BodyDeclaration<?>) members.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 327) members.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 327) members.get(i) ==> java.util.List.get(int)
+  Line 329) removeNulls(members) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 335) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 336) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 337) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 338) n.setScope((ClassOrInterfaceType) n.getScope().accept(this, arg)) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.setScope(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 338) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 338) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 340) n.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 342) typeArguments.size() ==> java.util.List.size()
+  Line 343) typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 343) typeArguments.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 343) typeArguments.get(i) ==> java.util.List.get(int)
+  Line 345) removeNulls(typeArguments) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 351) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 352) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 353) n.setPackage((PackageDeclaration) n.getPackage().accept(this, arg)) ==> com.github.javaparser.ast.CompilationUnit.setPackage(com.github.javaparser.ast.PackageDeclaration)
+  Line 353) n.getPackage().accept(this, arg) ==> com.github.javaparser.ast.PackageDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 353) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 355) n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 357) imports.size() ==> java.util.List.size()
+  Line 358) imports.set(i, (ImportDeclaration) imports.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 358) imports.get(i).accept(this, arg) ==> com.github.javaparser.ast.ImportDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 358) imports.get(i) ==> java.util.List.get(int)
+  Line 360) removeNulls(imports) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 362) n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 364) types.size() ==> java.util.List.size()
+  Line 365) types.set(i, (TypeDeclaration<?>) types.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 365) types.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 365) types.get(i) ==> java.util.List.get(int)
+  Line 367) removeNulls(types) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 373) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 374) n.setCondition((Expression) n.getCondition().accept(this, arg)) ==> com.github.javaparser.ast.expr.ConditionalExpr.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 374) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 374) n.getCondition() ==> com.github.javaparser.ast.expr.ConditionalExpr.getCondition()
+  Line 375) n.setThenExpr((Expression) n.getThenExpr().accept(this, arg)) ==> com.github.javaparser.ast.expr.ConditionalExpr.setThenExpr(com.github.javaparser.ast.expr.Expression)
+  Line 375) n.getThenExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 375) n.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 376) n.setElseExpr((Expression) n.getElseExpr().accept(this, arg)) ==> com.github.javaparser.ast.expr.ConditionalExpr.setElseExpr(com.github.javaparser.ast.expr.Expression)
+  Line 376) n.getElseExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 376) n.getElseExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getElseExpr()
+  Line 381) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 382) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 384) annotations.size() ==> java.util.List.size()
+  Line 385) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 385) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 385) annotations.get(i) ==> java.util.List.get(int)
+  Line 387) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 389) n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 391) typeParameters.size() ==> java.util.List.size()
+  Line 392) typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 392) typeParameters.get(i).accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 392) typeParameters.get(i) ==> java.util.List.get(int)
+  Line 394) removeNulls(typeParameters) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 396) n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 398) parameters.size() ==> java.util.List.size()
+  Line 399) parameters.set(i, (Parameter) parameters.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 399) parameters.get(i).accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 399) parameters.get(i) ==> java.util.List.get(int)
+  Line 401) removeNulls(parameters) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 403) n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 405) throwz.size() ==> java.util.List.size()
+  Line 406) throwz.set(i, (ReferenceType) throwz.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 406) throwz.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 406) throwz.get(i) ==> java.util.List.get(int)
+  Line 408) removeNulls(throwz) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 410) n.setBody((BlockStmt) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.body.ConstructorDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 410) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 410) n.getBody() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getBody()
+  Line 415) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 420) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 421) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 421) n.getBody() ==> com.github.javaparser.ast.stmt.DoStmt.getBody()
+  Line 425) n.setBody(body) ==> com.github.javaparser.ast.stmt.DoStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 427) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 427) n.getCondition() ==> com.github.javaparser.ast.stmt.DoStmt.getCondition()
+  Line 431) n.setCondition(condition) ==> com.github.javaparser.ast.stmt.DoStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 437) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 442) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 447) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 452) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 457) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 458) n.setInner((Expression) n.getInner().accept(this, arg)) ==> com.github.javaparser.ast.expr.EnclosedExpr.setInner(com.github.javaparser.ast.expr.Expression)
+  Line 458) n.getInner().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 458) n.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 463) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 464) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 466) annotations.size() ==> java.util.List.size()
+  Line 467) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 467) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 467) annotations.get(i) ==> java.util.List.get(int)
+  Line 469) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 471) n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 473) args.size() ==> java.util.List.size()
+  Line 474) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 474) args.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 474) args.get(i) ==> java.util.List.get(int)
+  Line 476) removeNulls(args) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 478) n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 480) classBody.size() ==> java.util.List.size()
+  Line 481) classBody.set(i, (BodyDeclaration<?>) classBody.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 481) classBody.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 481) classBody.get(i) ==> java.util.List.get(int)
+  Line 483) removeNulls(classBody) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 489) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 490) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 492) annotations.size() ==> java.util.List.size()
+  Line 493) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 493) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 493) annotations.get(i) ==> java.util.List.get(int)
+  Line 495) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 497) n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 499) implementz.size() ==> java.util.List.size()
+  Line 500) implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 500) implementz.get(i).accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 500) implementz.get(i) ==> java.util.List.get(int)
+  Line 502) removeNulls(implementz) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 504) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 506) entries.size() ==> java.util.List.size()
+  Line 507) entries.set(i, (EnumConstantDeclaration) entries.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 507) entries.get(i).accept(this, arg) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 507) entries.get(i) ==> java.util.List.get(int)
+  Line 509) removeNulls(entries) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 511) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 513) members.size() ==> java.util.List.size()
+  Line 514) members.set(i, (BodyDeclaration<?>) members.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 514) members.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 514) members.get(i) ==> java.util.List.get(int)
+  Line 516) removeNulls(members) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 522) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 523) n.isThis() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.isThis()
+  Line 523) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 524) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 524) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 524) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 526) n.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 528) typeArguments.size() ==> java.util.List.size()
+  Line 529) typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 529) typeArguments.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 529) typeArguments.get(i) ==> java.util.List.get(int)
+  Line 531) removeNulls(typeArguments) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 533) n.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 535) args.size() ==> java.util.List.size()
+  Line 536) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 536) args.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 536) args.get(i) ==> java.util.List.get(int)
+  Line 538) removeNulls(args) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 544) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 545) n.getExpression().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 545) n.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 549) n.setExpression(expr) ==> com.github.javaparser.ast.stmt.ExpressionStmt.setExpression(com.github.javaparser.ast.expr.Expression)
+  Line 554) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 555) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 555) n.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 559) n.setScope(scope) ==> com.github.javaparser.ast.expr.FieldAccessExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 564) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 565) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 567) annotations.size() ==> java.util.List.size()
+  Line 568) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 568) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 568) annotations.get(i) ==> java.util.List.get(int)
+  Line 570) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 572) n.setElementType((Type) n.getElementType().accept(this, arg)) ==> com.github.javaparser.ast.body.FieldDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 572) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 572) n.getElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getElementType()
+  Line 573) n.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 574) variables.size() ==> java.util.List.size()
+  Line 575) variables.set(i, (VariableDeclarator) variables.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 575) variables.get(i).accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 575) variables.get(i) ==> java.util.List.get(int)
+  Line 577) removeNulls(variables) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 582) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 583) n.setVariable((VariableDeclarationExpr) n.getVariable().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ForeachStmt.setVariable(com.github.javaparser.ast.expr.VariableDeclarationExpr)
+  Line 583) n.getVariable().accept(this, arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 583) n.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 584) n.setIterable((Expression) n.getIterable().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ForeachStmt.setIterable(com.github.javaparser.ast.expr.Expression)
+  Line 584) n.getIterable().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 584) n.getIterable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getIterable()
+  Line 585) n.setBody((Statement) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ForeachStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 585) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 585) n.getBody() ==> com.github.javaparser.ast.stmt.ForeachStmt.getBody()
+  Line 590) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 591) n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 593) init.size() ==> java.util.List.size()
+  Line 594) init.set(i, (Expression) init.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 594) init.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 594) init.get(i) ==> java.util.List.get(int)
+  Line 596) removeNulls(init) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 598) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 599) n.setCompare((Expression) n.getCompare().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ForStmt.setCompare(com.github.javaparser.ast.expr.Expression)
+  Line 599) n.getCompare().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 599) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 601) n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 603) update.size() ==> java.util.List.size()
+  Line 604) update.set(i, (Expression) update.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 604) update.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 604) update.get(i) ==> java.util.List.get(int)
+  Line 606) removeNulls(update) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 608) n.setBody((Statement) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ForStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 608) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 608) n.getBody() ==> com.github.javaparser.ast.stmt.ForStmt.getBody()
+  Line 613) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 615) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 615) n.getCondition() ==> com.github.javaparser.ast.stmt.IfStmt.getCondition()
+  Line 619) n.setCondition(condition) ==> com.github.javaparser.ast.stmt.IfStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 620) n.getThenStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 620) n.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 627) n.setThenStmt(thenStmt) ==> com.github.javaparser.ast.stmt.IfStmt.setThenStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 628) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 629) n.setElseStmt((Statement) n.getElseStmt().accept(this, arg)) ==> com.github.javaparser.ast.stmt.IfStmt.setElseStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 629) n.getElseStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 629) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 635) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 636) n.setName((NameExpr) n.getName().accept(this, arg)) ==> com.github.javaparser.ast.ImportDeclaration.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 636) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 636) n.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 641) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 642) n.setBlock((BlockStmt) n.getBlock().accept(this, arg)) ==> com.github.javaparser.ast.body.InitializerDeclaration.setBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 642) n.getBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 642) n.getBlock() ==> com.github.javaparser.ast.body.InitializerDeclaration.getBlock()
+  Line 647) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 648) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> com.github.javaparser.ast.expr.InstanceOfExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 648) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 648) n.getExpr() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getExpr()
+  Line 649) n.setType((Type) n.getType().accept(this, arg)) ==> com.github.javaparser.ast.expr.InstanceOfExpr.setType(com.github.javaparser.ast.type.Type)
+  Line 649) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 649) n.getType() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getType()
+  Line 654) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 659) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 668) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 669) n.setStmt((Statement) n.getStmt().accept(this, arg)) ==> com.github.javaparser.ast.stmt.LabeledStmt.setStmt(com.github.javaparser.ast.stmt.Statement)
+  Line 669) n.getStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 669) n.getStmt() ==> com.github.javaparser.ast.stmt.LabeledStmt.getStmt()
+  Line 674) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 679) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 684) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 685) n.setName((NameExpr) n.getName().accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 685) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 685) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 690) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 691) n.setValue((Expression) n.getValue().accept(this, arg)) ==> com.github.javaparser.ast.expr.MemberValuePair.setValue(com.github.javaparser.ast.expr.Expression)
+  Line 691) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 691) n.getValue() ==> com.github.javaparser.ast.expr.MemberValuePair.getValue()
+  Line 696) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 697) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 698) n.setScope((Expression) n.getScope().accept(this, arg)) ==> com.github.javaparser.ast.expr.MethodCallExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 698) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 698) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 700) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 702) typeArguments.size() ==> java.util.List.size()
+  Line 703) typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 703) typeArguments.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 703) typeArguments.get(i) ==> java.util.List.get(int)
+  Line 705) removeNulls(typeArguments) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 707) n.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 709) args.size() ==> java.util.List.size()
+  Line 710) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 710) args.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 710) args.get(i) ==> java.util.List.get(int)
+  Line 712) removeNulls(args) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 718) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 719) n.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 721) annotations.size() ==> java.util.List.size()
+  Line 722) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 722) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 722) annotations.get(i) ==> java.util.List.get(int)
+  Line 724) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 726) n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 728) typeParameters.size() ==> java.util.List.size()
+  Line 729) typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 729) typeParameters.get(i).accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 729) typeParameters.get(i) ==> java.util.List.get(int)
+  Line 731) removeNulls(typeParameters) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 733) n.setElementType((Type) n.getElementType().accept(this, arg)) ==> com.github.javaparser.ast.body.MethodDeclaration.setElementType(com.github.javaparser.ast.type.Type)
+  Line 733) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 733) n.getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 734) n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 736) parameters.size() ==> java.util.List.size()
+  Line 737) parameters.set(i, (Parameter) parameters.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 737) parameters.get(i).accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 737) parameters.get(i) ==> java.util.List.get(int)
+  Line 739) removeNulls(parameters) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 741) n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 743) throwz.size() ==> java.util.List.size()
+  Line 744) throwz.set(i, (ReferenceType) throwz.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 744) throwz.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 744) throwz.get(i) ==> java.util.List.get(int)
+  Line 746) removeNulls(throwz) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 748) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 749) n.setBody((BlockStmt) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.body.MethodDeclaration.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 749) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 749) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 755) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 760) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 761) n.setName((NameExpr) n.getName().accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 761) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 761) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 762) n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 764) pairs.size() ==> java.util.List.size()
+  Line 765) pairs.set(i, (MemberValuePair) pairs.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 765) pairs.get(i).accept(this, arg) ==> com.github.javaparser.ast.expr.MemberValuePair.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 765) pairs.get(i) ==> java.util.List.get(int)
+  Line 767) removeNulls(pairs) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 773) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 778) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 779) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 780) n.setScope((Expression) n.getScope().accept(this, arg)) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 780) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 780) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 782) n.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 784) typeArguments.size() ==> java.util.List.size()
+  Line 785) typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 785) typeArguments.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 785) typeArguments.get(i) ==> java.util.List.get(int)
+  Line 787) removeNulls(typeArguments) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 789) n.setType((ClassOrInterfaceType) n.getType().accept(this, arg)) ==> com.github.javaparser.ast.expr.ObjectCreationExpr.setType(com.github.javaparser.ast.type.Type<?>)
+  Line 789) n.getType().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 789) n.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 790) n.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 792) args.size() ==> java.util.List.size()
+  Line 793) args.set(i, (Expression) args.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 793) args.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 793) args.get(i) ==> java.util.List.get(int)
+  Line 795) removeNulls(args) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 797) n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 799) anonymousClassBody.size() ==> java.util.List.size()
+  Line 800) anonymousClassBody.set(i, (BodyDeclaration<?>) anonymousClassBody.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 800) anonymousClassBody.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 800) anonymousClassBody.get(i) ==> java.util.List.get(int)
+  Line 802) removeNulls(anonymousClassBody) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 808) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 809) n.getAnnotations() ==> com.github.javaparser.ast.PackageDeclaration.getAnnotations()
+  Line 811) annotations.size() ==> java.util.List.size()
+  Line 812) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 812) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 812) annotations.get(i) ==> java.util.List.get(int)
+  Line 814) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 816) n.setName((NameExpr) n.getName().accept(this, arg)) ==> com.github.javaparser.ast.PackageDeclaration.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 816) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 816) n.getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 821) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 822) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 823) n.setId((VariableDeclaratorId) n.getId().accept(this, arg)) ==> com.github.javaparser.ast.body.Parameter.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 823) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 823) n.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 824) n.setElementType((Type) n.getElementType().accept(this, arg)) ==> com.github.javaparser.ast.body.Parameter.setElementType(com.github.javaparser.ast.type.Type)
+  Line 824) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 824) n.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 829) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 830) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 835) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 836) n.setQualifier((NameExpr) n.getQualifier().accept(this, arg)) ==> com.github.javaparser.ast.expr.QualifiedNameExpr.setQualifier(com.github.javaparser.ast.expr.NameExpr)
+  Line 836) n.getQualifier().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 836) n.getQualifier() ==> com.github.javaparser.ast.expr.QualifiedNameExpr.getQualifier()
+  Line 842) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 843) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 844) n.setComponentType((Type) n.getComponentType().accept(this, arg)) ==> com.github.javaparser.ast.type.ArrayType.setComponentType(com.github.javaparser.ast.type.Type)
+  Line 844) n.getComponentType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 844) n.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 850) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 851) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 852) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 853) n.setDimension((Expression) n.getDimension().accept(this, arg)) ==> com.github.javaparser.ast.ArrayCreationLevel.setDimension(com.github.javaparser.ast.expr.Expression)
+  Line 853) n.getDimension().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 853) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 860) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 861) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 862) n.getElements() ==> com.github.javaparser.ast.type.IntersectionType.getElements()
+  Line 864) elements.size() ==> java.util.List.size()
+  Line 865) elements.set(i, (ReferenceType) elements.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 865) elements.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 865) elements.get(i) ==> java.util.List.get(int)
+  Line 867) removeNulls(elements) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 874) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 875) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 876) n.getElements() ==> com.github.javaparser.ast.type.UnionType.getElements()
+  Line 878) elements.size() ==> java.util.List.size()
+  Line 879) elements.set(i, (ReferenceType) elements.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 879) elements.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 879) elements.get(i) ==> java.util.List.get(int)
+  Line 881) removeNulls(elements) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 887) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 888) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 889) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ReturnStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 889) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 889) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 895) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 896) n.setName((NameExpr) n.getName().accept(this, arg)) ==> com.github.javaparser.ast.expr.AnnotationExpr.setName(com.github.javaparser.ast.expr.NameExpr)
+  Line 896) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 896) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 897) n.setMemberValue((Expression) n.getMemberValue().accept(this, arg)) ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.setMemberValue(com.github.javaparser.ast.expr.Expression)
+  Line 897) n.getMemberValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 897) n.getMemberValue() ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.getMemberValue()
+  Line 902) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 907) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 908) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 909) n.setClassExpr((Expression) n.getClassExpr().accept(this, arg)) ==> com.github.javaparser.ast.expr.SuperExpr.setClassExpr(com.github.javaparser.ast.expr.Expression)
+  Line 909) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 909) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 915) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 916) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 917) n.setLabel((Expression) n.getLabel().accept(this, arg)) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.setLabel(com.github.javaparser.ast.expr.Expression)
+  Line 917) n.getLabel().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 917) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 919) n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 921) stmts.size() ==> java.util.List.size()
+  Line 922) stmts.set(i, (Statement) stmts.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 922) stmts.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 922) stmts.get(i) ==> java.util.List.get(int)
+  Line 924) removeNulls(stmts) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 930) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 931) n.setSelector((Expression) n.getSelector().accept(this, arg)) ==> com.github.javaparser.ast.stmt.SwitchStmt.setSelector(com.github.javaparser.ast.expr.Expression)
+  Line 931) n.getSelector().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 931) n.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 932) n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 934) entries.size() ==> java.util.List.size()
+  Line 935) entries.set(i, (SwitchEntryStmt) entries.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 935) entries.get(i).accept(this, arg) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 935) entries.get(i) ==> java.util.List.get(int)
+  Line 937) removeNulls(entries) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 944) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 945) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> com.github.javaparser.ast.stmt.SynchronizedStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 945) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 945) n.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 946) n.setBody((BlockStmt) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.stmt.SynchronizedStmt.setBody(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 946) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 946) n.getBody() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getBody()
+  Line 951) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 952) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 953) n.setClassExpr((Expression) n.getClassExpr().accept(this, arg)) ==> com.github.javaparser.ast.expr.ThisExpr.setClassExpr(com.github.javaparser.ast.expr.Expression)
+  Line 953) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 953) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 959) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 960) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> com.github.javaparser.ast.stmt.ThrowStmt.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 960) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 960) n.getExpr() ==> com.github.javaparser.ast.stmt.ThrowStmt.getExpr()
+  Line 965) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 966) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 967) types.size() ==> java.util.List.size()
+  Line 968) n.getResources().set(i, (VariableDeclarationExpr) n.getResources().get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 968) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 969) n.getResources().get(i).accept(this, arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 969) n.getResources().get(i) ==> java.util.List.get(int)
+  Line 969) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 971) n.setTryBlock((BlockStmt) n.getTryBlock().accept(this, arg)) ==> com.github.javaparser.ast.stmt.TryStmt.setTryBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 971) n.getTryBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 971) n.getTryBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getTryBlock()
+  Line 972) n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 974) catchs.size() ==> java.util.List.size()
+  Line 975) catchs.set(i, (CatchClause) catchs.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 975) catchs.get(i).accept(this, arg) ==> com.github.javaparser.ast.stmt.CatchClause.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 975) catchs.get(i) ==> java.util.List.get(int)
+  Line 977) removeNulls(catchs) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 979) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 980) n.setFinallyBlock((BlockStmt) n.getFinallyBlock().accept(this, arg)) ==> com.github.javaparser.ast.stmt.TryStmt.setFinallyBlock(com.github.javaparser.ast.stmt.BlockStmt)
+  Line 980) n.getFinallyBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 980) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 986) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 987) n.setTypeDeclaration((TypeDeclaration<?>) n.getTypeDeclaration().accept(this, arg)) ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.setTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration)
+  Line 987) n.getTypeDeclaration().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 987) n.getTypeDeclaration() ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.getTypeDeclaration()
+  Line 992) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 993) n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 995) typeBound.size() ==> java.util.List.size()
+  Line 996) typeBound.set(i, (ClassOrInterfaceType) typeBound.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 996) typeBound.get(i).accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 996) typeBound.get(i) ==> java.util.List.get(int)
+  Line 998) removeNulls(typeBound) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 1004) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1005) n.setExpr((Expression) n.getExpr().accept(this, arg)) ==> com.github.javaparser.ast.expr.UnaryExpr.setExpr(com.github.javaparser.ast.expr.Expression)
+  Line 1005) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1005) n.getExpr() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpr()
+  Line 1010) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1015) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1016) n.getAnnotations() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getAnnotations()
+  Line 1018) annotations.size() ==> java.util.List.size()
+  Line 1019) annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 1019) annotations.get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1019) annotations.get(i) ==> java.util.List.get(int)
+  Line 1021) removeNulls(annotations) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 1024) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1024) n.getElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getElementType()
+  Line 1028) n.setElementType(type) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.setElementType(com.github.javaparser.ast.type.Type)
+  Line 1030) n.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 1031) vars.size() ==> java.util.List.size()
+  Line 1033) vars.get(i).accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1033) vars.get(i) ==> java.util.List.get(int)
+  Line 1035) vars.remove(i) ==> java.util.List.remove(int)
+  Line 1037) vars.set(i++, decl) ==> java.util.List.set(int, E)
+  Line 1040) vars.isEmpty() ==> java.util.List.isEmpty()
+  Line 1048) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1050) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1050) n.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 1054) n.setId(id) ==> com.github.javaparser.ast.body.VariableDeclarator.setId(com.github.javaparser.ast.body.VariableDeclaratorId)
+  Line 1055) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 1056) n.setInit((Expression) n.getInit().accept(this, arg)) ==> com.github.javaparser.ast.body.VariableDeclarator.setInit(com.github.javaparser.ast.expr.Expression)
+  Line 1056) n.getInit().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1056) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 1062) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1067) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1068) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 1073) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1074) n.setCondition((Expression) n.getCondition().accept(this, arg)) ==> com.github.javaparser.ast.stmt.WhileStmt.setCondition(com.github.javaparser.ast.expr.Expression)
+  Line 1074) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1074) n.getCondition() ==> com.github.javaparser.ast.stmt.WhileStmt.getCondition()
+  Line 1075) n.setBody((Statement) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.stmt.WhileStmt.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 1075) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1075) n.getBody() ==> com.github.javaparser.ast.stmt.WhileStmt.getBody()
+  Line 1080) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1081) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 1082) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 1083) n.setExtends((ReferenceType) n.getExtends().accept(this, arg)) ==> com.github.javaparser.ast.type.WildcardType.setExtends(com.github.javaparser.ast.type.ReferenceType)
+  Line 1083) n.getExtends().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1083) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 1085) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 1086) n.setSuper((ReferenceType) n.getSuper().accept(this, arg)) ==> com.github.javaparser.ast.type.WildcardType.setSuper(com.github.javaparser.ast.type.ReferenceType)
+  Line 1086) n.getSuper().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1086) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 1093) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1094) n.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 1095) parameters.size() ==> java.util.List.size()
+  Line 1096) parameters.set(i, (Parameter) parameters.get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 1096) parameters.get(i).accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1096) parameters.get(i) ==> java.util.List.get(int)
+  Line 1098) removeNulls(parameters) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.removeNulls(java.util.List<?>)
+  Line 1099) n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1100) n.setBody((Statement) n.getBody().accept(this, arg)) ==> com.github.javaparser.ast.expr.LambdaExpr.setBody(com.github.javaparser.ast.stmt.Statement)
+  Line 1100) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1100) n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 1107) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1108) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1109) types.size() ==> java.util.List.size()
+  Line 1110) n.getTypeArguments().set(i, (Type<?>) n.getTypeArguments().get(i).accept(this, arg)) ==> java.util.List.set(int, E)
+  Line 1110) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1111) n.getTypeArguments().get(i).accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1111) n.getTypeArguments().get(i) ==> java.util.List.get(int)
+  Line 1111) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 1113) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1114) n.setScope((Expression) n.getScope().accept(this, arg)) ==> com.github.javaparser.ast.expr.MethodReferenceExpr.setScope(com.github.javaparser.ast.expr.Expression)
+  Line 1114) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1114) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 1121) visitComment(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitComment(com.github.javaparser.ast.Node, A)
+  Line 1122) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1123) n.setType((Type<?>) n.getType().accept(this, arg)) ==> com.github.javaparser.ast.expr.TypeExpr.setType(com.github.javaparser.ast.type.Type<?>)
+  Line 1123) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1123) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 1130) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.ModifierVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 1145) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 1146) n.setComment((Comment) n.getComment().accept(this, arg)) ==> com.github.javaparser.ast.Node.setComment(com.github.javaparser.ast.comments.Comment)
+  Line 1146) n.getComment().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 1146) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_TreeVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_TreeVisitor.txt
new file mode 100644
index 0000000..b267e5f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_TreeVisitor.txt
@@ -0,0 +1,3 @@
+  Line 37) process(node) ==> com.github.javaparser.ast.visitor.TreeVisitor.process(com.github.javaparser.ast.Node)
+  Line 38) node.getChildrenNodes() ==> com.github.javaparser.ast.Node.getChildrenNodes()
+  Line 39) visitDepthFirst(child) ==> com.github.javaparser.ast.visitor.TreeVisitor.visitDepthFirst(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_VoidVisitor.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_VoidVisitor.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_VoidVisitor.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_VoidVisitorAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_VoidVisitorAdapter.txt
new file mode 100644
index 0000000..2ad1131
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_ast_visitor_VoidVisitorAdapter.txt
@@ -0,0 +1,511 @@
+  Line 93) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 93) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 94) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 95) n.getNameExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 95) n.getNameExpr() ==> com.github.javaparser.ast.body.TypeDeclaration.getNameExpr()
+  Line 96) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 97) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 98) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 104) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 104) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 105) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 106) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 106) n.getType() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getType()
+  Line 107) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 108) n.getDefaultValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 108) n.getDefaultValue() ==> com.github.javaparser.ast.body.AnnotationMemberDeclaration.getDefaultValue()
+  Line 113) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 113) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 114) n.getName().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 114) n.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 115) n.getIndex().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 115) n.getIndex() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getIndex()
+  Line 119) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 119) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 120) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 120) n.getType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getType()
+  Line 121) n.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 122) level.accept(this, arg) ==> com.github.javaparser.ast.ArrayCreationLevel.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 124) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 125) n.getInitializer().accept(this, arg) ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 125) n.getInitializer() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getInitializer()
+  Line 130) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 130) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 131) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 132) n.getValues() ==> com.github.javaparser.ast.expr.ArrayInitializerExpr.getValues()
+  Line 133) expr.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 139) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 139) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 140) n.getCheck().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 140) n.getCheck() ==> com.github.javaparser.ast.stmt.AssertStmt.getCheck()
+  Line 141) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 142) n.getMessage().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 142) n.getMessage() ==> com.github.javaparser.ast.stmt.AssertStmt.getMessage()
+  Line 147) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 147) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 148) n.getTarget().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 148) n.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 149) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 149) n.getValue() ==> com.github.javaparser.ast.expr.AssignExpr.getValue()
+  Line 153) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 153) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 154) n.getLeft().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 154) n.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 155) n.getRight().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 155) n.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 162) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 162) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 163) n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 164) n.getStmts() ==> com.github.javaparser.ast.stmt.BlockStmt.getStmts()
+  Line 165) s.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 171) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 171) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 175) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 175) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 179) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 179) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 180) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 180) n.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 181) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 181) n.getExpr() ==> com.github.javaparser.ast.expr.CastExpr.getExpr()
+  Line 185) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 185) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 186) n.getParam().accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 186) n.getParam() ==> com.github.javaparser.ast.stmt.CatchClause.getParam()
+  Line 187) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 187) n.getBody() ==> com.github.javaparser.ast.stmt.CatchClause.getBody()
+  Line 191) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 191) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 195) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 195) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 196) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 196) n.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 200) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 200) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 201) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 202) n.getNameExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 202) n.getNameExpr() ==> com.github.javaparser.ast.body.TypeDeclaration.getNameExpr()
+  Line 203) n.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 204) t.accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 206) n.getExtends() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtends()
+  Line 207) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 209) n.getImplements() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplements()
+  Line 210) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 212) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 213) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 218) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 218) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 219) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 220) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 221) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 221) n.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 223) n.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 224) n.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 225) t.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 231) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 231) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 232) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 233) n.getPackage().accept(this, arg) ==> com.github.javaparser.ast.PackageDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 233) n.getPackage() ==> com.github.javaparser.ast.CompilationUnit.getPackage()
+  Line 235) n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 236) n.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 237) i.accept(this, arg) ==> com.github.javaparser.ast.ImportDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 240) n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 241) n.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 242) typeDeclaration.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 248) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 248) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 249) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 249) n.getCondition() ==> com.github.javaparser.ast.expr.ConditionalExpr.getCondition()
+  Line 250) n.getThenExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 250) n.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 251) n.getElseExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 251) n.getElseExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getElseExpr()
+  Line 255) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 255) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 256) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 257) n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 258) n.getTypeParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getTypeParameters()
+  Line 259) t.accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 262) n.getNameExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 262) n.getNameExpr() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getNameExpr()
+  Line 263) n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 264) n.getParameters() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getParameters()
+  Line 265) p.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 268) n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 269) n.getThrows() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getThrows()
+  Line 270) name.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 273) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 273) n.getBody() ==> com.github.javaparser.ast.body.ConstructorDeclaration.getBody()
+  Line 277) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 277) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 281) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 281) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 282) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 282) n.getBody() ==> com.github.javaparser.ast.stmt.DoStmt.getBody()
+  Line 283) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 283) n.getCondition() ==> com.github.javaparser.ast.stmt.DoStmt.getCondition()
+  Line 287) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 287) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 291) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 291) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 295) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 295) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 299) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 299) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 300) n.getNameExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 300) n.getNameExpr() ==> com.github.javaparser.ast.body.TypeDeclaration.getNameExpr()
+  Line 304) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 304) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 305) n.getInner().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 305) n.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 309) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 309) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 310) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 311) n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 312) n.getArgs() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getArgs()
+  Line 313) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 316) n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 317) n.getClassBody() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getClassBody()
+  Line 318) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 324) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 324) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 325) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 326) n.getNameExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 326) n.getNameExpr() ==> com.github.javaparser.ast.body.TypeDeclaration.getNameExpr()
+  Line 327) n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 328) n.getImplements() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplements()
+  Line 329) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 332) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 333) n.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 334) e.accept(this, arg) ==> com.github.javaparser.ast.body.EnumConstantDeclaration.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 337) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 338) n.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 339) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 345) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 345) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 346) n.isThis() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.isThis()
+  Line 346) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 347) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 347) n.getExpr() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getExpr()
+  Line 349) n.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 350) n.getTypeArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getTypeArguments()
+  Line 351) t.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 354) n.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 355) n.getArgs() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArgs()
+  Line 356) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 362) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 362) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 363) n.getExpression().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 363) n.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 367) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 367) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 368) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 368) n.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 369) n.getFieldExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 369) n.getFieldExpr() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getFieldExpr()
+  Line 373) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 373) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 374) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 375) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 375) n.getElementType() ==> com.github.javaparser.ast.body.FieldDeclaration.getElementType()
+  Line 376) n.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 377) var.accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 382) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 382) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 383) n.getVariable().accept(this, arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 383) n.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 384) n.getIterable().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 384) n.getIterable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getIterable()
+  Line 385) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 385) n.getBody() ==> com.github.javaparser.ast.stmt.ForeachStmt.getBody()
+  Line 389) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 389) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 390) n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 391) n.getInit() ==> com.github.javaparser.ast.stmt.ForStmt.getInit()
+  Line 392) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 395) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 396) n.getCompare().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 396) n.getCompare() ==> com.github.javaparser.ast.stmt.ForStmt.getCompare()
+  Line 398) n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 399) n.getUpdate() ==> com.github.javaparser.ast.stmt.ForStmt.getUpdate()
+  Line 400) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 403) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 403) n.getBody() ==> com.github.javaparser.ast.stmt.ForStmt.getBody()
+  Line 407) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 407) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 408) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 408) n.getCondition() ==> com.github.javaparser.ast.stmt.IfStmt.getCondition()
+  Line 409) n.getThenStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 409) n.getThenStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getThenStmt()
+  Line 410) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 411) n.getElseStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 411) n.getElseStmt() ==> com.github.javaparser.ast.stmt.IfStmt.getElseStmt()
+  Line 416) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 416) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 417) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 417) n.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 421) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 421) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 422) n.getBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 422) n.getBlock() ==> com.github.javaparser.ast.body.InitializerDeclaration.getBlock()
+  Line 426) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 426) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 427) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 427) n.getExpr() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getExpr()
+  Line 428) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 428) n.getType() ==> com.github.javaparser.ast.expr.InstanceOfExpr.getType()
+  Line 432) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 432) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 436) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 436) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 443) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 443) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 444) n.getStmt().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 444) n.getStmt() ==> com.github.javaparser.ast.stmt.LabeledStmt.getStmt()
+  Line 451) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 451) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 455) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 455) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 459) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 459) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 460) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 460) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 464) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 464) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 465) n.getValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 465) n.getValue() ==> com.github.javaparser.ast.expr.MemberValuePair.getValue()
+  Line 469) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 469) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 470) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 471) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 471) n.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 473) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 474) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 475) t.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 478) n.getNameExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 478) n.getNameExpr() ==> com.github.javaparser.ast.expr.MethodCallExpr.getNameExpr()
+  Line 479) n.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 480) n.getArgs() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArgs()
+  Line 481) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 487) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 487) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 488) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 489) n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 490) n.getTypeParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getTypeParameters()
+  Line 491) t.accept(this, arg) ==> com.github.javaparser.ast.type.TypeParameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 494) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 494) n.getElementType() ==> com.github.javaparser.ast.body.MethodDeclaration.getElementType()
+  Line 495) n.getNameExpr().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 495) n.getNameExpr() ==> com.github.javaparser.ast.body.MethodDeclaration.getNameExpr()
+  Line 496) n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 497) n.getParameters() ==> com.github.javaparser.ast.body.MethodDeclaration.getParameters()
+  Line 498) p.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 501) n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 502) n.getThrows() ==> com.github.javaparser.ast.body.MethodDeclaration.getThrows()
+  Line 503) name.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 506) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 507) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 507) n.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 512) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 512) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 516) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 516) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 517) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 517) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 518) n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 519) n.getPairs() ==> com.github.javaparser.ast.expr.NormalAnnotationExpr.getPairs()
+  Line 520) m.accept(this, arg) ==> com.github.javaparser.ast.expr.MemberValuePair.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 526) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 526) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 530) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 530) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 531) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 532) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 532) n.getScope() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getScope()
+  Line 534) n.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 535) n.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 536) t.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 539) n.getType().accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 539) n.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 540) n.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 541) n.getArgs() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArgs()
+  Line 542) e.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 545) n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 546) n.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 547) member.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 553) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 553) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 554) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 555) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 555) n.getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 559) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 559) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 560) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 561) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 561) n.getElementType() ==> com.github.javaparser.ast.body.Parameter.getElementType()
+  Line 562) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 562) n.getId() ==> com.github.javaparser.ast.body.Parameter.getId()
+  Line 566) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 566) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 567) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 571) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 571) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 572) n.getQualifier().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 572) n.getQualifier() ==> com.github.javaparser.ast.expr.QualifiedNameExpr.getQualifier()
+  Line 577) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 577) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 578) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 579) n.getComponentType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 579) n.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 584) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 584) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 585) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 586) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 587) n.getDimension().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 587) n.getDimension() ==> com.github.javaparser.ast.ArrayCreationLevel.getDimension()
+  Line 592) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 592) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 593) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 594) n.getElements() ==> com.github.javaparser.ast.type.IntersectionType.getElements()
+  Line 595) element.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 600) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 600) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 601) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 602) n.getElements() ==> com.github.javaparser.ast.type.UnionType.getElements()
+  Line 603) element.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 608) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 608) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 609) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 610) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 610) n.getExpr() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpr()
+  Line 615) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 615) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 616) n.getName().accept(this, arg) ==> com.github.javaparser.ast.expr.NameExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 616) n.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 617) n.getMemberValue().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 617) n.getMemberValue() ==> com.github.javaparser.ast.expr.SingleMemberAnnotationExpr.getMemberValue()
+  Line 621) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 621) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 625) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 625) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 626) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 627) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 627) n.getClassExpr() ==> com.github.javaparser.ast.expr.SuperExpr.getClassExpr()
+  Line 632) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 632) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 633) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 634) n.getLabel().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 634) n.getLabel() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getLabel()
+  Line 636) n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 637) n.getStmts() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStmts()
+  Line 638) s.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 644) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 644) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 645) n.getSelector().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 645) n.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 646) n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 647) n.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 648) e.accept(this, arg) ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 654) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 654) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 655) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 655) n.getExpr() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getExpr()
+  Line 656) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 656) n.getBody() ==> com.github.javaparser.ast.stmt.SynchronizedStmt.getBody()
+  Line 660) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 660) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 661) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 662) n.getClassExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 662) n.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 667) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 667) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 668) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 668) n.getExpr() ==> com.github.javaparser.ast.stmt.ThrowStmt.getExpr()
+  Line 672) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 672) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 673) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 674) n.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 675) v.accept(this, arg) ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 678) n.getTryBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 678) n.getTryBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getTryBlock()
+  Line 679) n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 680) n.getCatchs() ==> com.github.javaparser.ast.stmt.TryStmt.getCatchs()
+  Line 681) c.accept(this, arg) ==> com.github.javaparser.ast.stmt.CatchClause.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 684) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 685) n.getFinallyBlock().accept(this, arg) ==> com.github.javaparser.ast.stmt.BlockStmt.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 685) n.getFinallyBlock() ==> com.github.javaparser.ast.stmt.TryStmt.getFinallyBlock()
+  Line 690) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 690) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 691) n.getTypeDeclaration().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 691) n.getTypeDeclaration() ==> com.github.javaparser.ast.stmt.TypeDeclarationStmt.getTypeDeclaration()
+  Line 695) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 695) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 696) n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 697) n.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 698) c.accept(this, arg) ==> com.github.javaparser.ast.type.ClassOrInterfaceType.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 704) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 704) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 705) n.getExpr().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 705) n.getExpr() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpr()
+  Line 709) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 709) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 713) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 713) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 714) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 715) n.getElementType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 715) n.getElementType() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getElementType()
+  Line 716) n.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 717) v.accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclarator.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 722) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 722) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 723) n.getId().accept(this, arg) ==> com.github.javaparser.ast.body.VariableDeclaratorId.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 723) n.getId() ==> com.github.javaparser.ast.body.VariableDeclarator.getId()
+  Line 724) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 725) n.getInit().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 725) n.getInit() ==> com.github.javaparser.ast.body.VariableDeclarator.getInit()
+  Line 730) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 730) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 734) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 734) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 735) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 740) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 740) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 741) n.getCondition().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 741) n.getCondition() ==> com.github.javaparser.ast.stmt.WhileStmt.getCondition()
+  Line 742) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 742) n.getBody() ==> com.github.javaparser.ast.stmt.WhileStmt.getBody()
+  Line 746) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 746) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 747) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 748) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 749) n.getExtends().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 749) n.getExtends() ==> com.github.javaparser.ast.type.WildcardType.getExtends()
+  Line 751) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 752) n.getSuper().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 752) n.getSuper() ==> com.github.javaparser.ast.type.WildcardType.getSuper()
+  Line 758) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 758) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 759) n.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 760) n.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 761) a.accept(this, arg) ==> com.github.javaparser.ast.body.Parameter.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 764) n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 765) n.getBody().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 765) n.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 771) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 771) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 772) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 773) n.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getTypeArguments()
+  Line 774) t.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 777) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 778) n.getScope().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 778) n.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 784) visitComment(n.getComment(), arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitComment(com.github.javaparser.ast.comments.Comment, A)
+  Line 784) n.getComment() ==> com.github.javaparser.ast.Node.getComment()
+  Line 785) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 786) n.getType().accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 786) n.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 792) visitAnnotations(n, arg) ==> com.github.javaparser.ast.visitor.VoidVisitorAdapter.visitAnnotations(com.github.javaparser.ast.nodeTypes.NodeWithAnnotations<?>, A)
+  Line 797) n.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
+  Line 802) n.getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 803) annotation.accept(this, arg) ==> com.github.javaparser.ast.Node.accept(com.github.javaparser.ast.visitor.VoidVisitor<A>, A)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_ClassUtils.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_ClassUtils.txt
new file mode 100644
index 0000000..130079b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_ClassUtils.txt
@@ -0,0 +1,16 @@
+  Line 12) primitiveWrapperMap.put(Boolean.TYPE, Boolean.class) ==> java.util.Map.put(K, V)
+  Line 13) primitiveWrapperMap.put(Byte.TYPE, Byte.class) ==> java.util.Map.put(K, V)
+  Line 14) primitiveWrapperMap.put(Character.TYPE, Character.class) ==> java.util.Map.put(K, V)
+  Line 15) primitiveWrapperMap.put(Short.TYPE, Short.class) ==> java.util.Map.put(K, V)
+  Line 16) primitiveWrapperMap.put(Integer.TYPE, Integer.class) ==> java.util.Map.put(K, V)
+  Line 17) primitiveWrapperMap.put(Long.TYPE, Long.class) ==> java.util.Map.put(K, V)
+  Line 18) primitiveWrapperMap.put(Double.TYPE, Double.class) ==> java.util.Map.put(K, V)
+  Line 19) primitiveWrapperMap.put(Float.TYPE, Float.class) ==> java.util.Map.put(K, V)
+  Line 20) primitiveWrapperMap.put(Void.TYPE, Void.TYPE) ==> java.util.Map.put(K, V)
+  Line 28) primitiveWrapperMap.keySet() ==> java.util.Map.keySet()
+  Line 29) primitiveWrapperMap.get(primitiveClass) ==> java.util.Map.get(java.lang.Object)
+  Line 30) primitiveClass.equals(wrapperClass) ==> java.lang.Object.equals(java.lang.Object)
+  Line 31) wrapperPrimitiveMap.put(wrapperClass, primitiveClass) ==> java.util.Map.put(K, V)
+  Line 51) type.isPrimitive() ==> java.lang.Class.isPrimitive()
+  Line 51) isPrimitiveWrapper(type) ==> com.github.javaparser.utils.ClassUtils.isPrimitiveWrapper(java.lang.Class<?>)
+  Line 67) wrapperPrimitiveMap.containsKey(type) ==> java.util.Map.containsKey(java.lang.Object)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_Pair.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_Pair.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_Pair.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_PositionUtils.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_PositionUtils.txt
new file mode 100644
index 0000000..96493b0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_PositionUtils.txt
@@ -0,0 +1,43 @@
+  Line 46) sortByBeginPosition(nodes, false) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>, boolean)
+  Line 50) Collections.sort(nodes, (o1, o2) -> PositionUtils.compare(o1, o2, ignoringAnnotations)) ==> java.util.Collections.sort(java.util.List<T>, java.util.Comparator<? super T>)
+  Line 50) PositionUtils.compare(o1, o2, ignoringAnnotations) ==> com.github.javaparser.utils.PositionUtils.compare(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node, boolean)
+  Line 54) areInOrder(a, b, false) ==> com.github.javaparser.utils.PositionUtils.areInOrder(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node, boolean)
+  Line 58) compare(a, b, ignoringAnnotations) ==> com.github.javaparser.utils.PositionUtils.compare(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node, boolean)
+  Line 63) signum(beginLineWithoutConsideringAnnotation(a) - beginLineWithoutConsideringAnnotation(b)) ==> java.lang.Integer.signum(int)
+  Line 63) beginLineWithoutConsideringAnnotation(a) ==> com.github.javaparser.utils.PositionUtils.beginLineWithoutConsideringAnnotation(com.github.javaparser.ast.Node)
+  Line 63) beginLineWithoutConsideringAnnotation(b) ==> com.github.javaparser.utils.PositionUtils.beginLineWithoutConsideringAnnotation(com.github.javaparser.ast.Node)
+  Line 65) signum(beginColumnWithoutConsideringAnnotation(a) - beginColumnWithoutConsideringAnnotation(b)) ==> java.lang.Integer.signum(int)
+  Line 65) beginColumnWithoutConsideringAnnotation(a) ==> com.github.javaparser.utils.PositionUtils.beginColumnWithoutConsideringAnnotation(com.github.javaparser.ast.Node)
+  Line 65) beginColumnWithoutConsideringAnnotation(b) ==> com.github.javaparser.utils.PositionUtils.beginColumnWithoutConsideringAnnotation(com.github.javaparser.ast.Node)
+  Line 71) signum(a.getBegin().line - b.getBegin().line) ==> java.lang.Integer.signum(int)
+  Line 71) a.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 71) b.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 73) signum(a.getBegin().column - b.getBegin().column) ==> java.lang.Integer.signum(int)
+  Line 73) a.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 73) b.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 82) annotations.addAll(((NodeWithAnnotations<?>) node).getAnnotations()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 82) ((NodeWithAnnotations<?>) node).getAnnotations() ==> com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.getAnnotations()
+  Line 83) annotations.isEmpty() ==> java.util.List.isEmpty()
+  Line 86) sortByBeginPosition(annotations) ==> com.github.javaparser.utils.PositionUtils.sortByBeginPosition(java.util.List<T>)
+  Line 87) annotations.get(annotations.size() - 1) ==> java.util.List.get(int)
+  Line 87) annotations.size() ==> java.util.List.size()
+  Line 94) beginNodeWithoutConsideringAnnotations(node).getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 94) beginNodeWithoutConsideringAnnotations(node) ==> com.github.javaparser.utils.PositionUtils.beginNodeWithoutConsideringAnnotations(com.github.javaparser.ast.Node)
+  Line 99) beginNodeWithoutConsideringAnnotations(node).getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 99) beginNodeWithoutConsideringAnnotations(node) ==> com.github.javaparser.utils.PositionUtils.beginNodeWithoutConsideringAnnotations(com.github.javaparser.ast.Node)
+  Line 105) casted.getElementType() ==> com.github.javaparser.ast.nodeTypes.NodeWithElementType.getElementType()
+  Line 108) casted.getNameExpr() ==> com.github.javaparser.ast.body.TypeDeclaration.getNameExpr()
+  Line 115) PositionUtils.getLastAnnotation(container) ==> com.github.javaparser.utils.PositionUtils.getLastAnnotation(com.github.javaparser.ast.Node)
+  Line 116) container.contains(contained) ==> com.github.javaparser.ast.Node.contains(com.github.javaparser.ast.Node)
+  Line 118) container.contains(contained) ==> com.github.javaparser.ast.Node.contains(com.github.javaparser.ast.Node)
+  Line 124) beginLineWithoutConsideringAnnotation(container) ==> com.github.javaparser.utils.PositionUtils.beginLineWithoutConsideringAnnotation(com.github.javaparser.ast.Node)
+  Line 125) beginColumnWithoutConsideringAnnotation(container) ==> com.github.javaparser.utils.PositionUtils.beginColumnWithoutConsideringAnnotation(com.github.javaparser.ast.Node)
+  Line 126) contained.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 127) contained.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 127) contained.getBegin() ==> com.github.javaparser.ast.Node.getBegin()
+  Line 128) container.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 128) contained.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 130) container.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 130) contained.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 130) container.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
+  Line 130) contained.getEnd() ==> com.github.javaparser.ast.Node.getEnd()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_Utils.txt b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_Utils.txt
new file mode 100644
index 0000000..3fd87b9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javaparser_methodcalls_expected_output/com_github_javaparser_utils_Utils.txt
@@ -0,0 +1,14 @@
+  Line 37) System.getProperty("line.separator") ==> java.lang.System.getProperty(java.lang.String)
+  Line 43) collection.isEmpty() ==> java.util.Collection.isEmpty()
+  Line 58) string.toCharArray() ==> java.lang.String.toCharArray()
+  Line 61) escapedString.append("\\n") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 64) escapedString.append("\\r") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 67) escapedString.append(c) ==> java.lang.StringBuilder.append(char)
+  Line 70) escapedString.toString() ==> java.lang.StringBuilder.toString()
+  Line 78) reader.read(buffer, 0, buffer.length) ==> java.io.Reader.read(char[], int, int)
+  Line 79) result.append(buffer, 0, numChars) ==> java.lang.StringBuilder.append(char[], int, int)
+  Line 82) result.toString() ==> java.lang.StringBuilder.toString()
+  Line 90) provider.read(buffer, 0, buffer.length) ==> com.github.javaparser.Provider.read(char[], int, int)
+  Line 91) result.append(buffer, 0, numChars) ==> java.lang.StringBuilder.append(char[], int, int)
+  Line 94) result.toString() ==> java.lang.StringBuilder.toString()
+  Line 103) Collections.addAll(list, array) ==> java.util.Collections.addAll(java.util.Collection<? super T>, T...)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/README.md b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/README.md
new file mode 100644
index 0000000..389f94c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/README.md
@@ -0,0 +1,8 @@
+For the tests regarding resolving symbols in Jar files, we need some jar files. Some other tests within JavaSymbolSolver use established external jars for that purpose. Given the very specific cases we need here, that would severly complicate writing and maintaining tests. Therefore, I've decided to write custom jars for the cases we need.
+
+`main_jar` contains most of the necessary classes, `included_jar` and `excluded_jar` both contain an interface and a superclass. Included_jar is included in the combined type solver, while excluded_jar is not.
+
+Running the buildTestJarMainJar gradle task should rebuild all necessary files.
+When you need to rebuild the jar, it is important to make sure you actually update the jar in git. Jar-files are in the git-ignore, so you'll have to force-add them using `git -f main_jar.jar`.
+
+(`result` was chosen as a name instead of `target` or `out`, because those seem to be ignored.)
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/excluded_jar.jar b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/excluded_jar.jar
new file mode 100644
index 0000000..2f5058e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/excluded_jar.jar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/result/doNotDelete.md b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/result/doNotDelete.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/result/doNotDelete.md
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/excluded_jar/InterfaceExcludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/excluded_jar/InterfaceExcludedJar.java
new file mode 100644
index 0000000..0dd82c2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/excluded_jar/InterfaceExcludedJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar;
+
+public interface InterfaceExcludedJar {
+    public static final String INTERFACE_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/excluded_jar/SuperClassExcludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/excluded_jar/SuperClassExcludedJar.java
new file mode 100644
index 0000000..6eb45f0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/excluded_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/excluded_jar/SuperClassExcludedJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar;
+
+public class SuperClassExcludedJar {
+    public static final String SUPER_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/included_jar.jar b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/included_jar.jar
new file mode 100644
index 0000000..990697e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/included_jar.jar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/result/doNotDelete.md b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/result/doNotDelete.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/result/doNotDelete.md
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/included_jar/InterfaceIncludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/included_jar/InterfaceIncludedJar.java
new file mode 100644
index 0000000..6afbd09
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/included_jar/InterfaceIncludedJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.included_jar;
+
+public interface InterfaceIncludedJar {
+    public static final String INTERFACE_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/included_jar/SuperClassIncludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/included_jar/SuperClassIncludedJar.java
new file mode 100644
index 0000000..44be5ca
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/included_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/included_jar/SuperClassIncludedJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.included_jar;
+
+public class SuperClassIncludedJar {
+    public static final String SUPER_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/main_jar.jar b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/main_jar.jar
new file mode 100644
index 0000000..faec52d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/main_jar.jar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/result/doNotDelete.md b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/result/doNotDelete.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/result/doNotDelete.md
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/ConcreteClass.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/ConcreteClass.java
new file mode 100644
index 0000000..b861683
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/ConcreteClass.java
@@ -0,0 +1,6 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public class ConcreteClass {
+    public static final String STATIC_STRING = "ThisIsAString";
+    public static final String SECOND_STRING = "ThisIsASecondString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/ConcreteEnum.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/ConcreteEnum.java
new file mode 100644
index 0000000..6dc2467
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/ConcreteEnum.java
@@ -0,0 +1,10 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public enum ConcreteEnum {
+    ENUM_VAL_ONE,
+    ENUM_VAL_TWO;
+
+    public static final String STATIC_STRING = "ThisIsAString";
+    public static final String SECOND_STRING = "ThisIsASecondString";
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserExcludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserExcludedJar.java
new file mode 100644
index 0000000..0d403ac
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserExcludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar;
+
+public enum EnumInterfaceUserExcludedJar implements InterfaceExcludedJar {
+    OWN_ENUM_VAL
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserIncludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserIncludedJar.java
new file mode 100644
index 0000000..910e5d0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserIncludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.included_jar.InterfaceIncludedJar;
+
+public enum EnumInterfaceUserIncludedJar implements InterfaceIncludedJar {
+    OWN_ENUM_VAL
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserOwnJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserOwnJar.java
new file mode 100644
index 0000000..43bf703
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/EnumInterfaceUserOwnJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public enum EnumInterfaceUserOwnJar implements InterfaceOwnJar {
+    OWN_ENUM_VAL
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceOwnJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceOwnJar.java
new file mode 100644
index 0000000..6809f26
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceOwnJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public interface InterfaceOwnJar {
+    public static final String INTERFACE_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserExcludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserExcludedJar.java
new file mode 100644
index 0000000..5e483f3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserExcludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar;
+
+public class InterfaceUserExcludedJar implements InterfaceExcludedJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserIncludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserIncludedJar.java
new file mode 100644
index 0000000..2eba271
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserIncludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.included_jar.InterfaceIncludedJar;
+
+public class InterfaceUserIncludedJar implements InterfaceIncludedJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserOwnJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserOwnJar.java
new file mode 100644
index 0000000..4126915
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/InterfaceUserOwnJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public class InterfaceUserOwnJar implements InterfaceOwnJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/StandaloneInterface.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/StandaloneInterface.java
new file mode 100644
index 0000000..99e1f00
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/StandaloneInterface.java
@@ -0,0 +1,6 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public interface StandaloneInterface {
+    public static final String STATIC_STRING = "ThisIsAString";
+    public static final String SECOND_STRING = "ThisIsASecondString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassExcludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassExcludedJar.java
new file mode 100644
index 0000000..6c495ed
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassExcludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.SuperClassExcludedJar;
+
+public class SubClassExcludedJar extends SuperClassExcludedJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassIncludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassIncludedJar.java
new file mode 100644
index 0000000..32a4d10
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassIncludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.included_jar.SuperClassIncludedJar;
+
+public class SubClassIncludedJar extends SuperClassIncludedJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassOwnJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassOwnJar.java
new file mode 100644
index 0000000..41efa3c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubClassOwnJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public class SubClassOwnJar extends SuperClassOwnJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceExcludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceExcludedJar.java
new file mode 100644
index 0000000..3021e08
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceExcludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar;
+
+public interface SubInterfaceExcludedJar extends InterfaceExcludedJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceIncludedJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceIncludedJar.java
new file mode 100644
index 0000000..906e537
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceIncludedJar.java
@@ -0,0 +1,7 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+import com.github.javaparser.javasymbolsolver.javassist_symbols.included_jar.InterfaceIncludedJar;
+
+public interface SubInterfaceIncludedJar extends InterfaceIncludedJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceOwnJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceOwnJar.java
new file mode 100644
index 0000000..891e94e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SubInterfaceOwnJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public interface SubInterfaceOwnJar extends InterfaceOwnJar {
+    public static final String OWN_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SuperClassOwnJar.java b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SuperClassOwnJar.java
new file mode 100644
index 0000000..d89666b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javassist_symbols/main_jar/src/com/github/javaparser/javasymbolsolver/javassist_symbols/main_jar/SuperClassOwnJar.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;
+
+public class SuperClassOwnJar {
+    public static final String SUPER_FIELD = "ThisIsAString";
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_SourceFileInfoExtractor.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_SourceFileInfoExtractor.txt
new file mode 100644
index 0000000..8537d62
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_SourceFileInfoExtractor.txt
@@ -0,0 +1,77 @@
+  Line 100) JavaParserFacade.get(typeSolver).getTypeDeclaration(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 100) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 101) typeDeclaration.isClass() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isClass()
+  Line 102) out.println("\n[ Class " + typeDeclaration.getQualifiedName() + " ]") ==> java.io.PrintStream.println(java.lang.String)
+  Line 102) typeDeclaration.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 103) typeDeclaration.asClass().getAllSuperClasses() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getAllSuperClasses()
+  Line 103) typeDeclaration.asClass() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asClass()
+  Line 104) out.println("  superclass: " + sc.getQualifiedName()) ==> java.io.PrintStream.println(java.lang.String)
+  Line 104) sc.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 106) typeDeclaration.asClass().getAllInterfaces() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getAllInterfaces()
+  Line 106) typeDeclaration.asClass() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asClass()
+  Line 107) out.println("  interface: " + sc.getQualifiedName()) ==> java.io.PrintStream.println(java.lang.String)
+  Line 107) sc.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 114) solveTypeDecl((ClassOrInterfaceDeclaration) node) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.solveTypeDecl(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 116) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 116) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 117) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 118) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 120) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 120) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 122) JavaParserFacade.get(typeSolver).getType(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 122) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 123) out.println("  Line " + node.getRange().get().begin.line + ") " + node + " ==> " + ref.describe()) ==> java.io.PrintStream.println(java.lang.String)
+  Line 123) node.getRange().get() ==> java.util.Optional.get()
+  Line 123) node.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 123) ref.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 127) err.println(upe.getMessage()) ==> java.io.PrintStream.println(java.lang.String)
+  Line 127) upe.getMessage() ==> java.lang.Throwable.getMessage()
+  Line 131) err.println(re.getMessage()) ==> java.io.PrintStream.println(java.lang.String)
+  Line 131) re.getMessage() ==> java.lang.Throwable.getMessage()
+  Line 140) out.println("  Line " + node.getBegin().get().line + ") " + node + " ==> " + toString((MethodCallExpr) node)) ==> java.io.PrintStream.println(java.lang.String)
+  Line 140) node.getBegin().get() ==> java.util.Optional.get()
+  Line 140) node.getBegin() ==> com.github.javaparser.ast.nodeTypes.NodeWithRange.getBegin()
+  Line 140) toString((MethodCallExpr) node) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.toString(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 142) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 143) solveMethodCalls(child) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.solveMethodCalls(com.github.javaparser.ast.Node)
+  Line 149) toString(JavaParserFacade.get(typeSolver).solve(node)) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.toString(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>)
+  Line 149) JavaParserFacade.get(typeSolver).solve(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 149) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 152) System.err.println("Error resolving call at L" + node.getBegin().get().line + ": " + node) ==> java.io.PrintStream.println(java.lang.String)
+  Line 152) node.getBegin().get() ==> java.util.Optional.get()
+  Line 152) node.getBegin() ==> com.github.javaparser.ast.nodeTypes.NodeWithRange.getBegin()
+  Line 153) e.printStackTrace() ==> java.lang.Throwable.printStackTrace()
+  Line 160) methodDeclarationSymbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 161) methodDeclarationSymbolReference.getCorrespondingDeclaration().getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 161) methodDeclarationSymbolReference.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 169) collectAllNodes(node, nodes) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.collectAllNodes(com.github.javaparser.ast.Node, java.util.List<com.github.javaparser.ast.Node>)
+  Line 170) nodes.sort((n1, n2) -> n1.getBegin().get().compareTo(n2.getBegin().get())) ==> java.util.List.sort(java.util.Comparator<? super E>)
+  Line 170) n1.getBegin().get().compareTo(n2.getBegin().get()) ==> ERROR
+  Line 170) n1.getBegin().get() ==> ERROR
+  Line 170) n1.getBegin() ==> com.github.javaparser.ast.nodeTypes.NodeWithRange.getBegin()
+  Line 170) n2.getBegin().get() ==> ERROR
+  Line 170) n2.getBegin() ==> com.github.javaparser.ast.nodeTypes.NodeWithRange.getBegin()
+  Line 175) nodes.add(node) ==> java.util.List.add(E)
+  Line 176) node.getChildNodes().forEach(c -> collectAllNodes(c, nodes)) ==> java.lang.Iterable.forEach(java.util.function.Consumer<? super T>)
+  Line 176) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 176) collectAllNodes(c, nodes) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.collectAllNodes(com.github.javaparser.ast.Node, java.util.List<com.github.javaparser.ast.Node>)
+  Line 180) file.isDirectory() ==> java.io.File.isDirectory()
+  Line 181) file.listFiles() ==> java.io.File.listFiles()
+  Line 182) solve(f) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.solve(java.io.File)
+  Line 185) file.getName().endsWith(".java") ==> java.lang.String.endsWith(java.lang.String)
+  Line 185) file.getName() ==> java.io.File.getName()
+  Line 187) out.println("- parsing " + file.getAbsolutePath()) ==> java.io.PrintStream.println(java.lang.String)
+  Line 187) file.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 189) JavaParser.parse(file) ==> com.github.javaparser.JavaParser.parse(java.io.File)
+  Line 190) collectAllNodes(cu) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.collectAllNodes(com.github.javaparser.ast.Node)
+  Line 191) nodes.forEach(n -> solve(n)) ==> java.lang.Iterable.forEach(java.util.function.Consumer<? super T>)
+  Line 191) solve(n) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.solve(com.github.javaparser.ast.Node)
+  Line 197) file.isDirectory() ==> java.io.File.isDirectory()
+  Line 198) file.listFiles() ==> java.io.File.listFiles()
+  Line 199) solveMethodCalls(f) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.solveMethodCalls(java.io.File)
+  Line 202) file.getName().endsWith(".java") ==> java.lang.String.endsWith(java.lang.String)
+  Line 202) file.getName() ==> java.io.File.getName()
+  Line 204) out.println("- parsing " + file.getAbsolutePath()) ==> java.io.PrintStream.println(java.lang.String)
+  Line 204) file.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 206) JavaParser.parse(file) ==> com.github.javaparser.JavaParser.parse(java.io.File)
+  Line 207) solveMethodCalls(cu) ==> com.github.javaparser.symbolsolver.SourceFileInfoExtractor.solveMethodCalls(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_core_resolution_Context.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_core_resolution_Context.txt
new file mode 100644
index 0000000..ddde45d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_core_resolution_Context.txt
@@ -0,0 +1,16 @@
+  Line 42) Optional.empty() ==> java.util.Optional.empty()
+  Line 46) getParent() ==> com.github.javaparser.symbolsolver.core.resolution.Context.getParent()
+  Line 48) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 50) parent.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 59) solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 60) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 61) Value.from(ref.getCorrespondingDeclaration()) ==> com.github.javaparser.symbolsolver.model.resolution.Value.from(com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration)
+  Line 61) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 62) Optional.of(value) ==> java.util.Optional.of(T)
+  Line 64) Optional.empty() ==> java.util.Optional.empty()
+  Line 89) solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 90) methodSolved.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 91) methodSolved.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 92) ContextHelper.resolveTypeVariables(this, methodDeclaration, argumentsTypes) ==> com.github.javaparser.symbolsolver.core.resolution.ContextHelper.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 93) Optional.of(methodUsage) ==> java.util.Optional.of(T)
+  Line 95) Optional.empty() ==> java.util.Optional.empty()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_core_resolution_ContextHelper.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_core_resolution_ContextHelper.txt
new file mode 100644
index 0000000..396ccf7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_core_resolution_ContextHelper.txt
@@ -0,0 +1,4 @@
+  Line 40) ((JavaParserMethodDeclaration) methodDeclaration).resolveTypeVariables(context, parameterTypes) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 42) ((JavassistMethodDeclaration) methodDeclaration).resolveTypeVariables(context, parameterTypes) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistMethodDeclaration.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 44) ((JavaParserEnumDeclaration.ValuesMethod) methodDeclaration).resolveTypeVariables(context, parameterTypes) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.ValuesMethod.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 46) ((ReflectionMethodDeclaration) methodDeclaration).resolveTypeVariables(context, parameterTypes) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodDeclaration.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_declarations_common_MethodDeclarationCommonLogic.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_declarations_common_MethodDeclarationCommonLogic.txt
new file mode 100644
index 0000000..243cffe
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_declarations_common_MethodDeclarationCommonLogic.txt
@@ -0,0 +1,34 @@
+  Line 47) replaceTypeParams(methodDeclaration.getReturnType(), typeSolver, context) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.replaceTypeParams(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 47) methodDeclaration.getReturnType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration.getReturnType()
+  Line 49) methodDeclaration.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 50) replaceTypeParams(methodDeclaration.getParam(i).getType(), typeSolver, context) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.replaceTypeParams(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 50) methodDeclaration.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 50) methodDeclaration.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 51) params.add(replaced) ==> java.util.List.add(E)
+  Line 58) methodDeclaration.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 58) methodDeclaration.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 59) methodDeclaration.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 59) methodDeclaration.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 60) parameterTypes.get(i) ==> java.util.List.get(int)
+  Line 61) inferenceContext.addPair(formalParamType, actualParamType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 64) inferenceContext.resolve(inferenceContext.addSingle(returnType)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 64) inferenceContext.addSingle(returnType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 70) type.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 71) type.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 72) typeParameter.declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 73) typeParamByName(typeParameter.getName(), typeSolver, context) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.typeParamByName(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 73) typeParameter.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 74) typeParam.isPresent() ==> java.util.Optional.isPresent()
+  Line 75) typeParam.get() ==> java.util.Optional.get()
+  Line 80) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 81) type.asReferenceType().transformTypeParameters(tp -> replaceTypeParams(tp, typeSolver, context)) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.transformTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer)
+  Line 81) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 81) replaceTypeParams(tp, typeSolver, context) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.replaceTypeParams(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 88) methodDeclaration.getTypeParameters().stream().filter(tp -> tp.getName().equals(name)).map(tp -> toType(tp)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 88) methodDeclaration.getTypeParameters().stream().filter(tp -> tp.getName().equals(name)).map(tp -> toType(tp)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 88) methodDeclaration.getTypeParameters().stream().filter(tp -> tp.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 88) methodDeclaration.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 88) methodDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 88) tp.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 88) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 88) toType(tp) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.toType(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparser_Navigator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparser_Navigator.txt
new file mode 100644
index 0000000..ea0f5e5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparser_Navigator.txt
@@ -0,0 +1,104 @@
+  Line 44) node.getParentNode().orElse(null) ==> java.util.Optional.orElse(T)
+  Line 44) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 49) cu.getTypes().isEmpty() ==> com.github.javaparser.ast.NodeList.isEmpty()
+  Line 49) cu.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 50) Optional.empty() ==> java.util.Optional.empty()
+  Line 53) getOuterTypeName(qualifiedName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getOuterTypeName(java.lang.String)
+  Line 54) cu.getTypes().stream().filter((t) -> t.getName().getId().equals(typeName)).findFirst() ==> ERROR
+  Line 54) cu.getTypes().stream().filter((t) -> t.getName().getId().equals(typeName)) ==> ERROR
+  Line 54) cu.getTypes().stream() ==> java.util.Collection.stream()
+  Line 54) cu.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 54) t.getName().getId().equals(typeName) ==> ERROR
+  Line 54) t.getName().getId() ==> ERROR
+  Line 54) t.getName() ==> ERROR
+  Line 56) getInnerTypeName(qualifiedName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getInnerTypeName(java.lang.String)
+  Line 57) type.isPresent() ==> java.util.Optional.isPresent()
+  Line 57) innerTypeName.isEmpty() ==> java.lang.String.isEmpty()
+  Line 58) findType(type.get(), innerTypeName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findType(com.github.javaparser.ast.body.TypeDeclaration<?>, java.lang.String)
+  Line 58) type.get() ==> java.util.Optional.get()
+  Line 64) getOuterTypeName(qualifiedName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getOuterTypeName(java.lang.String)
+  Line 66) Optional.empty() ==> java.util.Optional.empty()
+  Line 67) td.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 68) ((TypeDeclaration<?>) n).getName().getId().equals(typeName) ==> java.lang.String.equals(java.lang.Object)
+  Line 68) ((TypeDeclaration<?>) n).getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 68) ((TypeDeclaration<?>) n).getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 69) Optional.of((TypeDeclaration<?>) n) ==> java.util.Optional.of(T)
+  Line 73) getInnerTypeName(qualifiedName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getInnerTypeName(java.lang.String)
+  Line 74) type.isPresent() ==> java.util.Optional.isPresent()
+  Line 74) innerTypeName.isEmpty() ==> java.lang.String.isEmpty()
+  Line 75) findType(type.get(), innerTypeName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findType(com.github.javaparser.ast.body.TypeDeclaration<?>, java.lang.String)
+  Line 75) type.get() ==> java.util.Optional.get()
+  Line 81) demandClassOrInterface(cu, qualifiedName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.demandClassOrInterface(com.github.javaparser.ast.CompilationUnit, java.lang.String)
+  Line 82) cd.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 89) findType(cu, qualifiedName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findType(com.github.javaparser.ast.CompilationUnit, java.lang.String)
+  Line 90) res.isPresent() ==> java.util.Optional.isPresent()
+  Line 93) res.get() ==> java.util.Optional.get()
+  Line 96) res.get() ==> java.util.Optional.get()
+  Line 101) cd.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 104) md.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 104) md.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 104) md.getName() ==> com.github.javaparser.ast.body.CallableDeclaration.getName()
+  Line 119) cd.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 122) fd.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 123) vd.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 123) vd.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 123) vd.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 135) nameExpr.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 135) nameExpr.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 135) nameExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 135) nameExpr.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 139) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 140) findNameExpression(child, name) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findNameExpression(com.github.javaparser.ast.Node, java.lang.String)
+  Line 151) nameExpr.getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 151) nameExpr.getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 151) nameExpr.getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 155) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 156) findSimpleName(child, name) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findSimpleName(com.github.javaparser.ast.Node, java.lang.String)
+  Line 167) methodCallExpr.getName().getId().equals(methodName) ==> java.lang.String.equals(java.lang.Object)
+  Line 167) methodCallExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 167) methodCallExpr.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 171) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 172) findMethodCall(child, methodName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findMethodCall(com.github.javaparser.ast.Node, java.lang.String)
+  Line 183) variableDeclarator.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 183) variableDeclarator.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 183) variableDeclarator.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 187) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 188) demandVariableDeclaration(child, name) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.demandVariableDeclaration(com.github.javaparser.ast.Node, java.lang.String)
+  Line 197) findType(compilationUnit, qualifiedName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findType(com.github.javaparser.ast.CompilationUnit, java.lang.String)
+  Line 198) res.isPresent() ==> java.util.Optional.isPresent()
+  Line 201) res.get() ==> java.util.Optional.get()
+  Line 202) res.get().getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 202) res.get().getClass() ==> java.lang.Object.getClass()
+  Line 202) res.get() ==> java.util.Optional.get()
+  Line 204) res.get() ==> java.util.Optional.get()
+  Line 209) findSwitchHelper(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findSwitchHelper(com.github.javaparser.ast.Node)
+  Line 218) findNodeOfGivenClassHelper(node, clazz) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findNodeOfGivenClassHelper(com.github.javaparser.ast.Node, java.lang.Class<N>)
+  Line 228) findAllNodesOfGivenClassHelper(node, clazz, res) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findAllNodesOfGivenClassHelper(com.github.javaparser.ast.Node, java.lang.Class<N>, java.util.List<N>)
+  Line 233) findNodeOfGivenClass(method, ReturnStmt.class) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findNodeOfGivenClass(com.github.javaparser.ast.Node, java.lang.Class<N>)
+  Line 237) node.getParentNode().isPresent() ==> java.util.Optional.isPresent()
+  Line 237) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 238) Optional.empty() ==> java.util.Optional.empty()
+  Line 239) clazz.isInstance(node.getParentNode().get()) ==> java.lang.Class.isInstance(java.lang.Object)
+  Line 239) node.getParentNode().get() ==> java.util.Optional.get()
+  Line 239) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 240) Optional.of(clazz.cast(node.getParentNode().get())) ==> java.util.Optional.of(T)
+  Line 240) clazz.cast(node.getParentNode().get()) ==> java.lang.Class.cast(java.lang.Object)
+  Line 240) node.getParentNode().get() ==> java.util.Optional.get()
+  Line 240) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 242) findAncestor(node.getParentNode().get(), clazz) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findAncestor(com.github.javaparser.ast.Node, java.lang.Class<N>)
+  Line 242) node.getParentNode().get() ==> java.util.Optional.get()
+  Line 242) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 251) qualifiedName.split("\\.", 2) ==> java.lang.String.split(java.lang.String, int)
+  Line 255) qualifiedName.contains(".") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 256) qualifiedName.split("\\.", 2) ==> java.lang.String.split(java.lang.String, int)
+  Line 265) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 266) findSwitchHelper(child) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findSwitchHelper(com.github.javaparser.ast.Node)
+  Line 275) clazz.isInstance(node) ==> java.lang.Class.isInstance(java.lang.Object)
+  Line 276) clazz.cast(node) ==> java.lang.Class.cast(java.lang.Object)
+  Line 278) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 279) findNodeOfGivenClassHelper(child, clazz) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findNodeOfGivenClassHelper(com.github.javaparser.ast.Node, java.lang.Class<N>)
+  Line 288) clazz.isInstance(node) ==> java.lang.Class.isInstance(java.lang.Object)
+  Line 289) collector.add(clazz.cast(node)) ==> java.util.List.add(E)
+  Line 289) clazz.cast(node) ==> java.lang.Class.cast(java.lang.Object)
+  Line 291) node.getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 292) findAllNodesOfGivenClassHelper(child, clazz, collector) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findAllNodesOfGivenClassHelper(com.github.javaparser.ast.Node, java.lang.Class<N>, java.util.List<N>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_DefaultVisitorAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_DefaultVisitorAdapter.txt
new file mode 100644
index 0000000..b55a600
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_DefaultVisitorAdapter.txt
@@ -0,0 +1,180 @@
+  Line 18) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 18) node.getClass() ==> java.lang.Object.getClass()
+  Line 23) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 23) node.getClass() ==> java.lang.Object.getClass()
+  Line 28) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 28) node.getClass() ==> java.lang.Object.getClass()
+  Line 33) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 33) node.getClass() ==> java.lang.Object.getClass()
+  Line 38) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 38) node.getClass() ==> java.lang.Object.getClass()
+  Line 43) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 43) node.getClass() ==> java.lang.Object.getClass()
+  Line 48) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 48) node.getClass() ==> java.lang.Object.getClass()
+  Line 53) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 53) node.getClass() ==> java.lang.Object.getClass()
+  Line 58) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 58) node.getClass() ==> java.lang.Object.getClass()
+  Line 63) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 63) node.getClass() ==> java.lang.Object.getClass()
+  Line 68) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 68) node.getClass() ==> java.lang.Object.getClass()
+  Line 73) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 73) node.getClass() ==> java.lang.Object.getClass()
+  Line 78) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 78) node.getClass() ==> java.lang.Object.getClass()
+  Line 83) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 83) node.getClass() ==> java.lang.Object.getClass()
+  Line 88) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 88) node.getClass() ==> java.lang.Object.getClass()
+  Line 93) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 93) node.getClass() ==> java.lang.Object.getClass()
+  Line 98) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 98) node.getClass() ==> java.lang.Object.getClass()
+  Line 103) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 103) node.getClass() ==> java.lang.Object.getClass()
+  Line 108) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 108) node.getClass() ==> java.lang.Object.getClass()
+  Line 113) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 113) node.getClass() ==> java.lang.Object.getClass()
+  Line 118) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 118) node.getClass() ==> java.lang.Object.getClass()
+  Line 123) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 123) node.getClass() ==> java.lang.Object.getClass()
+  Line 128) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 128) node.getClass() ==> java.lang.Object.getClass()
+  Line 133) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 133) node.getClass() ==> java.lang.Object.getClass()
+  Line 138) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 138) node.getClass() ==> java.lang.Object.getClass()
+  Line 143) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 143) node.getClass() ==> java.lang.Object.getClass()
+  Line 148) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 148) node.getClass() ==> java.lang.Object.getClass()
+  Line 153) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 153) node.getClass() ==> java.lang.Object.getClass()
+  Line 158) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 158) node.getClass() ==> java.lang.Object.getClass()
+  Line 163) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 163) node.getClass() ==> java.lang.Object.getClass()
+  Line 168) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 168) node.getClass() ==> java.lang.Object.getClass()
+  Line 173) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 173) node.getClass() ==> java.lang.Object.getClass()
+  Line 178) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 178) node.getClass() ==> java.lang.Object.getClass()
+  Line 183) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 183) node.getClass() ==> java.lang.Object.getClass()
+  Line 188) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 188) node.getClass() ==> java.lang.Object.getClass()
+  Line 193) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 193) node.getClass() ==> java.lang.Object.getClass()
+  Line 198) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 198) node.getClass() ==> java.lang.Object.getClass()
+  Line 203) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 203) node.getClass() ==> java.lang.Object.getClass()
+  Line 208) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 208) node.getClass() ==> java.lang.Object.getClass()
+  Line 213) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 213) node.getClass() ==> java.lang.Object.getClass()
+  Line 218) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 218) node.getClass() ==> java.lang.Object.getClass()
+  Line 223) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 223) node.getClass() ==> java.lang.Object.getClass()
+  Line 228) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 228) node.getClass() ==> java.lang.Object.getClass()
+  Line 233) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 233) node.getClass() ==> java.lang.Object.getClass()
+  Line 238) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 238) node.getClass() ==> java.lang.Object.getClass()
+  Line 243) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 243) node.getClass() ==> java.lang.Object.getClass()
+  Line 248) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 248) node.getClass() ==> java.lang.Object.getClass()
+  Line 253) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 253) node.getClass() ==> java.lang.Object.getClass()
+  Line 258) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 258) node.getClass() ==> java.lang.Object.getClass()
+  Line 263) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 263) node.getClass() ==> java.lang.Object.getClass()
+  Line 268) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 268) node.getClass() ==> java.lang.Object.getClass()
+  Line 273) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 273) node.getClass() ==> java.lang.Object.getClass()
+  Line 278) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 278) node.getClass() ==> java.lang.Object.getClass()
+  Line 283) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 283) node.getClass() ==> java.lang.Object.getClass()
+  Line 288) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 288) node.getClass() ==> java.lang.Object.getClass()
+  Line 293) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 293) node.getClass() ==> java.lang.Object.getClass()
+  Line 298) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 298) node.getClass() ==> java.lang.Object.getClass()
+  Line 303) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 303) node.getClass() ==> java.lang.Object.getClass()
+  Line 308) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 308) node.getClass() ==> java.lang.Object.getClass()
+  Line 313) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 313) node.getClass() ==> java.lang.Object.getClass()
+  Line 318) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 318) node.getClass() ==> java.lang.Object.getClass()
+  Line 323) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 323) node.getClass() ==> java.lang.Object.getClass()
+  Line 328) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 328) node.getClass() ==> java.lang.Object.getClass()
+  Line 333) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 333) node.getClass() ==> java.lang.Object.getClass()
+  Line 338) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 338) node.getClass() ==> java.lang.Object.getClass()
+  Line 343) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 343) node.getClass() ==> java.lang.Object.getClass()
+  Line 348) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 348) node.getClass() ==> java.lang.Object.getClass()
+  Line 353) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 353) node.getClass() ==> java.lang.Object.getClass()
+  Line 358) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 358) node.getClass() ==> java.lang.Object.getClass()
+  Line 363) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 363) node.getClass() ==> java.lang.Object.getClass()
+  Line 368) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 368) node.getClass() ==> java.lang.Object.getClass()
+  Line 373) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 373) node.getClass() ==> java.lang.Object.getClass()
+  Line 378) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 378) node.getClass() ==> java.lang.Object.getClass()
+  Line 383) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 383) node.getClass() ==> java.lang.Object.getClass()
+  Line 388) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 388) node.getClass() ==> java.lang.Object.getClass()
+  Line 393) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 393) node.getClass() ==> java.lang.Object.getClass()
+  Line 398) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 398) node.getClass() ==> java.lang.Object.getClass()
+  Line 403) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 403) node.getClass() ==> java.lang.Object.getClass()
+  Line 408) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 408) node.getClass() ==> java.lang.Object.getClass()
+  Line 413) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 413) node.getClass() ==> java.lang.Object.getClass()
+  Line 418) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 418) node.getClass() ==> java.lang.Object.getClass()
+  Line 423) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 423) node.getClass() ==> java.lang.Object.getClass()
+  Line 428) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 428) node.getClass() ==> java.lang.Object.getClass()
+  Line 433) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 433) node.getClass() ==> java.lang.Object.getClass()
+  Line 438) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 438) node.getClass() ==> java.lang.Object.getClass()
+  Line 443) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 443) node.getClass() ==> java.lang.Object.getClass()
+  Line 448) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 448) node.getClass() ==> java.lang.Object.getClass()
+  Line 453) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 453) node.getClass() ==> java.lang.Object.getClass()
+  Line 458) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 458) node.getClass() ==> java.lang.Object.getClass()
+  Line 463) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 463) node.getClass() ==> java.lang.Object.getClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_JavaParserFacade.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_JavaParserFacade.txt
new file mode 100644
index 0000000..bb9ceb3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_JavaParserFacade.txt
@@ -0,0 +1,253 @@
+  Line 58) Logger.getLogger(JavaParserFacade.class.getCanonicalName()) ==> java.util.logging.Logger.getLogger(java.lang.String)
+  Line 58) JavaParserFacade.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 61) logger.setLevel(Level.INFO) ==> java.util.logging.Logger.setLevel(java.util.logging.Level)
+  Line 63) consoleHandler.setLevel(Level.INFO) ==> java.util.logging.Handler.setLevel(java.util.logging.Level)
+  Line 64) logger.addHandler(consoleHandler) ==> java.util.logging.Logger.addHandler(java.util.logging.Handler)
+  Line 75) typeSolver.getRoot() ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.getRoot()
+  Line 89) instances.computeIfAbsent(typeSolver, JavaParserFacade::new) ==> java.util.Map.computeIfAbsent(K, java.util.function.Function<? super K, ? extends V>)
+  Line 96) instances.clear() ==> java.util.Map.clear()
+  Line 100) type.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 101) context.solveGenericType(type.describe(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveGenericType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 101) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 102) solved.isPresent() ==> java.util.Optional.isPresent()
+  Line 103) solved.get() ==> java.util.Optional.get()
+  Line 107) type.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 108) type.asWildcard().isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 108) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 108) type.asWildcard().isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 108) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 109) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 110) solveGenericTypes(wildcardUsage.getBoundedType(), context, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.core.resolution.Context, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 110) wildcardUsage.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 111) wildcardUsage.isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 112) Wildcard.extendsBound(boundResolved) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 114) Wildcard.superBound(boundResolved) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 126) symbolSolver.solveSymbol(nameExpr.getName().getId(), nameExpr) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbol(java.lang.String, com.github.javaparser.ast.Node)
+  Line 126) nameExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 126) nameExpr.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 130) symbolSolver.solveSymbol(nameExpr.getId(), nameExpr) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbol(java.lang.String, com.github.javaparser.ast.Node)
+  Line 130) nameExpr.getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 135) solve((NameExpr) expr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.NameExpr)
+  Line 137) expr.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 137) expr.getClass() ==> java.lang.Object.getClass()
+  Line 142) solve(methodCallExpr, true) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.MethodCallExpr, boolean)
+  Line 146) solve(objectCreationExpr, true) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.ObjectCreationExpr, boolean)
+  Line 150) solve(explicitConstructorInvocationStmt, true) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt, boolean)
+  Line 157) solveArguments(explicitConstructorInvocationStmt, explicitConstructorInvocationStmt.getArguments(), solveLambdas, argumentTypes, placeholders) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveArguments(com.github.javaparser.ast.Node, com.github.javaparser.ast.NodeList<com.github.javaparser.ast.expr.Expression>, boolean, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, java.util.List<com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder>)
+  Line 157) explicitConstructorInvocationStmt.getArguments() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.getArguments()
+  Line 159) explicitConstructorInvocationStmt.getAncestorOfType(ClassOrInterfaceDeclaration.class) ==> com.github.javaparser.HasParentNode.getAncestorOfType(java.lang.Class<N>)
+  Line 160) optAncestor.isPresent() ==> java.util.Optional.isPresent()
+  Line 161) SymbolReference.unsolved(ConstructorDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 163) optAncestor.get() ==> java.util.Optional.get()
+  Line 165) explicitConstructorInvocationStmt.isThis() ==> com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt.isThis()
+  Line 166) JavaParserFacade.get(typeSolver).convert(classNode.getExtendedTypes(0), classNode) ==> UNSOLVED
+  Line 166) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 166) classNode.getExtendedTypes(0) ==> com.github.javaparser.ast.nodeTypes.NodeWithExtends.getExtendedTypes(int)
+  Line 167) classDecl.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 168) classDecl.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 168) classDecl.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 171) JavaParserFactory.getContext(classNode, typeSolver).solveType(classNode.getNameAsString(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 171) JavaParserFactory.getContext(classNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 171) classNode.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.getNameAsString()
+  Line 172) sr.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 173) sr.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 177) SymbolReference.unsolved(ConstructorDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 179) ConstructorResolutionLogic.findMostApplicable(((ClassDeclaration) typeDecl).getConstructors(), argumentTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration>, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 179) ((ClassDeclaration) typeDecl).getConstructors() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getConstructors()
+  Line 181) placeholder.setMethod(res) ==> com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder.setMethod(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration>)
+  Line 188) node.getClassExpr().isPresent() ==> java.util.Optional.isPresent()
+  Line 188) node.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 190) node.getClassExpr().get().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 190) node.getClassExpr().get() ==> java.util.Optional.get()
+  Line 190) node.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 192) typeSolver.tryToSolveType(className) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 193) clazz.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 194) SymbolReference.solved(clazz.getCorrespondingDeclaration()) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 194) clazz.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 197) node.getAncestorOfType(CompilationUnit.class) ==> com.github.javaparser.HasParentNode.getAncestorOfType(java.lang.Class<N>)
+  Line 198) cu.isPresent() ==> java.util.Optional.isPresent()
+  Line 199) cu.get().getClassByName(className) ==> com.github.javaparser.ast.CompilationUnit.getClassByName(java.lang.String)
+  Line 199) cu.get() ==> java.util.Optional.get()
+  Line 200) classByName.isPresent() ==> java.util.Optional.isPresent()
+  Line 201) SymbolReference.solved(getTypeDeclaration(classByName.get())) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 201) getTypeDeclaration(classByName.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 201) classByName.get() ==> java.util.Optional.get()
+  Line 205) SymbolReference.solved(getTypeDeclaration(findContainingTypeDecl(node))) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 205) getTypeDeclaration(findContainingTypeDecl(node)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 205) findContainingTypeDecl(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.findContainingTypeDecl(com.github.javaparser.ast.Node)
+  Line 215) solveArguments(objectCreationExpr, objectCreationExpr.getArguments(), solveLambdas, argumentTypes, placeholders) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveArguments(com.github.javaparser.ast.Node, com.github.javaparser.ast.NodeList<com.github.javaparser.ast.expr.Expression>, boolean, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, java.util.List<com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder>)
+  Line 215) objectCreationExpr.getArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getArguments()
+  Line 217) JavaParserFacade.get(typeSolver).convert(objectCreationExpr.getType(), objectCreationExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 217) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 217) objectCreationExpr.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 218) classDecl.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 219) SymbolReference.unsolved(ConstructorDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 221) ConstructorResolutionLogic.findMostApplicable(((ClassDeclaration) classDecl.asReferenceType().getTypeDeclaration()).getConstructors(), argumentTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration>, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 221) ((ClassDeclaration) classDecl.asReferenceType().getTypeDeclaration()).getConstructors() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getConstructors()
+  Line 221) classDecl.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 221) classDecl.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 223) placeholder.setMethod(res) ==> com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder.setMethod(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration>)
+  Line 233) argumentTypes.add(placeholder) ==> java.util.List.add(E)
+  Line 234) placeholders.add(placeholder) ==> java.util.List.add(E)
+  Line 237) argumentTypes.add(JavaParserFacade.get(typeSolver).getType(parameterValue, solveLambdas)) ==> java.util.List.add(E)
+  Line 237) JavaParserFacade.get(typeSolver).getType(parameterValue, solveLambdas) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node, boolean)
+  Line 237) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 241) String.format("Unable to calculate the type of a parameter of a method call. Method call: %s, Parameter: %s", node, parameterValue) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 256) solveArguments(methodCallExpr, methodCallExpr.getArguments(), solveLambdas, argumentTypes, placeholders) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveArguments(com.github.javaparser.ast.Node, com.github.javaparser.ast.NodeList<com.github.javaparser.ast.expr.Expression>, boolean, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, java.util.List<com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder>)
+  Line 256) methodCallExpr.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 258) JavaParserFactory.getContext(methodCallExpr, typeSolver).solveMethod(methodCallExpr.getName().getId(), argumentTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 258) JavaParserFactory.getContext(methodCallExpr, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 258) methodCallExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 258) methodCallExpr.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 260) placeholder.setMethod(res) ==> com.github.javaparser.symbolsolver.javaparsermodel.LambdaArgumentTypePlaceholder.setMethod(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration>)
+  Line 266) JavaParserFactory.getContext(annotationExpr, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 267) context.solveType(annotationExpr.getNameAsString(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 267) annotationExpr.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithName.getNameAsString()
+  Line 268) typeDeclarationSymbolReference.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 269) typeDeclarationSymbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 270) SymbolReference.solved(annotationDeclaration) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 272) SymbolReference.unsolved(AnnotationDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 277) getType(node, true) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node, boolean)
+  Line 282) cacheWithLambdasSolved.containsKey(node) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 283) getTypeConcrete(node, solveLambdas) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeConcrete(com.github.javaparser.ast.Node, boolean)
+  Line 285) cacheWithLambdasSolved.put(node, res) ==> java.util.Map.put(K, V)
+  Line 290) methodCallExpr.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 291) cacheWithLambdasSolved.containsKey(arg) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 292) getType(arg, true) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node, boolean)
+  Line 298) cacheWithLambdasSolved.remove(node) ==> java.util.Map.remove(java.lang.Object)
+  Line 299) cacheWithLambdasSolved.put(node, getType(node, true)) ==> java.util.Map.put(K, V)
+  Line 299) getType(node, true) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node, boolean)
+  Line 301) logger.finer("getType on " + node + " -> " + res) ==> java.util.logging.Logger.finer(java.lang.String)
+  Line 303) cacheWithLambdasSolved.get(node) ==> java.util.Map.get(java.lang.Object)
+  Line 305) find(cacheWithLambdasSolved, node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.find(java.util.Map<com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.ast.Node)
+  Line 306) res.isPresent() ==> java.util.Optional.isPresent()
+  Line 307) res.get() ==> java.util.Optional.get()
+  Line 309) find(cacheWithoutLambdasSolved, node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.find(java.util.Map<com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.ast.Node)
+  Line 310) res.isPresent() ==> java.util.Optional.isPresent()
+  Line 311) getTypeConcrete(node, solveLambdas) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeConcrete(com.github.javaparser.ast.Node, boolean)
+  Line 312) cacheWithoutLambdasSolved.put(node, resType) ==> java.util.Map.put(K, V)
+  Line 313) logger.finer("getType on " + node + " (no solveLambdas) -> " + res) ==> java.util.logging.Logger.finer(java.lang.String)
+  Line 316) res.get() ==> java.util.Optional.get()
+  Line 321) map.containsKey(node) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 322) Optional.of(map.get(node)) ==> java.util.Optional.of(T)
+  Line 322) map.get(node) ==> java.util.Map.get(java.lang.Object)
+  Line 325) find(map, (LambdaExpr) node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.find(java.util.Map<com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.ast.expr.LambdaExpr)
+  Line 327) Optional.empty() ==> java.util.Optional.empty()
+  Line 338) map.keySet() ==> java.util.Map.keySet()
+  Line 341) keyLambdaExpr.toString().equals(lambdaExpr.toString()) ==> java.lang.String.equals(java.lang.Object)
+  Line 341) keyLambdaExpr.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 341) lambdaExpr.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 341) getParentNode(keyLambdaExpr) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 341) getParentNode(lambdaExpr) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 342) Optional.of(map.get(keyLambdaExpr)) ==> java.util.Optional.of(T)
+  Line 342) map.get(keyLambdaExpr) ==> java.util.Map.get(java.lang.Object)
+  Line 346) Optional.empty() ==> java.util.Optional.empty()
+  Line 350) methodReferenceExpr.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 353) methodReferenceExpr.getScope() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getScope()
+  Line 354) typeExpr.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 355) typeExpr.getType().getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 355) typeExpr.getType().getClass() ==> java.lang.Object.getClass()
+  Line 355) typeExpr.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 357) typeExpr.getType() ==> com.github.javaparser.ast.expr.TypeExpr.getType()
+  Line 358) JavaParserFactory.getContext(classOrInterfaceType, typeSolver).solveType(classOrInterfaceType.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 358) JavaParserFactory.getContext(classOrInterfaceType, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 358) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 358) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 359) typeDeclarationSymbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 362) ((ReferenceTypeDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration()).getAllMethods().stream().filter(it -> it.getName().equals(methodReferenceExpr.getIdentifier())).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 362) ((ReferenceTypeDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration()).getAllMethods().stream().filter(it -> it.getName().equals(methodReferenceExpr.getIdentifier())) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 362) ((ReferenceTypeDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration()).getAllMethods().stream() ==> java.util.Collection.stream()
+  Line 362) ((ReferenceTypeDeclaration) typeDeclarationSymbolReference.getCorrespondingDeclaration()).getAllMethods() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllMethods()
+  Line 362) typeDeclarationSymbolReference.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 362) it.getName().equals(methodReferenceExpr.getIdentifier()) ==> java.lang.String.equals(java.lang.Object)
+  Line 362) it.getName() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getName()
+  Line 362) methodReferenceExpr.getIdentifier() ==> com.github.javaparser.ast.expr.MethodReferenceExpr.getIdentifier()
+  Line 362) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 363) methodUsages.size() ==> java.util.List.size()
+  Line 367) methodUsages.get(0) ==> java.util.List.get(int)
+  Line 374) getTypeConcrete(left, solveLambdas) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeConcrete(com.github.javaparser.ast.Node, boolean)
+  Line 375) getTypeConcrete(right, solveLambdas) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeConcrete(com.github.javaparser.ast.Node, boolean)
+  Line 376) rightType.isAssignableBy(leftType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 391) node.accept(typeExtractor, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 399) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 402) findContainingTypeDecl(getParentNode(node)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.findContainingTypeDecl(com.github.javaparser.ast.Node)
+  Line 402) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 407) JavaParserFacade.get(typeSolver).convertToUsage(var.getType(), var) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 407) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 407) var.getType() ==> com.github.javaparser.ast.body.VariableDeclarator.getType()
+  Line 415) convertToUsage(type, JavaParserFactory.getContext(context, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 415) JavaParserFactory.getContext(context, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 419) convertToUsage(type, type) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 424) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 424) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 425) classOrInterfaceType.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 425) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 426) qName(classOrInterfaceType.getScope().get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.qName(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 426) classOrInterfaceType.getScope().get() ==> java.util.Optional.get()
+  Line 426) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 435) qName(classOrInterfaceType) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.qName(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 436) context.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 437) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 440) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 441) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 442) classOrInterfaceType.getTypeArguments().isPresent() ==> java.util.Optional.isPresent()
+  Line 442) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 443) classOrInterfaceType.getTypeArguments().get().stream().map((pt) -> convertToUsage(pt, context)).collect(Collectors.toList()) ==> ERROR
+  Line 443) classOrInterfaceType.getTypeArguments().get().stream().map((pt) -> convertToUsage(pt, context)) ==> ERROR
+  Line 443) classOrInterfaceType.getTypeArguments().get().stream() ==> java.util.Collection.stream()
+  Line 443) classOrInterfaceType.getTypeArguments().get() ==> java.util.Optional.get()
+  Line 443) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 443) convertToUsage(pt, context) ==> ERROR
+  Line 443) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 445) typeDeclaration.isTypeParameter() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isTypeParameter()
+  Line 450) javaParserTypeVariableDeclaration.asTypeParameter() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration.asTypeParameter()
+  Line 456) PrimitiveType.byName(((com.github.javaparser.ast.type.PrimitiveType) type).getType().name()) ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.byName(java.lang.String)
+  Line 456) ((com.github.javaparser.ast.type.PrimitiveType) type).getType().name() ==> java.lang.Enum.name()
+  Line 456) ((com.github.javaparser.ast.type.PrimitiveType) type).getType() ==> com.github.javaparser.ast.type.PrimitiveType.getType()
+  Line 459) wildcardType.getExtendedTypes().isPresent() ==> java.util.Optional.isPresent()
+  Line 459) wildcardType.getExtendedTypes() ==> com.github.javaparser.ast.type.WildcardType.getExtendedTypes()
+  Line 459) wildcardType.getSuperTypes().isPresent() ==> java.util.Optional.isPresent()
+  Line 459) wildcardType.getSuperTypes() ==> com.github.javaparser.ast.type.WildcardType.getSuperTypes()
+  Line 460) Wildcard.extendsBound(convertToUsage(wildcardType.getExtendedTypes().get(), context)) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 460) convertToUsage(wildcardType.getExtendedTypes().get(), context) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 460) wildcardType.getExtendedTypes().get() ==> java.util.Optional.get()
+  Line 460) wildcardType.getExtendedTypes() ==> com.github.javaparser.ast.type.WildcardType.getExtendedTypes()
+  Line 461) wildcardType.getExtendedTypes().isPresent() ==> java.util.Optional.isPresent()
+  Line 461) wildcardType.getExtendedTypes() ==> com.github.javaparser.ast.type.WildcardType.getExtendedTypes()
+  Line 461) wildcardType.getSuperTypes().isPresent() ==> java.util.Optional.isPresent()
+  Line 461) wildcardType.getSuperTypes() ==> com.github.javaparser.ast.type.WildcardType.getSuperTypes()
+  Line 462) Wildcard.superBound(convertToUsage(wildcardType.getSuperTypes().get(), context)) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 462) convertToUsage(wildcardType.getSuperTypes().get(), context) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 462) wildcardType.getSuperTypes().get() ==> java.util.Optional.get()
+  Line 462) wildcardType.getSuperTypes() ==> com.github.javaparser.ast.type.WildcardType.getSuperTypes()
+  Line 463) wildcardType.getExtendedTypes().isPresent() ==> java.util.Optional.isPresent()
+  Line 463) wildcardType.getExtendedTypes() ==> com.github.javaparser.ast.type.WildcardType.getExtendedTypes()
+  Line 463) wildcardType.getSuperTypes().isPresent() ==> java.util.Optional.isPresent()
+  Line 463) wildcardType.getSuperTypes() ==> com.github.javaparser.ast.type.WildcardType.getSuperTypes()
+  Line 466) wildcardType.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 472) convertToUsage(jpArrayType.getComponentType(), context) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 472) jpArrayType.getComponentType() ==> com.github.javaparser.ast.type.ArrayType.getComponentType()
+  Line 474) type.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 474) type.getClass() ==> java.lang.Object.getClass()
+  Line 480) convert(type, JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 480) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 484) convertToUsage(type, context) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 489) call.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 490) call.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 493) params.add(getType(param, false)) ==> java.util.List.add(E)
+  Line 493) getType(param, false) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node, boolean)
+  Line 495) String.format("Error calculating the type of parameter %s of method call %s", param, call) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 500) JavaParserFactory.getContext(call, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 501) context.solveMethodAsUsage(call.getName().getId(), params, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 501) call.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 501) call.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 502) methodUsage.isPresent() ==> java.util.Optional.isPresent()
+  Line 503) call.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 504) call.getRange().get() ==> java.util.Optional.get()
+  Line 504) call.getRange() ==> com.github.javaparser.ast.Node.getRange()
+  Line 506) methodUsage.get() ==> java.util.Optional.get()
+  Line 510) JavaParserFactory.toTypeDeclaration(classOrInterfaceDeclaration, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.toTypeDeclaration(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 519) getTypeDeclaration((ClassOrInterfaceDeclaration) node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 524) getTypeOfThisIn(getParentNode(node)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeOfThisIn(com.github.javaparser.ast.Node)
+  Line 524) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 529) JavaParserFactory.toTypeDeclaration(typeDeclaration, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.toTypeDeclaration(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_JavaParserFactory.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_JavaParserFactory.txt
new file mode 100644
index 0000000..42d2421
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_JavaParserFactory.txt
@@ -0,0 +1,26 @@
+  Line 79) ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent() ==> java.util.Optional.isPresent()
+  Line 79) ((ObjectCreationExpr) node).getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 84) node.getParentNode().isPresent() ==> java.util.Optional.isPresent()
+  Line 84) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 84) node.getParentNode().get() ==> java.util.Optional.get()
+  Line 84) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 84) node.getParentNode().get().getParentNode().isPresent() ==> java.util.Optional.isPresent()
+  Line 84) node.getParentNode().get().getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 84) node.getParentNode().get() ==> java.util.Optional.get()
+  Line 84) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 85) getContext(node.getParentNode().get().getParentNode().get(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 85) node.getParentNode().get().getParentNode().get() ==> java.util.Optional.get()
+  Line 85) node.getParentNode().get().getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 85) node.getParentNode().get() ==> java.util.Optional.get()
+  Line 85) node.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 88) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 89) ((ObjectCreationExpr) parentNode).getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 90) getContext(getParentNode(parentNode), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 90) getParentNode(parentNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 92) getContext(parentNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 103) expressionStmt.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 104) expressionStmt.getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 112) foreachStmt.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 120) ((ClassOrInterfaceDeclaration) node).isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 132) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 132) node.getClass() ==> java.lang.Object.getClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_LambdaArgumentTypePlaceholder.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_LambdaArgumentTypePlaceholder.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_LambdaArgumentTypePlaceholder.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_TypeExtractor.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_TypeExtractor.txt
new file mode 100644
index 0000000..9291a06
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_TypeExtractor.txt
@@ -0,0 +1,279 @@
+  Line 41) Logger.getLogger(TypeExtractor.class.getCanonicalName()) ==> java.util.logging.Logger.getLogger(java.lang.String)
+  Line 41) TypeExtractor.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 44) logger.setLevel(Level.INFO) ==> java.util.logging.Logger.setLevel(java.util.logging.Level)
+  Line 46) consoleHandler.setLevel(Level.INFO) ==> java.util.logging.Handler.setLevel(java.util.logging.Level)
+  Line 47) logger.addHandler(consoleHandler) ==> java.util.logging.Logger.addHandler(java.util.logging.Handler)
+  Line 60) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 62) facade.convertToUsageVariableType(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsageVariableType(com.github.javaparser.ast.body.VariableDeclarator)
+  Line 63) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 65) facade.convertToUsageVariableType(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsageVariableType(com.github.javaparser.ast.body.VariableDeclarator)
+  Line 67) getParentNode(node).getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 67) getParentNode(node).getClass() ==> java.lang.Object.getClass()
+  Line 67) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 73) node.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 76) facade.convertToUsage(node.getType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 76) node.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 82) node.getName().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 82) node.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 83) arrayUsageType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 84) ((ArrayType) arrayUsageType).getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 91) facade.convertToUsage(node.getElementType(), JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 91) node.getElementType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getElementType()
+  Line 91) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 92) node.getLevels().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 92) node.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 100) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 100) node.getClass() ==> java.lang.Object.getClass()
+  Line 105) node.getTarget().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 105) node.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 110) node.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 115) facade.getBinaryTypeConcrete(node.getLeft(), node.getRight(), solveLambdas) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getBinaryTypeConcrete(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node, boolean)
+  Line 115) node.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 115) node.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 132) node.getLeft().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 132) node.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 134) node.getOperator().name() ==> java.lang.Enum.name()
+  Line 134) node.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 140) facade.convertToUsage(node.getType(), JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 140) node.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 140) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 146) node.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 147) facade.convertToUsage(astType, node.getType()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 147) node.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 148) ImmutableList.of(jssType) ==> com.google.common.collect.ImmutableList.of(E)
+  Line 153) node.getThenExpr().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 153) node.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 158) node.getInner().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 158) node.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 168) parentType.hasField(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasField(java.lang.String)
+  Line 168) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 168) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 169) parentType.getField(node.getName().getId()).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 169) parentType.getField(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getField(java.lang.String)
+  Line 169) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 169) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 170) parentType.hasInternalType(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.hasInternalType(java.lang.String)
+  Line 170) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 170) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 171) parentType.getInternalType(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getInternalType(java.lang.String)
+  Line 171) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 171) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 173) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 173) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 180) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 181) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 182) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 183) JavaParserFactory.getContext(node, typeSolver).solveType(staticValue.toString(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 183) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 183) staticValue.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 184) typeAccessedStatically.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 186) solveDotExpressionType(typeAccessedStatically.getCorrespondingDeclaration().asReferenceType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.solveDotExpressionType(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.ast.expr.FieldAccessExpr)
+  Line 187) typeAccessedStatically.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 187) typeAccessedStatically.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 189) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 192) facade.solve((ThisExpr) node.getScope()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.ThisExpr)
+  Line 192) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 194) solve.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 195) solve.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 197) solveDotExpressionType(correspondingDeclaration.asReferenceType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.solveDotExpressionType(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.ast.expr.FieldAccessExpr)
+  Line 197) correspondingDeclaration.asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 201) node.getScope().toString().indexOf('.') ==> java.lang.String.indexOf(int)
+  Line 201) node.getScope().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 201) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 203) typeSolver.tryToSolveType(node.getScope().toString()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 203) node.getScope().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 203) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 204) sr.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 205) solveDotExpressionType(sr.getCorrespondingDeclaration(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.solveDotExpressionType(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.ast.expr.FieldAccessExpr)
+  Line 205) sr.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 210) new SymbolSolver(typeSolver).solveSymbolAsValue(node.getField().getId(), node) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolAsValue(java.lang.String, com.github.javaparser.ast.Node)
+  Line 210) node.getField().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 210) node.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 214) typeSolver.tryToSolveType(node.toString()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 214) node.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 215) sref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 216) sref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 219) value.isPresent() ==> java.util.Optional.isPresent()
+  Line 220) value.get().getType() ==> com.github.javaparser.symbolsolver.model.resolution.Value.getType()
+  Line 220) value.get() ==> java.util.Optional.get()
+  Line 222) node.getField().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 222) node.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 233) new ReflectionTypeSolver().solveType("java.lang.String") ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 253) node.getValue().toLowerCase().endsWith("f") ==> java.lang.String.endsWith(java.lang.String)
+  Line 253) node.getValue().toLowerCase() ==> java.lang.String.toLowerCase()
+  Line 253) node.getValue() ==> com.github.javaparser.ast.expr.LiteralStringValueExpr.getValue()
+  Line 271) logger.finest("getType on method call " + node) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 273) facade.solveMethodAsUsage(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveMethodAsUsage(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 274) logger.finest("getType on method call " + node + " resolved to " + ref) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 275) logger.finest("getType on method call " + node + " return type is " + ref.returnType()) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 275) ref.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 276) ref.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 282) logger.finest("getType on name expr " + node) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 283) new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolAsValue(java.lang.String, com.github.javaparser.ast.Node)
+  Line 283) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 283) node.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 284) value.isPresent() ==> java.util.Optional.isPresent()
+  Line 285) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 285) node.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 287) value.get().getType() ==> com.github.javaparser.symbolsolver.model.resolution.Value.getType()
+  Line 287) value.get() ==> java.util.Optional.get()
+  Line 293) facade.convertToUsage(node.getType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 293) node.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 300) node.getClassExpr().isPresent() ==> java.util.Optional.isPresent()
+  Line 300) node.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 302) node.getClassExpr().get().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 302) node.getClassExpr().get() ==> java.util.Optional.get()
+  Line 302) node.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 304) typeSolver.tryToSolveType(className) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 305) clazz.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 306) clazz.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 309) node.getAncestorOfType(CompilationUnit.class) ==> com.github.javaparser.HasParentNode.getAncestorOfType(java.lang.Class<N>)
+  Line 310) cu.isPresent() ==> java.util.Optional.isPresent()
+  Line 311) cu.get().getClassByName(className) ==> com.github.javaparser.ast.CompilationUnit.getClassByName(java.lang.String)
+  Line 311) cu.get() ==> java.util.Optional.get()
+  Line 312) classByName.isPresent() ==> java.util.Optional.isPresent()
+  Line 313) facade.getTypeDeclaration(classByName.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 313) classByName.get() ==> java.util.Optional.get()
+  Line 318) facade.getTypeDeclaration(facade.findContainingTypeDecl(node)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 318) facade.findContainingTypeDecl(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.findContainingTypeDecl(com.github.javaparser.ast.Node)
+  Line 323) facade.getTypeDeclaration(facade.findContainingTypeDecl(node)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 323) facade.findContainingTypeDecl(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.findContainingTypeDecl(com.github.javaparser.ast.Node)
+  Line 325) ((ClassDeclaration) typeOfNode).getSuperClass() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getSuperClass()
+  Line 327) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 327) node.getClass() ==> java.lang.Object.getClass()
+  Line 333) node.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 336) node.getExpression().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 336) node.getExpression() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpression()
+  Line 343) node.getExpression().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 343) node.getExpression() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpression()
+  Line 345) node.getOperator().name() ==> java.lang.Enum.name()
+  Line 345) node.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 351) node.getVariables().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 351) node.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 354) facade.convertToUsageVariableType(node.getVariables().get(0)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsageVariableType(com.github.javaparser.ast.body.VariableDeclarator)
+  Line 354) node.getVariables().get(0) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 354) node.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 360) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 361) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 362) JavaParserSymbolDeclaration.getParamPos(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.getParamPos(com.github.javaparser.ast.Node)
+  Line 363) facade.solve(callExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 364) refMethod.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 365) getParentNode(node).toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 365) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 365) callExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 365) callExpr.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 367) logger.finest("getType on lambda expr " + refMethod.getCorrespondingDeclaration().getName()) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 367) refMethod.getCorrespondingDeclaration().getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 367) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 371) refMethod.getCorrespondingDeclaration().getParam(pos).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 371) refMethod.getCorrespondingDeclaration().getParam(pos) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 371) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 373) callExpr.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 373) callExpr.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 374) callExpr.getScope().get() ==> java.util.Optional.get()
+  Line 374) callExpr.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 381) JavaParserFactory.getContext(nameExpr, typeSolver).solveType(nameExpr.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 381) JavaParserFactory.getContext(nameExpr, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 381) nameExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 381) nameExpr.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 382) type.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 391) facade.getType(scope) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 392) scopeType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 393) scopeType.asReferenceType().useThisTypeParametersOnTheGivenType(result) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 393) scopeType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 399) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 400) facade.solveGenericTypes(result, ctx, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.core.resolution.Context, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 405) FunctionalInterfaceLogic.getFunctionalMethod(result) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 406) functionalMethod.isPresent() ==> java.util.Optional.isPresent()
+  Line 415) ReferenceTypeImpl.undeterminedParameters(functionalMethod.get().getDeclaration().declaringType(), typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl.undeterminedParameters(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 415) functionalMethod.get().getDeclaration().declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 415) functionalMethod.get().getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 415) functionalMethod.get() ==> java.util.Optional.get()
+  Line 417) lambdaCtx.addPair(result, functionalInterfaceType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 421) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 422) facade.getType(((ExpressionStmt) lambdaExpr.getBody()).getExpression()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 422) ((ExpressionStmt) lambdaExpr.getBody()).getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 422) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 423) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 424) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 425) blockStmt.getStatements() ==> com.github.javaparser.ast.stmt.BlockStmt.getStatements()
+  Line 428) blockStmt.getNodesByType(ReturnStmt.class) ==> com.github.javaparser.ast.Node.getNodesByType(java.lang.Class<N>)
+  Line 430) returnStmts.size() ==> java.util.List.size()
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}).filter(x -> x != null && !x.isVoid() && !x.isNull()).findFirst().orElse(VoidType.INSTANCE) ==> java.util.Optional.orElse(T)
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}).filter(x -> x != null && !x.isVoid() && !x.isNull()).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}).filter(x -> x != null && !x.isVoid() && !x.isNull()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 432) returnStmts.stream() ==> java.util.Collection.stream()
+  Line 434) returnStmt.getExpression() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpression()
+  Line 435) expression.isPresent() ==> java.util.Optional.isPresent()
+  Line 436) facade.getType(expression.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 436) expression.get() ==> java.util.Optional.get()
+  Line 441) x.isVoid() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isVoid()
+  Line 441) x.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 454) functionalMethod.get().returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 454) functionalMethod.get() ==> java.util.Optional.get()
+  Line 457) funcInterfaceCtx.addPair(formalType, actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 459) funcInterfaceCtx.resolve(funcInterfaceCtx.addSingle(functionalInterfaceType)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 459) funcInterfaceCtx.addSingle(functionalInterfaceType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 464) lambdaCtx.addPair(result, functionalTypeWithReturn) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 465) lambdaCtx.resolve(lambdaCtx.addSingle(result)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 465) lambdaCtx.addSingle(result) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 471) refMethod.getCorrespondingDeclaration().getParam(pos).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 471) refMethod.getCorrespondingDeclaration().getParam(pos) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 471) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 480) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 481) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 482) JavaParserSymbolDeclaration.getParamPos(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.getParamPos(com.github.javaparser.ast.Node)
+  Line 483) facade.solve(callExpr, false) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.MethodCallExpr, boolean)
+  Line 484) refMethod.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 485) getParentNode(node).toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 485) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 485) callExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 485) callExpr.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 487) logger.finest("getType on method reference expr " + refMethod.getCorrespondingDeclaration().getName()) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 487) refMethod.getCorrespondingDeclaration().getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 487) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 490) facade.solveMethodAsUsage(callExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveMethodAsUsage(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 491) usage.getParamType(pos) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 493) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 494) facade.solveGenericTypes(result, ctx, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.core.resolution.Context, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 499) FunctionalInterfaceLogic.getFunctionalMethod(result) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 500) functionalMethod.isPresent() ==> java.util.Optional.isPresent()
+  Line 504) facade.toMethodUsage(methodReferenceExpr).returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 504) facade.toMethodUsage(methodReferenceExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.toMethodUsage(com.github.javaparser.ast.expr.MethodReferenceExpr)
+  Line 505) functionalMethod.get().returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 505) functionalMethod.get() ==> java.util.Optional.get()
+  Line 508) inferenceContext.addPair(formalType, actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 509) inferenceContext.resolve(inferenceContext.addSingle(result)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 509) inferenceContext.addSingle(result) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 515) refMethod.getCorrespondingDeclaration().getParam(pos).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 515) refMethod.getCorrespondingDeclaration().getParam(pos) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 515) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_TypeExtractor_J9.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_TypeExtractor_J9.txt
new file mode 100644
index 0000000..28c113f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_TypeExtractor_J9.txt
@@ -0,0 +1,279 @@
+  Line 41) Logger.getLogger(TypeExtractor.class.getCanonicalName()) ==> java.util.logging.Logger.getLogger(java.lang.String)
+  Line 41) TypeExtractor.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 44) logger.setLevel(Level.INFO) ==> java.util.logging.Logger.setLevel(java.util.logging.Level)
+  Line 46) consoleHandler.setLevel(Level.INFO) ==> java.util.logging.Handler.setLevel(java.util.logging.Level)
+  Line 47) logger.addHandler(consoleHandler) ==> java.util.logging.Logger.addHandler(java.util.logging.Handler)
+  Line 60) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 62) facade.convertToUsageVariableType(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsageVariableType(com.github.javaparser.ast.body.VariableDeclarator)
+  Line 63) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 65) facade.convertToUsageVariableType(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsageVariableType(com.github.javaparser.ast.body.VariableDeclarator)
+  Line 67) getParentNode(node).getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 67) getParentNode(node).getClass() ==> java.lang.Object.getClass()
+  Line 67) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 73) node.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 76) facade.convertToUsage(node.getType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 76) node.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 82) node.getName().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 82) node.getName() ==> com.github.javaparser.ast.expr.ArrayAccessExpr.getName()
+  Line 83) arrayUsageType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 84) ((ArrayType) arrayUsageType).getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 91) facade.convertToUsage(node.getElementType(), JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 91) node.getElementType() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getElementType()
+  Line 91) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 92) node.getLevels().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 92) node.getLevels() ==> com.github.javaparser.ast.expr.ArrayCreationExpr.getLevels()
+  Line 100) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 100) node.getClass() ==> java.lang.Object.getClass()
+  Line 105) node.getTarget().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 105) node.getTarget() ==> com.github.javaparser.ast.expr.AssignExpr.getTarget()
+  Line 110) node.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 115) facade.getBinaryTypeConcrete(node.getLeft(), node.getRight(), solveLambdas) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getBinaryTypeConcrete(com.github.javaparser.ast.Node, com.github.javaparser.ast.Node, boolean)
+  Line 115) node.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 115) node.getRight() ==> com.github.javaparser.ast.expr.BinaryExpr.getRight()
+  Line 132) node.getLeft().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 132) node.getLeft() ==> com.github.javaparser.ast.expr.BinaryExpr.getLeft()
+  Line 134) node.getOperator().name() ==> java.lang.Enum.name()
+  Line 134) node.getOperator() ==> com.github.javaparser.ast.expr.BinaryExpr.getOperator()
+  Line 140) facade.convertToUsage(node.getType(), JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 140) node.getType() ==> com.github.javaparser.ast.expr.CastExpr.getType()
+  Line 140) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 146) node.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 147) facade.convertToUsage(astType, node.getType()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 147) node.getType() ==> com.github.javaparser.ast.expr.ClassExpr.getType()
+  Line 148) ImmutableList.of(jssType) ==> java.util.List.of(E...)
+  Line 153) node.getThenExpr().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 153) node.getThenExpr() ==> com.github.javaparser.ast.expr.ConditionalExpr.getThenExpr()
+  Line 158) node.getInner().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 158) node.getInner() ==> com.github.javaparser.ast.expr.EnclosedExpr.getInner()
+  Line 168) parentType.hasField(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasField(java.lang.String)
+  Line 168) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 168) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 169) parentType.getField(node.getName().getId()).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 169) parentType.getField(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getField(java.lang.String)
+  Line 169) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 169) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 170) parentType.hasInternalType(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.hasInternalType(java.lang.String)
+  Line 170) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 170) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 171) parentType.getInternalType(node.getName().getId()) ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getInternalType(java.lang.String)
+  Line 171) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 171) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 173) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 173) node.getName() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getName()
+  Line 180) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 181) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 182) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 183) JavaParserFactory.getContext(node, typeSolver).solveType(staticValue.toString(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 183) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 183) staticValue.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 184) typeAccessedStatically.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 186) solveDotExpressionType(typeAccessedStatically.getCorrespondingDeclaration().asReferenceType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.solveDotExpressionType(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.ast.expr.FieldAccessExpr)
+  Line 187) typeAccessedStatically.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 187) typeAccessedStatically.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 189) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 192) facade.solve((ThisExpr) node.getScope()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.ThisExpr)
+  Line 192) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 194) solve.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 195) solve.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 197) solveDotExpressionType(correspondingDeclaration.asReferenceType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.solveDotExpressionType(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.ast.expr.FieldAccessExpr)
+  Line 197) correspondingDeclaration.asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 201) node.getScope().toString().indexOf('.') ==> java.lang.String.indexOf(int)
+  Line 201) node.getScope().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 201) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 203) typeSolver.tryToSolveType(node.getScope().toString()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 203) node.getScope().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 203) node.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 204) sr.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 205) solveDotExpressionType(sr.getCorrespondingDeclaration(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.solveDotExpressionType(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.ast.expr.FieldAccessExpr)
+  Line 205) sr.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 210) new SymbolSolver(typeSolver).solveSymbolAsValue(node.getField().getId(), node) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolAsValue(java.lang.String, com.github.javaparser.ast.Node)
+  Line 210) node.getField().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 210) node.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 214) typeSolver.tryToSolveType(node.toString()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 214) node.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 215) sref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 216) sref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 219) value.isPresent() ==> java.util.Optional.isPresent()
+  Line 220) value.get().getType() ==> com.github.javaparser.symbolsolver.model.resolution.Value.getType()
+  Line 220) value.get() ==> java.util.Optional.get()
+  Line 222) node.getField().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 222) node.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 233) new ReflectionTypeSolver().solveType("java.lang.String") ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 253) node.getValue().toLowerCase().endsWith("f") ==> java.lang.String.endsWith(java.lang.String)
+  Line 253) node.getValue().toLowerCase() ==> java.lang.String.toLowerCase()
+  Line 253) node.getValue() ==> com.github.javaparser.ast.expr.LiteralStringValueExpr.getValue()
+  Line 271) logger.finest("getType on method call " + node) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 273) facade.solveMethodAsUsage(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveMethodAsUsage(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 274) logger.finest("getType on method call " + node + " resolved to " + ref) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 275) logger.finest("getType on method call " + node + " return type is " + ref.returnType()) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 275) ref.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 276) ref.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 282) logger.finest("getType on name expr " + node) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 283) new SymbolSolver(typeSolver).solveSymbolAsValue(node.getName().getId(), node) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolAsValue(java.lang.String, com.github.javaparser.ast.Node)
+  Line 283) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 283) node.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 284) value.isPresent() ==> java.util.Optional.isPresent()
+  Line 285) node.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 285) node.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 287) value.get().getType() ==> com.github.javaparser.symbolsolver.model.resolution.Value.getType()
+  Line 287) value.get() ==> java.util.Optional.get()
+  Line 293) facade.convertToUsage(node.getType(), node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 293) node.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 300) node.getClassExpr().isPresent() ==> java.util.Optional.isPresent()
+  Line 300) node.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 302) node.getClassExpr().get().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 302) node.getClassExpr().get() ==> java.util.Optional.get()
+  Line 302) node.getClassExpr() ==> com.github.javaparser.ast.expr.ThisExpr.getClassExpr()
+  Line 304) typeSolver.tryToSolveType(className) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 305) clazz.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 306) clazz.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 309) node.getAncestorOfType(CompilationUnit.class) ==> com.github.javaparser.HasParentNode.getAncestorOfType(java.lang.Class<N>)
+  Line 310) cu.isPresent() ==> java.util.Optional.isPresent()
+  Line 311) cu.get().getClassByName(className) ==> com.github.javaparser.ast.CompilationUnit.getClassByName(java.lang.String)
+  Line 311) cu.get() ==> java.util.Optional.get()
+  Line 312) classByName.isPresent() ==> java.util.Optional.isPresent()
+  Line 313) facade.getTypeDeclaration(classByName.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 313) classByName.get() ==> java.util.Optional.get()
+  Line 318) facade.getTypeDeclaration(facade.findContainingTypeDecl(node)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 318) facade.findContainingTypeDecl(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.findContainingTypeDecl(com.github.javaparser.ast.Node)
+  Line 323) facade.getTypeDeclaration(facade.findContainingTypeDecl(node)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 323) facade.findContainingTypeDecl(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.findContainingTypeDecl(com.github.javaparser.ast.Node)
+  Line 325) ((ClassDeclaration) typeOfNode).getSuperClass() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getSuperClass()
+  Line 327) node.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 327) node.getClass() ==> java.lang.Object.getClass()
+  Line 333) node.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 336) node.getExpression().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 336) node.getExpression() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpression()
+  Line 343) node.getExpression().accept(this, solveLambdas) ==> com.github.javaparser.ast.visitor.Visitable.accept(com.github.javaparser.ast.visitor.GenericVisitor<R, A>, A)
+  Line 343) node.getExpression() ==> com.github.javaparser.ast.expr.UnaryExpr.getExpression()
+  Line 345) node.getOperator().name() ==> java.lang.Enum.name()
+  Line 345) node.getOperator() ==> com.github.javaparser.ast.expr.UnaryExpr.getOperator()
+  Line 351) node.getVariables().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 351) node.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 354) facade.convertToUsageVariableType(node.getVariables().get(0)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsageVariableType(com.github.javaparser.ast.body.VariableDeclarator)
+  Line 354) node.getVariables().get(0) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 354) node.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 360) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 361) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 362) JavaParserSymbolDeclaration.getParamPos(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.getParamPos(com.github.javaparser.ast.Node)
+  Line 363) facade.solve(callExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 364) refMethod.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 365) getParentNode(node).toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 365) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 365) callExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 365) callExpr.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 367) logger.finest("getType on lambda expr " + refMethod.getCorrespondingDeclaration().getName()) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 367) refMethod.getCorrespondingDeclaration().getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 367) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 371) refMethod.getCorrespondingDeclaration().getParam(pos).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 371) refMethod.getCorrespondingDeclaration().getParam(pos) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 371) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 373) callExpr.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 373) callExpr.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 374) callExpr.getScope().get() ==> java.util.Optional.get()
+  Line 374) callExpr.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 381) JavaParserFactory.getContext(nameExpr, typeSolver).solveType(nameExpr.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 381) JavaParserFactory.getContext(nameExpr, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 381) nameExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 381) nameExpr.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 382) type.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 391) facade.getType(scope) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 392) scopeType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 393) scopeType.asReferenceType().useThisTypeParametersOnTheGivenType(result) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 393) scopeType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 399) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 400) facade.solveGenericTypes(result, ctx, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.core.resolution.Context, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 405) FunctionalInterfaceLogic.getFunctionalMethod(result) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 406) functionalMethod.isPresent() ==> java.util.Optional.isPresent()
+  Line 415) ReferenceTypeImpl.undeterminedParameters(functionalMethod.get().getDeclaration().declaringType(), typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl.undeterminedParameters(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 415) functionalMethod.get().getDeclaration().declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 415) functionalMethod.get().getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 415) functionalMethod.get() ==> java.util.Optional.get()
+  Line 417) lambdaCtx.addPair(result, functionalInterfaceType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 421) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 422) facade.getType(((ExpressionStmt) lambdaExpr.getBody()).getExpression()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 422) ((ExpressionStmt) lambdaExpr.getBody()).getExpression() ==> com.github.javaparser.ast.stmt.ExpressionStmt.getExpression()
+  Line 422) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 423) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 424) lambdaExpr.getBody() ==> com.github.javaparser.ast.expr.LambdaExpr.getBody()
+  Line 425) blockStmt.getStatements() ==> com.github.javaparser.ast.stmt.BlockStmt.getStatements()
+  Line 428) blockStmt.getNodesByType(ReturnStmt.class) ==> com.github.javaparser.ast.Node.getNodesByType(java.lang.Class<N>)
+  Line 430) returnStmts.size() ==> java.util.List.size()
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}).filter(x -> x != null && !x.isVoid() && !x.isNull()).findFirst().orElse(VoidType.INSTANCE) ==> java.util.Optional.orElse(T)
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}).filter(x -> x != null && !x.isVoid() && !x.isNull()).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}).filter(x -> x != null && !x.isVoid() && !x.isNull()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 432) returnStmts.stream().map(returnStmt -> {
+    Optional<Expression> expression = returnStmt.getExpression();
+    if (expression.isPresent()) {
+        return facade.getType(expression.get());
+    } else {
+        return VoidType.INSTANCE;
+    }
+}) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 432) returnStmts.stream() ==> java.util.Collection.stream()
+  Line 434) returnStmt.getExpression() ==> com.github.javaparser.ast.stmt.ReturnStmt.getExpression()
+  Line 435) expression.isPresent() ==> java.util.Optional.isPresent()
+  Line 436) facade.getType(expression.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 436) expression.get() ==> java.util.Optional.get()
+  Line 441) x.isVoid() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isVoid()
+  Line 441) x.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 454) functionalMethod.get().returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 454) functionalMethod.get() ==> java.util.Optional.get()
+  Line 457) funcInterfaceCtx.addPair(formalType, actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 459) funcInterfaceCtx.resolve(funcInterfaceCtx.addSingle(functionalInterfaceType)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 459) funcInterfaceCtx.addSingle(functionalInterfaceType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 464) lambdaCtx.addPair(result, functionalTypeWithReturn) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 465) lambdaCtx.resolve(lambdaCtx.addSingle(result)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 465) lambdaCtx.addSingle(result) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 471) refMethod.getCorrespondingDeclaration().getParam(pos).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 471) refMethod.getCorrespondingDeclaration().getParam(pos) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 471) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 480) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 481) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 482) JavaParserSymbolDeclaration.getParamPos(node) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.getParamPos(com.github.javaparser.ast.Node)
+  Line 483) facade.solve(callExpr, false) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(com.github.javaparser.ast.expr.MethodCallExpr, boolean)
+  Line 484) refMethod.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 485) getParentNode(node).toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 485) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 485) callExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 485) callExpr.getName() ==> com.github.javaparser.ast.expr.MethodCallExpr.getName()
+  Line 487) logger.finest("getType on method reference expr " + refMethod.getCorrespondingDeclaration().getName()) ==> java.util.logging.Logger.finest(java.lang.String)
+  Line 487) refMethod.getCorrespondingDeclaration().getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 487) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 490) facade.solveMethodAsUsage(callExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveMethodAsUsage(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 491) usage.getParamType(pos) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 493) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 494) facade.solveGenericTypes(result, ctx, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveGenericTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.core.resolution.Context, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 499) FunctionalInterfaceLogic.getFunctionalMethod(result) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 500) functionalMethod.isPresent() ==> java.util.Optional.isPresent()
+  Line 504) facade.toMethodUsage(methodReferenceExpr).returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 504) facade.toMethodUsage(methodReferenceExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.toMethodUsage(com.github.javaparser.ast.expr.MethodReferenceExpr)
+  Line 505) functionalMethod.get().returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 505) functionalMethod.get() ==> java.util.Optional.get()
+  Line 508) inferenceContext.addPair(formalType, actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 509) inferenceContext.resolve(inferenceContext.addSingle(result)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 509) inferenceContext.addSingle(result) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 515) refMethod.getCorrespondingDeclaration().getParam(pos).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 515) refMethod.getCorrespondingDeclaration().getParam(pos) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 515) refMethod.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_UnsolvedSymbolException.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_UnsolvedSymbolException.txt
new file mode 100644
index 0000000..eb5ab90
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_UnsolvedSymbolException.txt
@@ -0,0 +1 @@
+  Line 43) context.toString() ==> java.lang.Object.toString()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AbstractJavaParserContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AbstractJavaParserContext.txt
new file mode 100644
index 0000000..091a96d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AbstractJavaParserContext.txt
@@ -0,0 +1,30 @@
+  Line 49) symbolDeclarator.getSymbolDeclarations() ==> com.github.javaparser.symbolsolver.resolution.SymbolDeclarator.getSymbolDeclarations()
+  Line 50) decl.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 50) decl.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 51) SymbolReference.solved(decl) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 54) SymbolReference.unsolved(ValueDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 76) getClass() ==> java.lang.Object.getClass()
+  Line 76) o.getClass() ==> java.lang.Object.getClass()
+  Line 80) wrappedNode.equals(that.wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 87) wrappedNode.hashCode() ==> com.github.javaparser.ast.Node.hashCode()
+  Line 92) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 94) Optional.empty() ==> java.util.Optional.empty()
+  Line 96) parent.solveGenericType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveGenericType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 102) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 103) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 105) parentCall.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 106) parentCall.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 113) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 115) getParentNode(notMethod) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 117) JavaParserFactory.getContext(notMethod, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 120) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 122) getParentNode(notMethod) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 124) JavaParserFactory.getContext(notMethod, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 132) symbolDeclarator.getSymbolDeclarations().stream().filter(d -> d.getName().equals(name)).map(d -> Value.from(d)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 132) symbolDeclarator.getSymbolDeclarations().stream().filter(d -> d.getName().equals(name)).map(d -> Value.from(d)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 132) symbolDeclarator.getSymbolDeclarations().stream().filter(d -> d.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 132) symbolDeclarator.getSymbolDeclarations().stream() ==> java.util.Collection.stream()
+  Line 132) symbolDeclarator.getSymbolDeclarations() ==> com.github.javaparser.symbolsolver.resolution.SymbolDeclarator.getSymbolDeclarations()
+  Line 133) d.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 133) d.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 134) Value.from(d) ==> com.github.javaparser.symbolsolver.model.resolution.Value.from(com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AbstractMethodLikeDeclarationContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AbstractMethodLikeDeclarationContext.txt
new file mode 100644
index 0000000..51d21ec
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AbstractMethodLikeDeclarationContext.txt
@@ -0,0 +1,44 @@
+  Line 34) wrappedNode.getParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameters()
+  Line 35) JavaParserFactory.getSymbolDeclarator(parameter, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 36) AbstractJavaParserContext.solveWith(sb, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 37) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 43) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 43) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 48) wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.getTypeParameters()
+  Line 49) tp.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 49) tp.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 49) tp.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 50) Optional.of(new TypeVariable(new JavaParserTypeParameter(tp, typeSolver))) ==> java.util.Optional.of(T)
+  Line 53) super.solveGenericType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveGenericType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 58) wrappedNode.getParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameters()
+  Line 59) JavaParserFactory.getSymbolDeclarator(parameter, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 60) solveWithAsValue(sb, name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWithAsValue(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 61) symbolReference.isPresent() ==> java.util.Optional.isPresent()
+  Line 68) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 68) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 73) wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.getTypeParameters()
+  Line 74) wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.getTypeParameters()
+  Line 75) tp.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 75) tp.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 75) tp.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 76) SymbolReference.solved(new JavaParserTypeParameter(tp, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 82) wrappedNode.getChildNodesByType(com.github.javaparser.ast.body.TypeDeclaration.class) ==> com.github.javaparser.ast.Node.getChildNodesByType(java.lang.Class<N>)
+  Line 85) localType.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 85) localType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 85) localType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 86) SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(localType)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 86) JavaParserFacade.get(typeSolver).getTypeDeclaration(localType) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 86) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 87) name.startsWith(String.format("%s.", localType.getName())) ==> java.lang.String.startsWith(java.lang.String)
+  Line 87) String.format("%s.", localType.getName()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 87) localType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 88) JavaParserFactory.getContext(localType, typeSolver).solveType(name.substring(localType.getName().getId().length() + 1), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 88) JavaParserFactory.getContext(localType, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 89) name.substring(localType.getName().getId().length() + 1) ==> java.lang.String.substring(int)
+  Line 89) localType.getName().getId().length() ==> java.lang.String.length()
+  Line 89) localType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 89) localType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 93) getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 93) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 99) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 99) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AnonymousClassDeclarationContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AnonymousClassDeclarationContext.txt
new file mode 100644
index 0000000..b556156
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_AnonymousClassDeclarationContext.txt
@@ -0,0 +1,96 @@
+  Line 37) Preconditions.checkArgument(node.getAnonymousClassBody().isPresent(), "An anonymous class must have a body") ==> com.google.common.base.Preconditions.checkArgument(boolean, java.lang.Object)
+  Line 37) node.getAnonymousClassBody().isPresent() ==> java.util.Optional.isPresent()
+  Line 37) node.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 47) myDeclaration.getDeclaredMethods().stream().filter(m -> m.getName().equals(name) && (!staticOnly || m.isStatic())).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 47) myDeclaration.getDeclaredMethods().stream().filter(m -> m.getName().equals(name) && (!staticOnly || m.isStatic())) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 47) myDeclaration.getDeclaredMethods().stream() ==> java.util.Collection.stream()
+  Line 47) myDeclaration.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getDeclaredMethods()
+  Line 50) m.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 50) m.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 50) m.isStatic() ==> com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration.isStatic()
+  Line 51) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 53) Object.class.getCanonicalName().equals(myDeclaration.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 53) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 53) myDeclaration.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getQualifiedName()
+  Line 54) myDeclaration.getAncestors() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getAncestors()
+  Line 56) MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 56) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 64) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 65) candidateMethods.add(res.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 65) res.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 72) candidateMethods.isEmpty() ==> java.util.List.isEmpty()
+  Line 74) getParent().solveMethod(name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 74) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 75) parentSolution.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 76) candidateMethods.add(parentSolution.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 76) parentSolution.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 81) candidateMethods.isEmpty() ==> java.util.List.isEmpty()
+  Line 81) myDeclaration.getSuperTypeDeclaration().isInterface() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isInterface()
+  Line 81) myDeclaration.getSuperTypeDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getSuperTypeDeclaration()
+  Line 83) MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class, typeSolver), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 89) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 90) candidateMethods.add(res.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 90) res.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 94) MethodResolutionLogic.findMostApplicable(candidateMethods, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 103) myDeclaration.findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.findMembersOfKind(java.lang.Class<T>)
+  Line 107) typeDeclarations.stream().filter(internalType -> internalType.getName().getId().equals(name)).findFirst().map(internalType -> SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType))) ==> java.util.Optional.map(java.util.function.Function<? super T, ? extends U>)
+  Line 107) typeDeclarations.stream().filter(internalType -> internalType.getName().getId().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 107) typeDeclarations.stream().filter(internalType -> internalType.getName().getId().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 107) typeDeclarations.stream() ==> java.util.Collection.stream()
+  Line 109) internalType.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 109) internalType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 109) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 112) SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 113) JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 113) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 115) exactMatch.isPresent() ==> java.util.Optional.isPresent()
+  Line 116) exactMatch.get() ==> java.util.Optional.get()
+  Line 120) typeDeclarations.stream().filter(internalType -> name.startsWith(String.format("%s.", internalType.getName()))).findFirst().map(internalType -> JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(internalType.getName().getId().length() + 1), typeSolver)) ==> java.util.Optional.map(java.util.function.Function<? super T, ? extends U>)
+  Line 120) typeDeclarations.stream().filter(internalType -> name.startsWith(String.format("%s.", internalType.getName()))).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 120) typeDeclarations.stream().filter(internalType -> name.startsWith(String.format("%s.", internalType.getName()))) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 120) typeDeclarations.stream() ==> java.util.Collection.stream()
+  Line 122) name.startsWith(String.format("%s.", internalType.getName())) ==> java.lang.String.startsWith(java.lang.String)
+  Line 122) String.format("%s.", internalType.getName()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 122) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 125) JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(internalType.getName().getId().length() + 1), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 125) JavaParserFactory.getContext(internalType, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 127) name.substring(internalType.getName().getId().length() + 1) ==> java.lang.String.substring(int)
+  Line 127) internalType.getName().getId().length() ==> java.lang.String.length()
+  Line 127) internalType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 127) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 130) recursiveMatch.isPresent() ==> java.util.Optional.isPresent()
+  Line 131) recursiveMatch.get() ==> java.util.Optional.get()
+  Line 135) wrappedNode.getTypeArguments().map(nodes -> ((NodeWithTypeArguments<?>) nodes).getTypeArguments().orElse(new NodeList<>())).orElse(new NodeList<>()).stream().filter(type -> type.toString().equals(name)).findFirst().map(matchingType -> SymbolReference.solved(new JavaParserTypeParameter(new TypeParameter(matchingType.toString()), typeSolver))) ==> ERROR
+  Line 135) wrappedNode.getTypeArguments().map(nodes -> ((NodeWithTypeArguments<?>) nodes).getTypeArguments().orElse(new NodeList<>())).orElse(new NodeList<>()).stream().filter(type -> type.toString().equals(name)).findFirst() ==> ERROR
+  Line 135) wrappedNode.getTypeArguments().map(nodes -> ((NodeWithTypeArguments<?>) nodes).getTypeArguments().orElse(new NodeList<>())).orElse(new NodeList<>()).stream().filter(type -> type.toString().equals(name)) ==> ERROR
+  Line 135) wrappedNode.getTypeArguments().map(nodes -> ((NodeWithTypeArguments<?>) nodes).getTypeArguments().orElse(new NodeList<>())).orElse(new NodeList<>()).stream() ==> java.util.Collection.stream()
+  Line 135) wrappedNode.getTypeArguments().map(nodes -> ((NodeWithTypeArguments<?>) nodes).getTypeArguments().orElse(new NodeList<>())).orElse(new NodeList<>()) ==> java.util.Optional.orElse(T)
+  Line 135) wrappedNode.getTypeArguments().map(nodes -> ((NodeWithTypeArguments<?>) nodes).getTypeArguments().orElse(new NodeList<>())) ==> java.util.Optional.map(java.util.function.Function<? super T, ? extends U>)
+  Line 135) wrappedNode.getTypeArguments() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getTypeArguments()
+  Line 138) ((NodeWithTypeArguments<?>) nodes).getTypeArguments().orElse(new NodeList<>()) ==> java.util.Optional.orElse(T)
+  Line 138) ((NodeWithTypeArguments<?>) nodes).getTypeArguments() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments.getTypeArguments()
+  Line 142) type.toString().equals(name) ==> ERROR
+  Line 142) type.toString() ==> ERROR
+  Line 145) SymbolReference.solved(new JavaParserTypeParameter(new TypeParameter(matchingType.toString()), typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 146) matchingType.toString() ==> ERROR
+  Line 149) typeArgumentsMatch.isPresent() ==> java.util.Optional.isPresent()
+  Line 150) typeArgumentsMatch.get() ==> java.util.Optional.get()
+  Line 154) myDeclaration.getAncestors() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getAncestors()
+  Line 156) ancestor.getTypeDeclaration().getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 156) ancestor.getTypeDeclaration().getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 156) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 157) SymbolReference.solved(ancestor.getTypeDeclaration()) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 157) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 161) ancestor.getTypeDeclaration().internalTypes() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.internalTypes()
+  Line 161) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 162) internalTypeDeclaration.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 162) internalTypeDeclaration.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 163) SymbolReference.solved(internalTypeDeclaration) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 171) getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 171) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 177) Preconditions.checkArgument(typeSolver != null) ==> com.google.common.base.Preconditions.checkArgument(boolean)
+  Line 179) myDeclaration.hasVisibleField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasVisibleField(java.lang.String)
+  Line 180) SymbolReference.solved(myDeclaration.getVisibleField(name)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 180) myDeclaration.getVisibleField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getVisibleField(java.lang.String)
+  Line 183) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 183) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_CatchClauseContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_CatchClauseContext.txt
new file mode 100644
index 0000000..cebbaa0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_CatchClauseContext.txt
@@ -0,0 +1,14 @@
+  Line 26) JavaParserFactory.getSymbolDeclarator(wrappedNode.getParameter(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 26) wrappedNode.getParameter() ==> com.github.javaparser.ast.stmt.CatchClause.getParameter()
+  Line 27) AbstractJavaParserContext.solveWith(sb, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 28) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 33) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 33) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 38) JavaParserFactory.getSymbolDeclarator(wrappedNode.getParameter(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 38) wrappedNode.getParameter() ==> com.github.javaparser.ast.stmt.CatchClause.getParameter()
+  Line 39) solveWithAsValue(sb, name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWithAsValue(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 40) symbolReference.isPresent() ==> java.util.Optional.isPresent()
+  Line 46) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 46) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 52) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 52) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ClassOrInterfaceDeclarationContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ClassOrInterfaceDeclarationContext.txt
new file mode 100644
index 0000000..c40ab77
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ClassOrInterfaceDeclarationContext.txt
@@ -0,0 +1,28 @@
+  Line 46) getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext.getDeclaration()
+  Line 57) this.getDeclaration().hasVisibleField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasVisibleField(java.lang.String)
+  Line 57) this.getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext.getDeclaration()
+  Line 58) SymbolReference.solved(this.getDeclaration().getVisibleField(name)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 58) this.getDeclaration().getVisibleField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getVisibleField(java.lang.String)
+  Line 58) this.getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext.getDeclaration()
+  Line 62) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 62) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 69) this.getDeclaration().hasVisibleField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasVisibleField(java.lang.String)
+  Line 69) this.getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext.getDeclaration()
+  Line 70) Optional.of(Value.from(this.getDeclaration().getVisibleField(name))) ==> java.util.Optional.of(T)
+  Line 70) Value.from(this.getDeclaration().getVisibleField(name)) ==> com.github.javaparser.symbolsolver.model.resolution.Value.from(com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration)
+  Line 70) this.getDeclaration().getVisibleField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getVisibleField(java.lang.String)
+  Line 70) this.getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ClassOrInterfaceDeclarationContext.getDeclaration()
+  Line 74) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 74) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 79) wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 80) tp.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 80) tp.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 80) tp.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 81) Optional.of(new TypeVariable(new JavaParserTypeParameter(tp, typeSolver))) ==> java.util.Optional.of(T)
+  Line 84) getParent().solveGenericType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveGenericType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 84) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 89) javaParserTypeDeclarationAdapter.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.JavaParserTypeDeclarationAdapter.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 94) javaParserTypeDeclarationAdapter.solveMethod(name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.JavaParserTypeDeclarationAdapter.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 98) javaParserTypeDeclarationAdapter.solveConstructor(argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.JavaParserTypeDeclarationAdapter.solveConstructor(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 106) JavaParserFacade.get(typeSolver).getTypeDeclaration(this.wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 106) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_CompilationUnitContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_CompilationUnitContext.txt
new file mode 100644
index 0000000..532124e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_CompilationUnitContext.txt
@@ -0,0 +1,130 @@
+  Line 49) name.contains(".") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 69) itName.contains(".") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 70) getType(itName) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.getType(java.lang.String)
+  Line 71) getMember(itName) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.getMember(java.lang.String)
+  Line 72) this.solveType(typeName, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 73) type.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 74) new SymbolSolver(typeSolver).solveSymbolInType(type.getCorrespondingDeclaration(), memberName) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String)
+  Line 74) type.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 81) wrappedNode.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 82) wrappedNode.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 83) importDecl.isStatic() ==> com.github.javaparser.ast.ImportDeclaration.isStatic()
+  Line 84) importDecl.isAsterisk() ==> com.github.javaparser.ast.ImportDeclaration.isAsterisk()
+  Line 85) importDecl.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithName.getNameAsString()
+  Line 86) typeSolver.solveType(qName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 87) new SymbolSolver(typeSolver).solveSymbolInType(importedType, name) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String)
+  Line 88) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 92) importDecl.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithName.getNameAsString()
+  Line 95) getMember(whole) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.getMember(java.lang.String)
+  Line 96) getType(whole) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.getType(java.lang.String)
+  Line 98) memberName.equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 99) typeSolver.solveType(typeName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 100) new SymbolSolver(typeSolver).solveSymbolInType(importedType, memberName) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String)
+  Line 107) SymbolReference.unsolved(ValueDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 112) wrappedNode.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 113) wrappedNode.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 114) type.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 114) type.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 114) type.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 116) SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration((ClassOrInterfaceDeclaration) type)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 116) JavaParserFacade.get(typeSolver).getTypeDeclaration((ClassOrInterfaceDeclaration) type) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 116) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 118) SymbolReference.solved(new JavaParserAnnotationDeclaration((AnnotationDeclaration) type, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 120) type.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 120) type.getClass() ==> java.lang.Object.getClass()
+  Line 126) wrappedNode.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 127) name.indexOf('.') ==> java.lang.String.indexOf(int)
+  Line 130) name.substring(0, dotPos) ==> java.lang.String.substring(int, int)
+  Line 133) wrappedNode.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 134) importDecl.isAsterisk() ==> com.github.javaparser.ast.ImportDeclaration.isAsterisk()
+  Line 135) importDecl.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithName.getNameAsString()
+  Line 136) importDecl.getName().getQualifier().isPresent() ==> java.util.Optional.isPresent()
+  Line 136) importDecl.getName().getQualifier() ==> com.github.javaparser.ast.expr.Name.getQualifier()
+  Line 136) importDecl.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 137) importDecl.getName().getIdentifier().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 137) importDecl.getName().getIdentifier() ==> com.github.javaparser.ast.expr.Name.getIdentifier()
+  Line 137) importDecl.getName() ==> com.github.javaparser.ast.ImportDeclaration.getName()
+  Line 140) qName.endsWith("." + prefix) ==> java.lang.String.endsWith(java.lang.String)
+  Line 142) name.substring(dotPos) ==> java.lang.String.substring(int)
+  Line 147) typeSolver.tryToSolveType(qName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 148) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 149) SymbolReference.adapt(ref, com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.adapt(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends O>, java.lang.Class<O>)
+  Line 155) wrappedNode.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 156) importDecl.isAsterisk() ==> com.github.javaparser.ast.ImportDeclaration.isAsterisk()
+  Line 157) importDecl.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithName.getNameAsString()
+  Line 158) typeSolver.tryToSolveType(qName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 159) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 160) SymbolReference.adapt(ref, com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.adapt(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends O>, java.lang.Class<O>)
+  Line 167) this.wrappedNode.getPackageDeclaration().isPresent() ==> java.util.Optional.isPresent()
+  Line 167) this.wrappedNode.getPackageDeclaration() ==> com.github.javaparser.ast.CompilationUnit.getPackageDeclaration()
+  Line 168) this.wrappedNode.getPackageDeclaration().get().getName().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 168) this.wrappedNode.getPackageDeclaration().get().getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 168) this.wrappedNode.getPackageDeclaration().get() ==> java.util.Optional.get()
+  Line 168) this.wrappedNode.getPackageDeclaration() ==> com.github.javaparser.ast.CompilationUnit.getPackageDeclaration()
+  Line 169) typeSolver.tryToSolveType(qName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 170) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 171) SymbolReference.adapt(ref, com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.adapt(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends O>, java.lang.Class<O>)
+  Line 176) typeSolver.tryToSolveType(qName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 177) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 178) SymbolReference.adapt(ref, com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.adapt(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends O>, java.lang.Class<O>)
+  Line 183) typeSolver.tryToSolveType("java.lang." + name) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 184) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 185) SymbolReference.adapt(ref, com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.adapt(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends O>, java.lang.Class<O>)
+  Line 189) isQualifiedName(name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.isQualifiedName(java.lang.String)
+  Line 190) SymbolReference.adapt(typeSolver.tryToSolveType(name), com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.adapt(com.github.javaparser.symbolsolver.model.resolution.SymbolReference<? extends O>, java.lang.Class<O>)
+  Line 190) typeSolver.tryToSolveType(name) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 192) SymbolReference.unsolved(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 197) type.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 197) type.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 198) qName(type.getScope().get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.qName(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 198) type.getScope().get() ==> java.util.Optional.get()
+  Line 198) type.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 198) type.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 198) type.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 200) type.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 200) type.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 205) name.getQualifier().isPresent() ==> java.util.Optional.isPresent()
+  Line 205) name.getQualifier() ==> com.github.javaparser.ast.expr.Name.getQualifier()
+  Line 206) qName(name.getQualifier().get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.qName(com.github.javaparser.ast.expr.Name)
+  Line 206) name.getQualifier().get() ==> java.util.Optional.get()
+  Line 206) name.getQualifier() ==> com.github.javaparser.ast.expr.Name.getQualifier()
+  Line 206) name.getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 208) name.getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 213) qName.split("\\.") ==> java.lang.String.split(java.lang.String)
+  Line 218) qName.lastIndexOf('.') ==> java.lang.String.lastIndexOf(int)
+  Line 222) qName.substring(0, lastDot) ==> java.lang.String.substring(int, int)
+  Line 228) wrappedNode.getImports() ==> com.github.javaparser.ast.CompilationUnit.getImports()
+  Line 229) importDecl.isStatic() ==> com.github.javaparser.ast.ImportDeclaration.isStatic()
+  Line 230) importDecl.isAsterisk() ==> com.github.javaparser.ast.ImportDeclaration.isAsterisk()
+  Line 231) importDecl.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithName.getNameAsString()
+  Line 233) this.wrappedNode.getPackageDeclaration().isPresent() ==> java.util.Optional.isPresent()
+  Line 233) this.wrappedNode.getPackageDeclaration() ==> com.github.javaparser.ast.CompilationUnit.getPackageDeclaration()
+  Line 234) this.wrappedNode.getPackageDeclaration().get().getName().getIdentifier().equals(packageName(importString)) ==> java.lang.String.equals(java.lang.Object)
+  Line 234) this.wrappedNode.getPackageDeclaration().get().getName().getIdentifier() ==> com.github.javaparser.ast.expr.Name.getIdentifier()
+  Line 234) this.wrappedNode.getPackageDeclaration().get().getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 234) this.wrappedNode.getPackageDeclaration().get() ==> java.util.Optional.get()
+  Line 234) this.wrappedNode.getPackageDeclaration() ==> com.github.javaparser.ast.CompilationUnit.getPackageDeclaration()
+  Line 234) packageName(importString) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.packageName(java.lang.String)
+  Line 235) this.wrappedNode.getTypes().stream().anyMatch(it -> it.getName().getIdentifier().equals(toSimpleName(importString))) ==> ERROR
+  Line 235) this.wrappedNode.getTypes().stream() ==> java.util.Collection.stream()
+  Line 235) this.wrappedNode.getTypes() ==> com.github.javaparser.ast.CompilationUnit.getTypes()
+  Line 235) it.getName().getIdentifier().equals(toSimpleName(importString)) ==> ERROR
+  Line 235) it.getName().getIdentifier() ==> ERROR
+  Line 235) it.getName() ==> ERROR
+  Line 235) toSimpleName(importString) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.toSimpleName(java.lang.String)
+  Line 238) SymbolReference.unsolved(MethodDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 241) typeSolver.solveType(importString) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 242) MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, true, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 244) method.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 248) importDecl.getNameAsString() ==> com.github.javaparser.ast.nodeTypes.NodeWithName.getNameAsString()
+  Line 250) qName.equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 250) qName.endsWith("." + name) ==> java.lang.String.endsWith(java.lang.String)
+  Line 251) getType(qName) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.CompilationUnitContext.getType(java.lang.String)
+  Line 252) typeSolver.solveType(typeName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 253) MethodResolutionLogic.solveMethodInType(ref, name, argumentsTypes, true, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 254) method.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 261) SymbolReference.unsolved(MethodDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 269) qName.lastIndexOf('.') ==> java.lang.String.lastIndexOf(int)
+  Line 273) qName.substring(0, index) ==> java.lang.String.substring(int, int)
+  Line 278) qName.lastIndexOf('.') ==> java.lang.String.lastIndexOf(int)
+  Line 282) qName.substring(index + 1) ==> java.lang.String.substring(int)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ConstructorContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ConstructorContext.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ConstructorContext.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ContextHelper.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ContextHelper.txt
new file mode 100644
index 0000000..dd6aa34
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ContextHelper.txt
@@ -0,0 +1,13 @@
+  Line 50) ((JavassistClassDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 52) ((JavassistInterfaceDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 54) ((JavassistEnumDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 56) ((ReflectionClassDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 58) ((ReflectionInterfaceDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 60) ((ReflectionEnumDeclaration) typeDeclaration).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, typeParameters) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 62) ((JavaParserClassDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 62) ((JavaParserClassDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getContext()
+  Line 64) ((JavaParserInterfaceDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 64) ((JavaParserInterfaceDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.getContext()
+  Line 66) ((JavaParserEnumDeclaration) typeDeclaration).getContext().solveMethodAsUsage(name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 66) ((JavaParserEnumDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.getContext()
+  Line 68) typeDeclaration.toString() ==> java.lang.Object.toString()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_EnumDeclarationContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_EnumDeclarationContext.txt
new file mode 100644
index 0000000..125da24
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_EnumDeclarationContext.txt
@@ -0,0 +1,15 @@
+  Line 41) getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.EnumDeclarationContext.getDeclaration()
+  Line 49) wrappedNode.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 50) constant.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 50) constant.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 50) constant.getName() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getName()
+  Line 51) SymbolReference.solved(new JavaParserEnumConstantDeclaration(constant, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 55) this.getDeclaration().hasField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasField(java.lang.String)
+  Line 55) this.getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.EnumDeclarationContext.getDeclaration()
+  Line 56) SymbolReference.solved(this.getDeclaration().getField(name)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 56) this.getDeclaration().getField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getField(java.lang.String)
+  Line 56) this.getDeclaration() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.EnumDeclarationContext.getDeclaration()
+  Line 60) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 60) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 65) javaParserTypeDeclarationAdapter.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.JavaParserTypeDeclarationAdapter.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 70) javaParserTypeDeclarationAdapter.solveMethod(name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.JavaParserTypeDeclarationAdapter.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_FieldAccessContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_FieldAccessContext.txt
new file mode 100644
index 0000000..62039f6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_FieldAccessContext.txt
@@ -0,0 +1,37 @@
+  Line 52) wrappedNode.getField().toString().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 52) wrappedNode.getField().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 52) wrappedNode.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 53) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 54) JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeOfThisIn(com.github.javaparser.ast.Node)
+  Line 54) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 55) new SymbolSolver(typeSolver).solveSymbolInType(typeOfThis.asReferenceType().getTypeDeclaration(), name) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String)
+  Line 55) typeOfThis.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 55) typeOfThis.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 58) JavaParserFactory.getContext(getParentNode(wrappedNode), typeSolver).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 58) JavaParserFactory.getContext(getParentNode(wrappedNode), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 58) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 63) JavaParserFactory.getContext(getParentNode(wrappedNode), typeSolver).solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 63) JavaParserFactory.getContext(getParentNode(wrappedNode), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 63) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 68) JavaParserFactory.getContext(getParentNode(wrappedNode), typeSolver).solveMethod(name, parameterTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 68) JavaParserFactory.getContext(getParentNode(wrappedNode), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 68) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 73) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getScope()
+  Line 74) wrappedNode.getField().toString().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 74) wrappedNode.getField().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 74) wrappedNode.getField() ==> com.github.javaparser.ast.expr.FieldAccessExpr.getField()
+  Line 75) JavaParserFacade.get(typeSolver).getType(scope) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 75) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 76) typeOfScope.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 76) name.equals(ARRAY_LENGTH_FIELD_NAME) ==> java.lang.String.equals(java.lang.Object)
+  Line 77) Optional.of(new Value(PrimitiveType.INT, ARRAY_LENGTH_FIELD_NAME)) ==> java.util.Optional.of(T)
+  Line 79) typeOfScope.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 80) typeOfScope.asReferenceType().getFieldType(name) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getFieldType(java.lang.String)
+  Line 80) typeOfScope.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 81) typeUsage.isPresent() ==> java.util.Optional.isPresent()
+  Line 82) Optional.of(new Value(typeUsage.get(), name)) ==> java.util.Optional.of(T)
+  Line 82) typeUsage.get() ==> java.util.Optional.get()
+  Line 84) Optional.empty() ==> java.util.Optional.empty()
+  Line 87) Optional.empty() ==> java.util.Optional.empty()
+  Line 90) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 90) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ForStatementContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ForStatementContext.txt
new file mode 100644
index 0000000..1c4e6a3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ForStatementContext.txt
@@ -0,0 +1,15 @@
+  Line 45) wrappedNode.getInitialization() ==> com.github.javaparser.ast.stmt.ForStmt.getInitialization()
+  Line 48) variableDeclarationExpr.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 49) variableDeclarator.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 49) variableDeclarator.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 49) variableDeclarator.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 50) SymbolReference.solved(JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 50) JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.localVar(com.github.javaparser.ast.body.VariableDeclarator, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 54) expression.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 54) expression.getClass() ==> java.lang.Object.getClass()
+  Line 58) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 59) StatementContext.solveInBlock(name, typeSolver, wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.StatementContext.solveInBlock(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.ast.stmt.Statement)
+  Line 61) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 61) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 67) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 67) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ForechStatementContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ForechStatementContext.txt
new file mode 100644
index 0000000..835f3e4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_ForechStatementContext.txt
@@ -0,0 +1,17 @@
+  Line 41) wrappedNode.getVariable().getVariables().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 41) wrappedNode.getVariable().getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 41) wrappedNode.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 44) wrappedNode.getVariable().getVariables().get(0) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 44) wrappedNode.getVariable().getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 44) wrappedNode.getVariable() ==> com.github.javaparser.ast.stmt.ForeachStmt.getVariable()
+  Line 45) variableDeclarator.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 45) variableDeclarator.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 45) variableDeclarator.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 46) SymbolReference.solved(JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 46) JavaParserSymbolDeclaration.localVar(variableDeclarator, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.localVar(com.github.javaparser.ast.body.VariableDeclarator, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 48) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 49) StatementContext.solveInBlock(name, typeSolver, wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.StatementContext.solveInBlock(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.ast.stmt.Statement)
+  Line 51) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 51) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 58) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 58) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_JavaParserTypeDeclarationAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_JavaParserTypeDeclarationAdapter.txt
new file mode 100644
index 0000000..a39bb25
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_JavaParserTypeDeclarationAdapter.txt
@@ -0,0 +1,80 @@
+  Line 42) this.wrappedNode.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 42) this.wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 42) this.wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 43) SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(wrappedNode)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 43) JavaParserFacade.get(typeSolver).getTypeDeclaration(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 43) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 47) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 50) internalType.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 50) internalType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 50) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 51) SymbolReference.solved(JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 51) JavaParserFacade.get(typeSolver).getTypeDeclaration(internalType) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 51) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 52) name.startsWith(String.format("%s.%s", wrappedNode.getName(), internalType.getName())) ==> java.lang.String.startsWith(java.lang.String)
+  Line 52) String.format("%s.%s", wrappedNode.getName(), internalType.getName()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 52) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 52) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 53) JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(wrappedNode.getName().getId().length() + 1), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 53) JavaParserFactory.getContext(internalType, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 53) name.substring(wrappedNode.getName().getId().length() + 1) ==> java.lang.String.substring(int)
+  Line 53) wrappedNode.getName().getId().length() ==> java.lang.String.length()
+  Line 53) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 53) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 54) name.startsWith(String.format("%s.", internalType.getName())) ==> java.lang.String.startsWith(java.lang.String)
+  Line 54) String.format("%s.", internalType.getName()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 54) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 55) JavaParserFactory.getContext(internalType, typeSolver).solveType(name.substring(internalType.getName().getId().length() + 1), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 55) JavaParserFactory.getContext(internalType, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 55) name.substring(internalType.getName().getId().length() + 1) ==> java.lang.String.substring(int)
+  Line 55) internalType.getName().getId().length() ==> java.lang.String.length()
+  Line 55) internalType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 55) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 62) nodeWithTypeParameters.getTypeParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.getTypeParameters()
+  Line 64) astTp.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 64) astTp.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 64) astTp.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 65) SymbolReference.solved(new JavaParserTypeParameter(astTp, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 71) this.typeDeclaration.getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 73) ancestor.getTypeDeclaration().internalTypes() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.internalTypes()
+  Line 73) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 74) internalTypeDeclaration.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 74) internalTypeDeclaration.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 75) SymbolReference.solved(internalTypeDeclaration) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 83) context.getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 83) context.getParent() ==> com.github.javaparser.symbolsolver.core.resolution.Context.getParent()
+  Line 87) typeDeclaration.getDeclaredMethods().stream().filter(m -> m.getName().equals(name)).filter(m -> !staticOnly || (staticOnly && m.isStatic())).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 87) typeDeclaration.getDeclaredMethods().stream().filter(m -> m.getName().equals(name)).filter(m -> !staticOnly || (staticOnly && m.isStatic())) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 87) typeDeclaration.getDeclaredMethods().stream().filter(m -> m.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 87) typeDeclaration.getDeclaredMethods().stream() ==> java.util.Collection.stream()
+  Line 87) typeDeclaration.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getDeclaredMethods()
+  Line 88) m.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 88) m.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 89) m.isStatic() ==> com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration.isStatic()
+  Line 90) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 92) Object.class.getCanonicalName().equals(typeDeclaration.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 92) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 92) typeDeclaration.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 93) typeDeclaration.getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 95) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 96) MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 97) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 101) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 102) candidateMethods.add(res.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 102) res.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 109) candidateMethods.isEmpty() ==> java.util.List.isEmpty()
+  Line 110) context.getParent().solveMethod(name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 110) context.getParent() ==> com.github.javaparser.symbolsolver.core.resolution.Context.getParent()
+  Line 111) parentSolution.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 112) candidateMethods.add(parentSolution.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 112) parentSolution.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 117) candidateMethods.isEmpty() ==> java.util.List.isEmpty()
+  Line 117) typeDeclaration.isInterface() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isInterface()
+  Line 118) MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class, typeSolver), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 119) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 120) candidateMethods.add(res.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 120) res.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 124) MethodResolutionLogic.findMostApplicable(candidateMethods, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 129) ConstructorResolutionLogic.findMostApplicable(((ClassDeclaration) typeDeclaration).getConstructors(), argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration>, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 129) ((ClassDeclaration) typeDeclaration).getConstructors() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getConstructors()
+  Line 131) SymbolReference.unsolved(ConstructorDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_LambdaExprContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_LambdaExprContext.txt
new file mode 100644
index 0000000..f9e6d59
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_LambdaExprContext.txt
@@ -0,0 +1,78 @@
+  Line 58) wrappedNode.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 59) JavaParserFactory.getSymbolDeclarator(parameter, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 61) sb.getSymbolDeclarations() ==> com.github.javaparser.symbolsolver.resolution.SymbolDeclarator.getSymbolDeclarations()
+  Line 62) decl.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 62) decl.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 63) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 64) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 65) JavaParserFacade.get(typeSolver).solveMethodAsUsage(methodCallExpr) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveMethodAsUsage(com.github.javaparser.ast.expr.MethodCallExpr)
+  Line 65) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 66) pos(methodCallExpr, wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.LambdaExprContext.pos(com.github.javaparser.ast.expr.MethodCallExpr, com.github.javaparser.ast.expr.Expression)
+  Line 67) methodUsage.getParamTypes().get(i) ==> java.util.List.get(int)
+  Line 67) methodUsage.getParamTypes() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamTypes()
+  Line 70) FunctionalInterfaceLogic.getFunctionalMethod(lambdaType) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 71) functionalMethodOpt.isPresent() ==> java.util.Optional.isPresent()
+  Line 72) functionalMethodOpt.get() ==> java.util.Optional.get()
+  Line 77) inferenceContext.addPair(lambdaType, new ReferenceTypeImpl(lambdaType.asReferenceType().getTypeDeclaration(), typeSolver)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 77) lambdaType.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 77) lambdaType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 82) wrappedNode.getParameters().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 82) wrappedNode.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 83) wrappedNode.getParameter(lambdaParamIndex).getName().getIdentifier().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 83) wrappedNode.getParameter(lambdaParamIndex).getName().getIdentifier() ==> com.github.javaparser.ast.expr.SimpleName.getIdentifier()
+  Line 83) wrappedNode.getParameter(lambdaParamIndex).getName() ==> com.github.javaparser.ast.body.Parameter.getName()
+  Line 83) wrappedNode.getParameter(lambdaParamIndex) ==> com.github.javaparser.ast.nodeTypes.NodeWithParameters.getParameter(int)
+  Line 88) Optional.empty() ==> java.util.Optional.empty()
+  Line 91) inferenceContext.resolve(inferenceContext.addSingle(functionalMethod.getParamType(lambdaParamIndex))) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 91) inferenceContext.addSingle(functionalMethod.getParamType(lambdaParamIndex)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 91) functionalMethod.getParamType(lambdaParamIndex) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 94) argType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 95) LambdaConstraintType.bound(argType.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.bound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 95) argType.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 95) argType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 97) LambdaConstraintType.bound(argType) ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.bound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 100) Optional.of(value) ==> java.util.Optional.of(T)
+  Line 102) Optional.empty() ==> java.util.Optional.empty()
+  Line 104) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 105) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 106) JavaParserFacade.get(typeSolver).convertToUsageVariableType(variableDeclarator) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsageVariableType(com.github.javaparser.ast.body.VariableDeclarator)
+  Line 106) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 107) FunctionalInterfaceLogic.getFunctionalMethod(t) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 108) functionalMethod.isPresent() ==> java.util.Optional.isPresent()
+  Line 109) functionalMethod.get().getParamType(index) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 109) functionalMethod.get() ==> java.util.Optional.get()
+  Line 113) lambdaType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 114) lambdaType.asReferenceType().getTypeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeParametersMap()
+  Line 114) lambdaType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 115) entry._2.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 115) entry._2.asTypeParameter().declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 115) entry._2.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 116) t.asReferenceType().typeParametersMap().getValue(entry._1) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 116) t.asReferenceType().typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 116) t.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 117) lambdaType.replaceTypeVariables(entry._1, ot, inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 120) lambdaType.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 120) lambdaType.asTypeParameter().declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 120) lambdaType.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 121) t.asReferenceType().typeParametersMap().getValue(lambdaType.asTypeParameter()) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 121) t.asReferenceType().typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 121) t.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 121) lambdaType.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 125) Optional.of(value) ==> java.util.Optional.of(T)
+  Line 138) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 138) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 143) wrappedNode.getParameters() ==> com.github.javaparser.ast.expr.LambdaExpr.getParameters()
+  Line 144) JavaParserFactory.getSymbolDeclarator(parameter, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 145) solveWith(sb, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 146) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 152) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 152) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 157) getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 157) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 163) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 163) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 171) symbolDeclarator.getSymbolDeclarations() ==> com.github.javaparser.symbolsolver.resolution.SymbolDeclarator.getSymbolDeclarations()
+  Line 172) decl.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 172) decl.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 177) Optional.empty() ==> java.util.Optional.empty()
+  Line 186) callExpr.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_MethodCallExprContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_MethodCallExprContext.txt
new file mode 100644
index 0000000..2c751fe
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_MethodCallExprContext.txt
@@ -0,0 +1,322 @@
+  Line 64) wrappedNode.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 64) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 65) JavaParserFacade.get(typeSolver).getType(wrappedNode.getScope().get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 65) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 65) wrappedNode.getScope().get() ==> java.util.Optional.get()
+  Line 65) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 66) typeOfScope.asReferenceType().getGenericParameterByName(name) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getGenericParameterByName(java.lang.String)
+  Line 66) typeOfScope.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 69) Optional.empty() ==> java.util.Optional.empty()
+  Line 80) wrappedNode.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 80) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 81) wrappedNode.getScope().get() ==> java.util.Optional.get()
+  Line 81) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 84) ((NameExpr) scope).getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 84) ((NameExpr) scope).getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 85) solveType(className, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 86) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 87) MethodResolutionLogic.solveMethodInType(ref.getCorrespondingDeclaration(), name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 87) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 88) m.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 89) m.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 90) resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.resolveMethodTypeParametersFromExplicitList(com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.methods.MethodUsage)
+  Line 91) resolveMethodTypeParameters(methodUsage, argumentsTypes) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.resolveMethodTypeParameters(com.github.javaparser.symbolsolver.model.methods.MethodUsage, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 92) Optional.of(methodUsage) ==> java.util.Optional.of(T)
+  Line 94) ref.getCorrespondingDeclaration().toString() ==> java.lang.Object.toString()
+  Line 94) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 100) JavaParserFacade.get(typeSolver).getType(scope) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 100) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 104) argumentsTypes.size() ==> java.util.List.size()
+  Line 107) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 108) usingParameterTypesFromScope(typeOfScope, originalArgumentType, inferredTypes) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.usingParameterTypesFromScope(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 109) argumentsTypes.set(i, updatedArgumentType) ==> java.util.List.set(int, E)
+  Line 111) argumentsTypes.size() ==> java.util.List.size()
+  Line 112) applyInferredTypes(argumentsTypes.get(i), inferredTypes) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.applyInferredTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 112) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 113) argumentsTypes.set(i, updatedArgumentType) ==> java.util.List.set(int, E)
+  Line 116) solveMethodAsUsage(typeOfScope, name, argumentsTypes, typeSolver, this) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.typesystem.Type, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 118) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 120) parentContext.getParent() ==> com.github.javaparser.symbolsolver.core.resolution.Context.getParent()
+  Line 122) parentContext.solveMethodAsUsage(name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 127) wrappedNode.getTypeArguments().isPresent() ==> java.util.Optional.isPresent()
+  Line 127) wrappedNode.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 129) wrappedNode.getTypeArguments().get() ==> java.util.Optional.get()
+  Line 129) wrappedNode.getTypeArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getTypeArguments()
+  Line 130) typeArguments.add(JavaParserFacade.get(typeSolver).convertToUsage(ty)) ==> java.util.List.add(E)
+  Line 130) JavaParserFacade.get(typeSolver).convertToUsage(ty) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type)
+  Line 130) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 133) methodUsage.getDeclaration().getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 133) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 134) tyParamDecls.size() ==> java.util.List.size()
+  Line 134) typeArguments.size() ==> java.util.List.size()
+  Line 135) tyParamDecls.size() ==> java.util.List.size()
+  Line 136) methodUsage.replaceTypeParameter(tyParamDecls.get(i), typeArguments.get(i)) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceTypeParameter(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 136) tyParamDecls.get(i) ==> java.util.List.get(int)
+  Line 136) typeArguments.get(i) ==> java.util.List.get(int)
+  Line 146) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 146) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 151) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 152) parentContext.solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 157) wrappedNode.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 157) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 158) wrappedNode.getScope().get() ==> java.util.Optional.get()
+  Line 158) wrappedNode.getScope() ==> com.github.javaparser.ast.expr.MethodCallExpr.getScope()
+  Line 163) this.solveType(scopeAsName.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 163) scopeAsName.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 163) scopeAsName.getName() ==> com.github.javaparser.ast.expr.NameExpr.getName()
+  Line 164) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 164) symbolReference.getCorrespondingDeclaration().isType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isType()
+  Line 164) symbolReference.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 165) symbolReference.getCorrespondingDeclaration().asType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asType()
+  Line 165) symbolReference.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 166) MethodResolutionLogic.solveMethodInType(typeDeclaration, name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 172) JavaParserFacade.get(typeSolver).getType(scope) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 172) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 174) String.format("Issue calculating the type of the scope of " + this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 176) typeOfScope.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 177) typeOfScope.asWildcard().isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 177) typeOfScope.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 177) typeOfScope.asWildcard().isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 177) typeOfScope.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 178) MethodResolutionLogic.solveMethodInType(typeOfScope.asWildcard().getBoundedType().asReferenceType().getTypeDeclaration(), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 178) typeOfScope.asWildcard().getBoundedType().asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 178) typeOfScope.asWildcard().getBoundedType().asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 178) typeOfScope.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 178) typeOfScope.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 180) MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class, typeSolver), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 182) typeOfScope.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 184) MethodResolutionLogic.solveMethodInType(new ReflectionClassDeclaration(Object.class, typeSolver), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 185) typeOfScope.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 186) typeOfScope.asTypeParameter().getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 186) typeOfScope.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 187) MethodResolutionLogic.solveMethodInType(bound.getType().asReferenceType().getTypeDeclaration(), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 187) bound.getType().asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 187) bound.getType().asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 187) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 188) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 192) SymbolReference.unsolved(MethodDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 193) typeOfScope.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 194) MethodResolutionLogic.solveMethodInType(typeOfScope.asConstraintType().getBound().asReferenceType().getTypeDeclaration(), name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 194) typeOfScope.asConstraintType().getBound().asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 194) typeOfScope.asConstraintType().getBound().asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 194) typeOfScope.asConstraintType().getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 194) typeOfScope.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
+  Line 196) MethodResolutionLogic.solveMethodInType(typeOfScope.asReferenceType().getTypeDeclaration(), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 196) typeOfScope.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 196) typeOfScope.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 199) JavaParserFacade.get(typeSolver).getTypeOfThisIn(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeOfThisIn(com.github.javaparser.ast.Node)
+  Line 199) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 200) MethodResolutionLogic.solveMethodInType(typeOfScope.asReferenceType().getTypeDeclaration(), name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 200) typeOfScope.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 200) typeOfScope.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 211) ContextHelper.solveMethodAsUsage(refType.getTypeDeclaration(), name, argumentsTypes, typeSolver, invokationContext, refType.typeParametersValues()) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ContextHelper.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 211) refType.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 211) refType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 212) ref.isPresent() ==> java.util.Optional.isPresent()
+  Line 213) ref.get() ==> java.util.Optional.get()
+  Line 215) resolveMethodTypeParametersFromExplicitList(typeSolver, methodUsage) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.resolveMethodTypeParametersFromExplicitList(com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.methods.MethodUsage)
+  Line 236) methodUsage.getParamTypes().size() ==> java.util.List.size()
+  Line 236) methodUsage.getParamTypes() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamTypes()
+  Line 237) methodUsage.getDeclaration().getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 237) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 238) parameter.getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 239) parameter.isVariadic() ==> com.github.javaparser.symbolsolver.model.declarations.ParameterDeclaration.isVariadic()
+  Line 240) parameterType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 240) parameterType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 242) inferTypes(argumentsTypes.get(i), parameterType, derivedValues) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 242) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 245) derivedValues.entrySet() ==> java.util.Map.entrySet()
+  Line 246) methodUsage.replaceTypeParameter(entry.getKey(), entry.getValue()) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceTypeParameter(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 246) entry.getKey() ==> java.util.Map.Entry.getKey()
+  Line 246) entry.getValue() ==> java.util.Map.Entry.getValue()
+  Line 249) refType.useThisTypeParametersOnTheGivenType(methodUsage.returnType()) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 249) methodUsage.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 250) methodUsage.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 251) methodUsage.replaceReturnType(returnType) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceReturnType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 253) methodUsage.getParamTypes().size() ==> java.util.List.size()
+  Line 253) methodUsage.getParamTypes() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamTypes()
+  Line 254) refType.useThisTypeParametersOnTheGivenType(methodUsage.getParamTypes().get(i)) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 254) methodUsage.getParamTypes().get(i) ==> java.util.List.get(int)
+  Line 254) methodUsage.getParamTypes() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamTypes()
+  Line 255) methodUsage.replaceParamType(i, replaced) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceParamType(int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 257) Optional.of(methodUsage) ==> java.util.Optional.of(T)
+  Line 264) source.equals(target) ==> java.lang.Object.equals(java.lang.Object)
+  Line 267) source.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 267) target.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 268) source.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 269) target.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 270) sourceRefType.getQualifiedName().equals(targetRefType.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 270) sourceRefType.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 270) targetRefType.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 271) sourceRefType.isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 271) targetRefType.isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 272) sourceRefType.typeParametersValues().size() ==> java.util.List.size()
+  Line 272) sourceRefType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 273) inferTypes(sourceRefType.typeParametersValues().get(i), targetRefType.typeParametersValues().get(i), mappings) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 273) sourceRefType.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 273) sourceRefType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 273) targetRefType.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 273) targetRefType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 279) source.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 279) target.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 280) target.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 280) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 281) inferTypes(source, target.asWildcard().getBoundedType(), mappings) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 281) target.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 281) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 286) source.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 286) target.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 287) source.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 287) source.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 287) target.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 287) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 288) inferTypes(source.asWildcard().getBoundedType(), target.asWildcard().getBoundedType(), mappings) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 288) source.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 288) source.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 288) target.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 288) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 292) source.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 292) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 293) mappings.put(target.asTypeParameter(), source) ==> java.util.Map.put(K, V)
+  Line 293) target.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 296) source.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 296) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 297) mappings.put(target.asTypeParameter(), source) ==> java.util.Map.put(K, V)
+  Line 297) target.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 300) source.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 300) target.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 301) target.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 301) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 302) inferTypes(source, target.asWildcard().getBoundedType(), mappings) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 302) target.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 302) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 307) source.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 307) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 308) mappings.put(target.asTypeParameter(), source) ==> java.util.Map.put(K, V)
+  Line 308) target.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 312) source.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 312) target.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 313) source.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 313) source.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 314) inferTypes(source.asWildcard().getBoundedType(), target, mappings) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 314) source.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 314) source.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 318) source.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 318) target.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 319) inferTypes(source.asConstraintType().getBound(), target, mappings) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 319) source.asConstraintType().getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 319) source.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
+  Line 323) source.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 323) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 324) inferTypes(source.asConstraintType().getBound(), target, mappings) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 324) source.asConstraintType().getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 324) source.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
+  Line 327) source.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 327) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 328) mappings.put(target.asTypeParameter(), source) ==> java.util.Map.put(K, V)
+  Line 328) target.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 331) source.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 331) target.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 334) source.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 337) source.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 337) target.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 343) methodUsage.getDeclaration().hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 343) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 344) actualParamTypes.size() ==> java.util.List.size()
+  Line 344) methodUsage.getDeclaration().getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 344) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 347) methodUsage.getDeclaration().getLastParam().getType().asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 347) methodUsage.getDeclaration().getLastParam().getType().asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 347) methodUsage.getDeclaration().getLastParam().getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 347) methodUsage.getDeclaration().getLastParam() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getLastParam()
+  Line 347) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 350) actualParamTypes.get(actualParamTypes.size() - 1).isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 350) actualParamTypes.get(actualParamTypes.size() - 1) ==> java.util.List.get(int)
+  Line 350) actualParamTypes.size() ==> java.util.List.size()
+  Line 351) actualParamTypes.get(actualParamTypes.size() - 1).asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 351) actualParamTypes.get(actualParamTypes.size() - 1).asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 351) actualParamTypes.get(actualParamTypes.size() - 1) ==> java.util.List.get(int)
+  Line 351) actualParamTypes.size() ==> java.util.List.size()
+  Line 352) actualParamTypes.get(actualParamTypes.size() - 1) ==> java.util.List.get(int)
+  Line 352) actualParamTypes.size() ==> java.util.List.size()
+  Line 353) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 354) methodUsage.getDeclaration().getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 354) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 355) MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.replaceTypeParam(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 358) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 361) String.format("Unable to resolve the type typeParametersValues in a MethodUsage. Expected type: %s, Actual type: %s. Method Declaration: %s. MethodUsage: %s", expectedType, actualType, methodUsage.getDeclaration(), methodUsage) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 364) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 368) matchTypeParameters(expectedType, actualType, matchedTypeParameters) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.matchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 374) methodUsage.getDeclaration().hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 374) methodUsage.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 375) actualParamTypes.size() ==> java.util.List.size()
+  Line 376) actualParamTypes.size() ==> java.util.List.size()
+  Line 379) methodUsage.getParamType(i) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 380) actualParamTypes.get(i) ==> java.util.List.get(int)
+  Line 381) matchTypeParameters(expectedType, actualType, matchedTypeParameters) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.matchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 383) matchedTypeParameters.keySet() ==> java.util.Map.keySet()
+  Line 384) methodUsage.replaceTypeParameter(tp, matchedTypeParameters.get(tp)) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceTypeParameter(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 384) matchedTypeParameters.get(tp) ==> java.util.Map.get(java.lang.Object)
+  Line 390) expectedType.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 391) actualType.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 391) actualType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 392) actualType.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 392) actualType.getClass() ==> java.lang.Object.getClass()
+  Line 394) matchedTypeParameters.put(expectedType.asTypeParameter(), actualType) ==> java.util.Map.put(K, V)
+  Line 394) expectedType.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 395) expectedType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 396) actualType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 397) actualType.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 397) actualType.getClass() ==> java.lang.Object.getClass()
+  Line 399) matchTypeParameters(expectedType.asArrayType().getComponentType(), actualType.asArrayType().getComponentType(), matchedTypeParameters) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.matchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 400) expectedType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 400) expectedType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 401) actualType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 401) actualType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 403) expectedType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 405) actualType.asReferenceType().typeParametersValues().size() ==> java.util.List.size()
+  Line 405) actualType.asReferenceType().typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 405) actualType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 407) expectedType.asReferenceType().typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 407) expectedType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 408) matchTypeParameters(tp, actualType.asReferenceType().typeParametersValues().get(i), matchedTypeParameters) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.matchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 408) actualType.asReferenceType().typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 408) actualType.asReferenceType().typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 408) actualType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 413) expectedType.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 415) expectedType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 418) expectedType.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 418) expectedType.getClass() ==> java.lang.Object.getClass()
+  Line 423) tp.asTypeParameter().getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 423) tp.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.asTypeParameter()
+  Line 424) solveMethodAsUsage(bound.getType(), name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.typesystem.Type, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 424) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 425) methodUsage.isPresent() ==> java.util.Optional.isPresent()
+  Line 429) Optional.empty() ==> java.util.Optional.empty()
+  Line 434) solveMethodAsUsage((ReferenceType) type, name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 436) solveMethodAsUsage((TypeVariable) type, name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.typesystem.TypeVariable, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 439) wildcardUsage.isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 440) solveMethodAsUsage(wildcardUsage.getBoundedType(), name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.typesystem.Type, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 440) wildcardUsage.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 441) wildcardUsage.isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 448) solveMethodAsUsage(constraintType.getBound(), name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.typesystem.Type, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 448) constraintType.getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 451) solveMethodAsUsage(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver), name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 453) type.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 453) type.getClass() ==> java.lang.Object.getClass()
+  Line 458) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 459) type.asReferenceType().getTypeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeParametersMap()
+  Line 459) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 460) entry._1.declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 460) scope.asReferenceType().getGenericParameterByName(entry._1.getName()).isPresent() ==> java.util.Optional.isPresent()
+  Line 460) scope.asReferenceType().getGenericParameterByName(entry._1.getName()) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getGenericParameterByName(java.lang.String)
+  Line 460) scope.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 460) entry._1.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 461) type.replaceTypeVariables(entry._1, scope.asReferenceType().getGenericParameterByName(entry._1.getName()).get(), inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 461) scope.asReferenceType().getGenericParameterByName(entry._1.getName()).get() ==> java.util.Optional.get()
+  Line 461) scope.asReferenceType().getGenericParameterByName(entry._1.getName()) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getGenericParameterByName(java.lang.String)
+  Line 461) scope.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 461) entry._1.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 471) inferredTypes.keySet() ==> java.util.Map.keySet()
+  Line 472) type.replaceTypeVariables(tp, inferredTypes.get(tp), inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 472) inferredTypes.get(tp) ==> java.util.Map.get(java.lang.Object)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_MethodContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_MethodContext.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_MethodContext.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_StatementContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_StatementContext.txt
new file mode 100644
index 0000000..774a465
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_StatementContext.txt
@@ -0,0 +1,93 @@
+  Line 49) getParentNode(stmt) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 52) getParentNode(stmt) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 54) blockStmt.getStatements().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 54) blockStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 55) blockStmt.getStatements().get(i).equals(stmt) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 55) blockStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 55) blockStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 63) JavaParserFactory.getSymbolDeclarator(blockStmt.getStatements().get(i), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 63) blockStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 63) blockStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 64) solveWith(symbolDeclarator, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 65) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 71) JavaParserFactory.getContext(getParentNode(stmt), typeSolver).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 71) JavaParserFactory.getContext(getParentNode(stmt), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 71) getParentNode(stmt) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 75) getParentNode(stmt) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 78) getParentNode(stmt) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 80) blockStmt.getStatements().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 80) blockStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 81) blockStmt.getStatements().get(i).equals(stmt) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 81) blockStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 81) blockStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 89) JavaParserFactory.getSymbolDeclarator(blockStmt.getStatements().get(i), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 89) blockStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 89) blockStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 90) solveWith(symbolDeclarator, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 91) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 92) Optional.of(Value.from(symbolReference.getCorrespondingDeclaration())) ==> java.util.Optional.of(T)
+  Line 92) Value.from(symbolReference.getCorrespondingDeclaration()) ==> com.github.javaparser.symbolsolver.model.resolution.Value.from(com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration)
+  Line 92) symbolReference.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 97) JavaParserFactory.getContext(getParentNode(stmt), typeSolver).solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 97) JavaParserFactory.getContext(getParentNode(stmt), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 97) getParentNode(stmt) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 104) JavaParserFactory.getSymbolDeclarator(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 105) solveWithAsValue(symbolDeclarator, name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWithAsValue(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 106) symbolReference.isPresent() ==> java.util.Optional.isPresent()
+  Line 111) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 112) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 112) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 114) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 115) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 115) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 117) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 118) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 118) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 120) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 121) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 121) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 123) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 125) nodeWithStmt.getStatements().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 125) nodeWithStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 126) nodeWithStmt.getStatements().get(i).equals(wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 126) nodeWithStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 126) nodeWithStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 134) JavaParserFactory.getSymbolDeclarator(nodeWithStmt.getStatements().get(i), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 134) nodeWithStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 134) nodeWithStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 135) solveWithAsValue(symbolDeclarator, name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWithAsValue(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 136) symbolReference.isPresent() ==> java.util.Optional.isPresent()
+  Line 142) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 143) parentContext.solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 150) JavaParserFactory.getSymbolDeclarator(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 151) solveWith(symbolDeclarator, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 152) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 157) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 158) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 158) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 160) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 161) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 161) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 163) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 164) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 164) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 166) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 167) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 167) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 169) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 171) nodeWithStmt.getStatements().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 171) nodeWithStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 172) nodeWithStmt.getStatements().get(i).equals(wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 172) nodeWithStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 172) nodeWithStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 180) JavaParserFactory.getSymbolDeclarator(nodeWithStmt.getStatements().get(i), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 180) nodeWithStmt.getStatements().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 180) nodeWithStmt.getStatements() ==> com.github.javaparser.ast.nodeTypes.NodeWithStatements.getStatements()
+  Line 181) solveWith(symbolDeclarator, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 182) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 188) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 188) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 193) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 193) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 198) getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 198) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_SwitchEntryContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_SwitchEntryContext.txt
new file mode 100644
index 0000000..9552ce0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_SwitchEntryContext.txt
@@ -0,0 +1,23 @@
+  Line 47) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 48) JavaParserFacade.get(typeSolver).getType(switchStmt.getSelector()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 48) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 48) switchStmt.getSelector() ==> com.github.javaparser.ast.stmt.SwitchStmt.getSelector()
+  Line 49) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 49) type.asReferenceType().getTypeDeclaration().isEnum() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isEnum()
+  Line 49) type.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 49) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 52) typeUsageOfTypeDeclaration.getTypeDeclaration().hasField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasField(java.lang.String)
+  Line 52) typeUsageOfTypeDeclaration.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 53) SymbolReference.solved(typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 53) typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getField(java.lang.String)
+  Line 53) typeUsageOfTypeDeclaration.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 61) switchStmt.getEntries() ==> com.github.javaparser.ast.stmt.SwitchStmt.getEntries()
+  Line 62) seStmt.equals(wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 63) seStmt.getStatements() ==> com.github.javaparser.ast.stmt.SwitchEntryStmt.getStatements()
+  Line 64) JavaParserFactory.getSymbolDeclarator(stmt, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getSymbolDeclarator(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 65) solveWith(symbolDeclarator, name) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.solveWith(com.github.javaparser.symbolsolver.resolution.SymbolDeclarator, java.lang.String)
+  Line 66) symbolReference.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 73) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 73) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 78) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 78) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_TryWithResourceContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_TryWithResourceContext.txt
new file mode 100644
index 0000000..ee4c0ca
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_contexts_TryWithResourceContext.txt
@@ -0,0 +1,25 @@
+  Line 45) wrappedNode.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 46) expr.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 47) v.getName().getIdentifier().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 47) v.getName().getIdentifier() ==> com.github.javaparser.ast.expr.SimpleName.getIdentifier()
+  Line 47) v.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 48) JavaParserSymbolDeclaration.localVar(v, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.localVar(com.github.javaparser.ast.body.VariableDeclarator, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 49) Optional.of(Value.from(decl)) ==> java.util.Optional.of(T)
+  Line 49) Value.from(decl) ==> com.github.javaparser.symbolsolver.model.resolution.Value.from(com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration)
+  Line 54) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 55) StatementContext.solveInBlockAsValue(name, typeSolver, wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.StatementContext.solveInBlockAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.ast.stmt.Statement)
+  Line 57) getParent().solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 57) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 63) wrappedNode.getResources() ==> com.github.javaparser.ast.stmt.TryStmt.getResources()
+  Line 64) expr.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 65) v.getName().getIdentifier().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 65) v.getName().getIdentifier() ==> com.github.javaparser.ast.expr.SimpleName.getIdentifier()
+  Line 65) v.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 66) SymbolReference.solved(JavaParserSymbolDeclaration.localVar(v, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 66) JavaParserSymbolDeclaration.localVar(v, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.localVar(com.github.javaparser.ast.body.VariableDeclarator, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 71) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 72) StatementContext.solveInBlock(name, typeSolver, wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.StatementContext.solveInBlock(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.ast.stmt.Statement)
+  Line 74) getParent().solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 74) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
+  Line 80) getParent().solveMethod(name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 80) getParent() ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.AbstractJavaParserContext.getParent()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_DefaultConstructorDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_DefaultConstructorDeclaration.txt
new file mode 100644
index 0000000..8ead6fd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_DefaultConstructorDeclaration.txt
@@ -0,0 +1,2 @@
+  Line 52) classDeclaration.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 62) Collections.emptyList() ==> java.util.Collections.emptyList()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_Helper.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_Helper.txt
new file mode 100644
index 0000000..d540027
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_Helper.txt
@@ -0,0 +1,26 @@
+  Line 36) modifiers.contains(Modifier.PRIVATE) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 38) modifiers.contains(Modifier.PROTECTED) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 40) modifiers.contains(Modifier.PUBLIC) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 48) getPackageName(container) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getPackageName(com.github.javaparser.ast.Node)
+  Line 49) getClassName("", container) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 51) packageName.isEmpty() ==> java.lang.String.isEmpty()
+  Line 51) className.isEmpty() ==> java.lang.String.isEmpty()
+  Line 57) ((CompilationUnit) container).getPackageDeclaration() ==> com.github.javaparser.ast.CompilationUnit.getPackageDeclaration()
+  Line 58) p.isPresent() ==> java.util.Optional.isPresent()
+  Line 59) p.get().getName().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 59) p.get().getName() ==> com.github.javaparser.ast.PackageDeclaration.getName()
+  Line 59) p.get() ==> java.util.Optional.get()
+  Line 62) getPackageName(getParentNode(container)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getPackageName(com.github.javaparser.ast.Node)
+  Line 62) getParentNode(container) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 69) getClassName(base, getParentNode(container)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 69) getParentNode(container) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 70) ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 70) ((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) container).getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 71) b.isEmpty() ==> java.lang.String.isEmpty()
+  Line 77) getClassName(base, getParentNode(container)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 77) getParentNode(container) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 78) ((com.github.javaparser.ast.body.EnumDeclaration) container).getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 78) ((com.github.javaparser.ast.body.EnumDeclaration) container).getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 79) b.isEmpty() ==> java.lang.String.isEmpty()
+  Line 85) getClassName(base, getParentNode(container)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 85) getParentNode(container) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserAnnotationDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserAnnotationDeclaration.txt
new file mode 100644
index 0000000..f63725b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserAnnotationDeclaration.txt
@@ -0,0 +1,12 @@
+  Line 60) Helper.getPackageName(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getPackageName(com.github.javaparser.ast.Node)
+  Line 65) Helper.getClassName("", wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 70) Helper.containerName(getParentNode(wrappedNode)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.containerName(com.github.javaparser.ast.Node)
+  Line 70) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 71) containerName.isEmpty() ==> java.lang.String.isEmpty()
+  Line 72) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 72) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 74) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 80) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 80) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 90) this.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 90) this.getClass() ==> java.lang.Object.getClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserAnonymousClassDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserAnonymousClassDeclaration.txt
new file mode 100644
index 0000000..a195f82
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserAnonymousClassDeclaration.txt
@@ -0,0 +1,87 @@
+  Line 37) UUID.randomUUID() ==> java.util.UUID.randomUUID()
+  Line 44) JavaParserFactory.getContext(wrappedNode.getParentNode().get(), typeSolver).solveType(wrappedNode.getType().getName().getId(), typeSolver).getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 44) JavaParserFactory.getContext(wrappedNode.getParentNode().get(), typeSolver).solveType(wrappedNode.getType().getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 44) JavaParserFactory.getContext(wrappedNode.getParentNode().get(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 44) wrappedNode.getParentNode().get() ==> java.util.Optional.get()
+  Line 44) wrappedNode.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 45) wrappedNode.getType().getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 45) wrappedNode.getType().getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 45) wrappedNode.getType() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getType()
+  Line 54) wrappedNode.getAnonymousClassBody().get().stream().filter(node -> memberClass.isAssignableFrom(node.getClass())).map(node -> (T) node).collect(Collectors.toList()) ==> ERROR
+  Line 54) wrappedNode.getAnonymousClassBody().get().stream().filter(node -> memberClass.isAssignableFrom(node.getClass())).map(node -> (T) node) ==> ERROR
+  Line 54) wrappedNode.getAnonymousClassBody().get().stream().filter(node -> memberClass.isAssignableFrom(node.getClass())) ==> ERROR
+  Line 54) wrappedNode.getAnonymousClassBody().get().stream() ==> java.util.Collection.stream()
+  Line 54) wrappedNode.getAnonymousClassBody().get() ==> java.util.Optional.get()
+  Line 54) wrappedNode.getAnonymousClassBody() ==> com.github.javaparser.ast.expr.ObjectCreationExpr.getAnonymousClassBody()
+  Line 58) memberClass.isAssignableFrom(node.getClass()) ==> ERROR
+  Line 58) node.getClass() ==> ERROR
+  Line 60) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 65) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 65) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 70) superTypeDeclaration.asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 76) superTypeDeclaration.asReferenceType().getAncestors().stream().filter(type -> type.getTypeDeclaration().isInterface()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 76) superTypeDeclaration.asReferenceType().getAncestors().stream().filter(type -> type.getTypeDeclaration().isInterface()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 76) superTypeDeclaration.asReferenceType().getAncestors().stream() ==> java.util.Collection.stream()
+  Line 76) superTypeDeclaration.asReferenceType().getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 76) superTypeDeclaration.asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 79) type.getTypeDeclaration().isInterface() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isInterface()
+  Line 79) type.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 80) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 86) findMembersOfKind(com.github.javaparser.ast.body.ConstructorDeclaration.class).stream().map(ctor -> new JavaParserConstructorDeclaration(this, ctor, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 86) findMembersOfKind(com.github.javaparser.ast.body.ConstructorDeclaration.class).stream().map(ctor -> new JavaParserConstructorDeclaration(this, ctor, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 86) findMembersOfKind(com.github.javaparser.ast.body.ConstructorDeclaration.class).stream() ==> java.util.Collection.stream()
+  Line 86) findMembersOfKind(com.github.javaparser.ast.body.ConstructorDeclaration.class) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.findMembersOfKind(java.lang.Class<T>)
+  Line 89) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 100) ImmutableList.<ReferenceType>builder().add(getSuperClass()).addAll(superTypeDeclaration.asReferenceType().getAncestors()).build() ==> com.google.common.collect.ImmutableList.Builder.build()
+  Line 100) ImmutableList.<ReferenceType>builder().add(getSuperClass()).addAll(superTypeDeclaration.asReferenceType().getAncestors()) ==> com.google.common.collect.ImmutableList.Builder.addAll(java.lang.Iterable<? extends E>)
+  Line 100) ImmutableList.<ReferenceType>builder().add(getSuperClass()) ==> com.google.common.collect.ImmutableList.Builder.add(E...)
+  Line 100) ImmutableList.<ReferenceType>builder() ==> com.google.common.collect.ImmutableList.builder()
+  Line 102) getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getSuperClass()
+  Line 103) superTypeDeclaration.asReferenceType().getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 103) superTypeDeclaration.asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 111) findMembersOfKind(com.github.javaparser.ast.body.FieldDeclaration.class).stream().flatMap(field -> field.getVariables().stream().map(variable -> new JavaParserFieldDeclaration(variable, typeSolver))).collect(Collectors.toList()) ==> ERROR
+  Line 111) findMembersOfKind(com.github.javaparser.ast.body.FieldDeclaration.class).stream().flatMap(field -> field.getVariables().stream().map(variable -> new JavaParserFieldDeclaration(variable, typeSolver))) ==> java.util.stream.Stream.flatMap(java.util.function.Function<? super T, ? extends java.util.stream.Stream<? extends R>>)
+  Line 111) findMembersOfKind(com.github.javaparser.ast.body.FieldDeclaration.class).stream() ==> java.util.Collection.stream()
+  Line 111) findMembersOfKind(com.github.javaparser.ast.body.FieldDeclaration.class) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.findMembersOfKind(java.lang.Class<T>)
+  Line 114) field.getVariables().stream().map(variable -> new JavaParserFieldDeclaration(variable, typeSolver)) ==> ERROR
+  Line 114) field.getVariables().stream() ==> ERROR
+  Line 114) field.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 117) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 120) getSuperClass().getTypeDeclaration().getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 120) getSuperClass().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 120) getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getSuperClass()
+  Line 123) getInterfaces().stream().flatMap(inteface -> inteface.getTypeDeclaration().getAllFields().stream()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 123) getInterfaces().stream().flatMap(inteface -> inteface.getTypeDeclaration().getAllFields().stream()) ==> java.util.stream.Stream.flatMap(java.util.function.Function<? super T, ? extends java.util.stream.Stream<? extends R>>)
+  Line 123) getInterfaces().stream() ==> java.util.Collection.stream()
+  Line 123) getInterfaces() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getInterfaces()
+  Line 124) inteface.getTypeDeclaration().getAllFields().stream() ==> java.util.Collection.stream()
+  Line 124) inteface.getTypeDeclaration().getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 124) inteface.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 125) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 128) ImmutableList.<FieldDeclaration>builder().addAll(myFields).addAll(superClassFields).addAll(interfaceFields).build() ==> com.google.common.collect.ImmutableList.Builder.build()
+  Line 128) ImmutableList.<FieldDeclaration>builder().addAll(myFields).addAll(superClassFields).addAll(interfaceFields) ==> com.google.common.collect.ImmutableList.Builder.addAll(java.lang.Iterable<? extends E>)
+  Line 128) ImmutableList.<FieldDeclaration>builder().addAll(myFields).addAll(superClassFields) ==> com.google.common.collect.ImmutableList.Builder.addAll(java.lang.Iterable<? extends E>)
+  Line 128) ImmutableList.<FieldDeclaration>builder().addAll(myFields) ==> com.google.common.collect.ImmutableList.Builder.addAll(java.lang.Iterable<? extends E>)
+  Line 128) ImmutableList.<FieldDeclaration>builder() ==> com.google.common.collect.ImmutableList.builder()
+  Line 139) findMembersOfKind(com.github.javaparser.ast.body.MethodDeclaration.class).stream().map(method -> new JavaParserMethodDeclaration(method, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 139) findMembersOfKind(com.github.javaparser.ast.body.MethodDeclaration.class).stream().map(method -> new JavaParserMethodDeclaration(method, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 139) findMembersOfKind(com.github.javaparser.ast.body.MethodDeclaration.class).stream() ==> java.util.Collection.stream()
+  Line 139) findMembersOfKind(com.github.javaparser.ast.body.MethodDeclaration.class) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.findMembersOfKind(java.lang.Class<T>)
+  Line 142) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 162) Helper.getPackageName(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getPackageName(com.github.javaparser.ast.Node)
+  Line 167) Helper.getClassName("", wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 172) Helper.containerName(getParentNode(wrappedNode)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.containerName(com.github.javaparser.ast.Node)
+  Line 172) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 173) containerName.isEmpty() ==> java.lang.String.isEmpty()
+  Line 174) getName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getName()
+  Line 176) getName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.getName()
+  Line 183) findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class).stream().map(typeMember -> JavaParserFacade.get(typeSolver).getTypeDeclaration(typeMember)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 183) findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class).stream().map(typeMember -> JavaParserFacade.get(typeSolver).getTypeDeclaration(typeMember)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 183) findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class).stream() ==> java.util.Collection.stream()
+  Line 183) findMembersOfKind(com.github.javaparser.ast.body.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserAnonymousClassDeclaration.findMembersOfKind(java.lang.Class<T>)
+  Line 185) JavaParserFacade.get(typeSolver).getTypeDeclaration(typeMember) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 185) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 186) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 196) Lists.newArrayList() ==> com.google.common.collect.Lists.newArrayList()
+  Line 201) this.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 201) this.getClass() ==> java.lang.Object.getClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserClassDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserClassDeclaration.txt
new file mode 100644
index 0000000..af627c4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserClassDeclaration.txt
@@ -0,0 +1,139 @@
+  Line 64) wrappedNode.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 79) getClass() ==> java.lang.Object.getClass()
+  Line 79) o.getClass() ==> java.lang.Object.getClass()
+  Line 83) wrappedNode.equals(that.wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 90) wrappedNode.hashCode() ==> com.github.javaparser.ast.Node.hashCode()
+  Line 107) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 110) field.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 111) fields.add(new JavaParserFieldDeclaration(vd, typeSolver)) ==> java.util.ArrayList.add(E)
+  Line 116) this.getSuperClass().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 116) this.getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getSuperClass()
+  Line 118) fields.addAll(superclass.getAllFields()) ==> java.util.ArrayList.addAll(java.util.Collection<? extends E>)
+  Line 118) superclass.getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 120) getInterfaces().forEach(interf -> interf.getTypeDeclaration().getAllFields().forEach(f -> {
+    fields.add(f);
+})) ==> java.lang.Iterable.forEach(java.util.function.Consumer<? super T>)
+  Line 120) getInterfaces() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getInterfaces()
+  Line 120) interf.getTypeDeclaration().getAllFields().forEach(f -> {
+    fields.add(f);
+}) ==> java.lang.Iterable.forEach(java.util.function.Consumer<? super T>)
+  Line 120) interf.getTypeDeclaration().getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 120) interf.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 121) fields.add(f) ==> java.util.ArrayList.add(E)
+  Line 132) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getContext()
+  Line 133) ctx.solveMethod(name, parameterTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 138) JavaParserFactory.getContext(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 147) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 147) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 152) wrappedNode.getExtendedTypes().isEmpty() ==> com.github.javaparser.ast.NodeList.isEmpty()
+  Line 152) wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 153) object() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.object()
+  Line 155) toReferenceType(wrappedNode.getExtendedTypes().get(0)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 155) wrappedNode.getExtendedTypes().get(0) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 155) wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 162) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 163) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 164) interfaces.add(toReferenceType(t)) ==> java.util.List.add(E)
+  Line 164) toReferenceType(t) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 173) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 176) declared.add(new JavaParserConstructorDeclaration(this, constructorDeclaration, typeSolver)) ==> java.util.List.add(E)
+  Line 179) declared.isEmpty() ==> java.util.List.isEmpty()
+  Line 181) ImmutableList.of(new DefaultConstructorDeclaration(this)) ==> com.google.common.collect.ImmutableList.of(E)
+  Line 189) wrappedNode.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName) ==> java.lang.String.equals(java.lang.Object)
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 190) annotationExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 190) annotationExpr.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 199) wrappedNode.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 204) javaParserTypeAdapter.getPackageName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getPackageName()
+  Line 209) javaParserTypeAdapter.getClassName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getClassName()
+  Line 214) javaParserTypeAdapter.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getQualifiedName()
+  Line 219) javaParserTypeAdapter.isAssignableBy(other) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 224) javaParserTypeAdapter.isAssignableBy(type) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 230) this.getQualifiedName().equals(other.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 230) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getQualifiedName()
+  Line 230) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 233) getSuperClass().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 233) getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getSuperClass()
+  Line 236) Object.class.getCanonicalName().equals(superclass.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 236) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 236) superclass.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 239) superclass.canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 244) this.wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 245) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 246) new SymbolSolver(typeSolver).solveType(type) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveType(com.github.javaparser.ast.type.Type)
+  Line 247) ancestor.canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 263) this.wrappedNode.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 263) this.wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 263) this.wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 264) SymbolReference.solved(this) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 266) javaParserTypeAdapter.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 267) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 271) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 272) name.startsWith(prefix) ==> java.lang.String.startsWith(java.lang.String)
+  Line 272) name.length() ==> java.lang.String.length()
+  Line 272) prefix.length() ==> java.lang.String.length()
+  Line 273) new JavaParserClassDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length()), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 273) name.substring(prefix.length()) ==> java.lang.String.substring(int)
+  Line 273) prefix.length() ==> java.lang.String.length()
+  Line 276) getContext().getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 276) getContext().getParent() ==> com.github.javaparser.symbolsolver.core.resolution.Context.getParent()
+  Line 276) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getContext()
+  Line 282) getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getSuperClass()
+  Line 284) ancestors.add(superclass) ==> java.util.List.add(E)
+  Line 286) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 287) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 288) toReferenceType(implemented) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 289) ancestors.add(ancestor) ==> java.util.List.add(E)
+  Line 298) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 300) methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver)) ==> java.util.Set.add(E)
+  Line 308) this.wrappedNode.getTypeParameters().stream().map((tp) -> new JavaParserTypeParameter(tp, typeSolver)).collect(Collectors.toList()) ==> ERROR
+  Line 308) this.wrappedNode.getTypeParameters().stream().map((tp) -> new JavaParserTypeParameter(tp, typeSolver)) ==> ERROR
+  Line 308) this.wrappedNode.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 308) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 310) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 324) Helper.toAccessLevel(wrappedNode.getModifiers()) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.toAccessLevel(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 324) wrappedNode.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 333) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 333) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 339) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 341) res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member)) ==> java.util.Set.add(E)
+  Line 341) JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 341) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 349) javaParserTypeAdapter.containerType() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.containerType()
+  Line 357) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 357) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 358) classOrInterfaceType.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 358) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 360) classOrInterfaceType.getScope().get().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 360) classOrInterfaceType.getScope().get() ==> java.util.Optional.get()
+  Line 360) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 362) solveType(className, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 363) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 364) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 365) localScope.isPresent() ==> java.util.Optional.isPresent()
+  Line 366) localScope.get().getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 366) localScope.get().getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 366) localScope.get() ==> java.util.Optional.get()
+  Line 366) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 366) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 367) solveType(localName, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 370) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 371) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 371) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 373) classOrInterfaceType.getTypeArguments().isPresent() ==> java.util.Optional.isPresent()
+  Line 373) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 374) ref.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 374) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 376) classOrInterfaceType.getTypeArguments().get().stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))).collect(Collectors.toList()) ==> ERROR
+  Line 376) classOrInterfaceType.getTypeArguments().get().stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))) ==> ERROR
+  Line 376) classOrInterfaceType.getTypeArguments().get().stream() ==> java.util.Collection.stream()
+  Line 376) classOrInterfaceType.getTypeArguments().get() ==> java.util.Optional.get()
+  Line 376) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 377) JavaParserFacade.get(typeSolver).convert(ta, ta) ==> ERROR
+  Line 377) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 378) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 379) ref.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 379) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserClassDeclaration_J9.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserClassDeclaration_J9.txt
new file mode 100644
index 0000000..df92d78
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserClassDeclaration_J9.txt
@@ -0,0 +1,139 @@
+  Line 64) wrappedNode.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 79) getClass() ==> java.lang.Object.getClass()
+  Line 79) o.getClass() ==> java.lang.Object.getClass()
+  Line 83) wrappedNode.equals(that.wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 90) wrappedNode.hashCode() ==> com.github.javaparser.ast.Node.hashCode()
+  Line 107) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 110) field.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 111) fields.add(new JavaParserFieldDeclaration(vd, typeSolver)) ==> java.util.ArrayList.add(E)
+  Line 116) this.getSuperClass().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 116) this.getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getSuperClass()
+  Line 118) fields.addAll(superclass.getAllFields()) ==> java.util.ArrayList.addAll(java.util.Collection<? extends E>)
+  Line 118) superclass.getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 120) getInterfaces().forEach(interf -> interf.getTypeDeclaration().getAllFields().forEach(f -> {
+    fields.add(f);
+})) ==> java.lang.Iterable.forEach(java.util.function.Consumer<? super T>)
+  Line 120) getInterfaces() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getInterfaces()
+  Line 120) interf.getTypeDeclaration().getAllFields().forEach(f -> {
+    fields.add(f);
+}) ==> java.lang.Iterable.forEach(java.util.function.Consumer<? super T>)
+  Line 120) interf.getTypeDeclaration().getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 120) interf.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 121) fields.add(f) ==> java.util.ArrayList.add(E)
+  Line 132) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getContext()
+  Line 133) ctx.solveMethod(name, parameterTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 138) JavaParserFactory.getContext(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 147) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 147) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 152) wrappedNode.getExtendedTypes().isEmpty() ==> com.github.javaparser.ast.NodeList.isEmpty()
+  Line 152) wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 153) object() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.object()
+  Line 155) toReferenceType(wrappedNode.getExtendedTypes().get(0)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 155) wrappedNode.getExtendedTypes().get(0) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 155) wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 162) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 163) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 164) interfaces.add(toReferenceType(t)) ==> java.util.List.add(E)
+  Line 164) toReferenceType(t) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 173) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 176) declared.add(new JavaParserConstructorDeclaration(this, constructorDeclaration, typeSolver)) ==> java.util.List.add(E)
+  Line 179) declared.isEmpty() ==> java.util.List.isEmpty()
+  Line 181) ImmutableList.of(new DefaultConstructorDeclaration(this)) ==> java.util.List.of(E...)
+  Line 189) wrappedNode.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName) ==> java.lang.String.equals(java.lang.Object)
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 190) solveType(annotationExpr.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 190) annotationExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 190) annotationExpr.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 199) wrappedNode.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 204) javaParserTypeAdapter.getPackageName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getPackageName()
+  Line 209) javaParserTypeAdapter.getClassName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getClassName()
+  Line 214) javaParserTypeAdapter.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getQualifiedName()
+  Line 219) javaParserTypeAdapter.isAssignableBy(other) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 224) javaParserTypeAdapter.isAssignableBy(type) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 230) this.getQualifiedName().equals(other.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 230) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getQualifiedName()
+  Line 230) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 233) getSuperClass().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 233) getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getSuperClass()
+  Line 236) Object.class.getCanonicalName().equals(superclass.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 236) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 236) superclass.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 239) superclass.canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 244) this.wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 245) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 246) new SymbolSolver(typeSolver).solveType(type) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveType(com.github.javaparser.ast.type.Type)
+  Line 247) ancestor.canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 263) this.wrappedNode.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 263) this.wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 263) this.wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 264) SymbolReference.solved(this) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 266) javaParserTypeAdapter.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 267) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 271) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 272) name.startsWith(prefix) ==> java.lang.String.startsWith(java.lang.String)
+  Line 272) name.length() ==> java.lang.String.length()
+  Line 272) prefix.length() ==> java.lang.String.length()
+  Line 273) new JavaParserClassDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length()), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 273) name.substring(prefix.length()) ==> java.lang.String.substring(int)
+  Line 273) prefix.length() ==> java.lang.String.length()
+  Line 276) getContext().getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 276) getContext().getParent() ==> com.github.javaparser.symbolsolver.core.resolution.Context.getParent()
+  Line 276) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getContext()
+  Line 282) getSuperClass() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getSuperClass()
+  Line 284) ancestors.add(superclass) ==> java.util.List.add(E)
+  Line 286) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 287) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 288) toReferenceType(implemented) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 289) ancestors.add(ancestor) ==> java.util.List.add(E)
+  Line 298) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 300) methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver)) ==> java.util.Set.add(E)
+  Line 308) this.wrappedNode.getTypeParameters().stream().map((tp) -> new JavaParserTypeParameter(tp, typeSolver)).collect(Collectors.toList()) ==> ERROR
+  Line 308) this.wrappedNode.getTypeParameters().stream().map((tp) -> new JavaParserTypeParameter(tp, typeSolver)) ==> ERROR
+  Line 308) this.wrappedNode.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 308) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 310) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 324) Helper.toAccessLevel(wrappedNode.getModifiers()) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.toAccessLevel(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 324) wrappedNode.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 333) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 333) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 339) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 341) res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member)) ==> java.util.Set.add(E)
+  Line 341) JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 341) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 349) javaParserTypeAdapter.containerType() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.containerType()
+  Line 357) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 357) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 358) classOrInterfaceType.getScope().isPresent() ==> java.util.Optional.isPresent()
+  Line 358) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 360) classOrInterfaceType.getScope().get().toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 360) classOrInterfaceType.getScope().get() ==> java.util.Optional.get()
+  Line 360) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 362) solveType(className, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 363) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 364) classOrInterfaceType.getScope() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getScope()
+  Line 365) localScope.isPresent() ==> java.util.Optional.isPresent()
+  Line 366) localScope.get().getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 366) localScope.get().getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 366) localScope.get() ==> java.util.Optional.get()
+  Line 366) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 366) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 367) solveType(localName, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 370) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 371) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 371) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 373) classOrInterfaceType.getTypeArguments().isPresent() ==> java.util.Optional.isPresent()
+  Line 373) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 374) ref.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 374) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 376) classOrInterfaceType.getTypeArguments().get().stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))).collect(Collectors.toList()) ==> ERROR
+  Line 376) classOrInterfaceType.getTypeArguments().get().stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))) ==> ERROR
+  Line 376) classOrInterfaceType.getTypeArguments().get().stream() ==> java.util.Collection.stream()
+  Line 376) classOrInterfaceType.getTypeArguments().get() ==> java.util.Optional.get()
+  Line 376) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 377) JavaParserFacade.get(typeSolver).convert(ta, ta) ==> ERROR
+  Line 377) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 378) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 379) ref.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 379) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserConstructorDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserConstructorDeclaration.txt
new file mode 100644
index 0000000..5bbbf3e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserConstructorDeclaration.txt
@@ -0,0 +1,15 @@
+  Line 48) this.wrappedNode.getParameters().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 48) this.wrappedNode.getParameters() ==> com.github.javaparser.ast.body.CallableDeclaration.getParameters()
+  Line 53) getNumberOfParams() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserConstructorDeclaration.getNumberOfParams()
+  Line 54) String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 54) getNumberOfParams() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserConstructorDeclaration.getNumberOfParams()
+  Line 56) wrappedNode.getParameters().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 56) wrappedNode.getParameters() ==> com.github.javaparser.ast.body.CallableDeclaration.getParameters()
+  Line 61) this.classDeclaration.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 75) Helper.toAccessLevel(wrappedNode.getModifiers()) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.toAccessLevel(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 75) wrappedNode.getModifiers() ==> com.github.javaparser.ast.body.CallableDeclaration.getModifiers()
+  Line 80) this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)).collect(Collectors.toList()) ==> ERROR
+  Line 80) this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)) ==> ERROR
+  Line 80) this.wrappedNode.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 80) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.body.CallableDeclaration.getTypeParameters()
+  Line 80) Collectors.toList() ==> java.util.stream.Collectors.toList()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserEnumConstantDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserEnumConstantDeclaration.txt
new file mode 100644
index 0000000..6cb9132
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserEnumConstantDeclaration.txt
@@ -0,0 +1,3 @@
+  Line 42) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 47) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 47) wrappedNode.getName() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserEnumDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserEnumDeclaration.txt
new file mode 100644
index 0000000..6abb39d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserEnumDeclaration.txt
@@ -0,0 +1,71 @@
+  Line 69) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 71) methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver)) ==> java.util.Set.add(E)
+  Line 78) JavaParserFactory.getContext(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 83) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 83) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 109) other.getQualifiedName().equals(this.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 109) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 109) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.getQualifiedName()
+  Line 112) other.getQualifiedName().equals(Enum.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 112) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 112) Enum.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 116) other.getQualifiedName().equals(Comparable.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 116) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 116) Comparable.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 119) other.getQualifiedName().equals(Serializable.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 119) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 119) Serializable.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 122) other.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 122) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 122) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 140) javaParserTypeAdapter.getPackageName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getPackageName()
+  Line 145) javaParserTypeAdapter.getClassName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getClassName()
+  Line 150) javaParserTypeAdapter.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getQualifiedName()
+  Line 155) javaParserTypeAdapter.isAssignableBy(other) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 160) javaParserTypeAdapter.isAssignableBy(type) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 171) getClass() ==> java.lang.Object.getClass()
+  Line 171) o.getClass() ==> java.lang.Object.getClass()
+  Line 175) wrappedNode.equals(that.wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 182) wrappedNode.hashCode() ==> com.github.javaparser.ast.Node.hashCode()
+  Line 187) name.equals("values") ==> java.lang.String.equals(java.lang.Object)
+  Line 187) parameterTypes.isEmpty() ==> java.util.List.isEmpty()
+  Line 188) Optional.of(new ValuesMethod(this, typeSolver).getUsage(null)) ==> java.util.Optional.of(T)
+  Line 188) new ValuesMethod(this, typeSolver).getUsage(null) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.ValuesMethod.getUsage(com.github.javaparser.ast.Node)
+  Line 191) getContext().solveMethodAsUsage(name, parameterTypes, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 191) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.getContext()
+  Line 197) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 198) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 201) field.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 202) fields.add(new JavaParserFieldDeclaration(vd, typeSolver)) ==> java.util.ArrayList.add(E)
+  Line 208) this.wrappedNode.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 209) this.wrappedNode.getEntries() ==> com.github.javaparser.ast.body.EnumDeclaration.getEntries()
+  Line 210) fields.add(new JavaParserFieldDeclaration(member, typeSolver)) ==> java.util.ArrayList.add(E)
+  Line 220) ReflectionFactory.typeUsageFor(Enum.class, typeSolver).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 220) ReflectionFactory.typeUsageFor(Enum.class, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 221) enumClass.getTypeDeclaration().getTypeParameters().get(0) ==> java.util.List.get(int)
+  Line 221) enumClass.getTypeDeclaration().getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 221) enumClass.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 222) enumClass.deriveTypeParameters(new TypeParametersMap.Builder().setValue(eTypeParameter, new ReferenceTypeImpl(this, typeSolver)).build()) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.deriveTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap)
+  Line 222) new TypeParametersMap.Builder().setValue(eTypeParameter, new ReferenceTypeImpl(this, typeSolver)).build() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.Builder.build()
+  Line 222) new TypeParametersMap.Builder().setValue(eTypeParameter, new ReferenceTypeImpl(this, typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.Builder.setValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 223) ancestors.add(enumClass) ==> java.util.List.add(E)
+  Line 224) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplementedTypes()
+  Line 225) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.EnumDeclaration.getImplementedTypes()
+  Line 226) new SymbolSolver(typeSolver).solveTypeInType(this, implementedType.getName().getId()) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveTypeInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String)
+  Line 226) implementedType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 226) implementedType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 227) implementedDeclRef.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 228) implementedType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 228) implementedType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 230) ancestors.add(new ReferenceTypeImpl((ReferenceTypeDeclaration) implementedDeclRef.getCorrespondingDeclaration(), typeSolver)) ==> java.util.List.add(E)
+  Line 230) implementedDeclRef.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 238) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 311) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 316) Helper.toAccessLevel(enumDeclaration.getWrappedNode().getModifiers()) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.toAccessLevel(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 316) enumDeclaration.getWrappedNode().getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 316) enumDeclaration.getWrappedNode() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.getWrappedNode()
+  Line 328) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 330) res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member)) ==> java.util.Set.add(E)
+  Line 330) JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 330) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 338) javaParserTypeAdapter.containerType() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.containerType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserFieldDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserFieldDeclaration.txt
new file mode 100644
index 0000000..1c2fe0c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserFieldDeclaration.txt
@@ -0,0 +1,23 @@
+  Line 51) getParentNode(variableDeclarator) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 52) getParentNode(variableDeclarator).getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 52) getParentNode(variableDeclarator).getClass() ==> java.lang.Object.getClass()
+  Line 52) getParentNode(variableDeclarator) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 54) getParentNode(variableDeclarator) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 68) getParentNode(enumConstantDeclaration) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 71) JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 71) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 71) variableDeclarator.getType() ==> com.github.javaparser.ast.body.VariableDeclarator.getType()
+  Line 79) enumConstantDeclaration.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 79) enumConstantDeclaration.getName() ==> com.github.javaparser.ast.body.EnumConstantDeclaration.getName()
+  Line 81) variableDeclarator.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 81) variableDeclarator.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 87) wrappedNode.getModifiers().contains(Modifier.STATIC) ==> java.util.AbstractCollection.contains(java.lang.Object)
+  Line 87) wrappedNode.getModifiers() ==> com.github.javaparser.ast.body.FieldDeclaration.getModifiers()
+  Line 106) getName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserFieldDeclaration.getName()
+  Line 111) Helper.toAccessLevel(wrappedNode.getModifiers()) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.toAccessLevel(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 111) wrappedNode.getModifiers() ==> com.github.javaparser.ast.body.FieldDeclaration.getModifiers()
+  Line 116) Navigator.findAncestor(wrappedNode, com.github.javaparser.ast.body.TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findAncestor(com.github.javaparser.ast.Node, java.lang.Class<N>)
+  Line 117) typeDeclaration.isPresent() ==> java.util.Optional.isPresent()
+  Line 118) JavaParserFacade.get(typeSolver).getTypeDeclaration(typeDeclaration.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 118) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 118) typeDeclaration.get() ==> java.util.Optional.get()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserInterfaceDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserInterfaceDeclaration.txt
new file mode 100644
index 0000000..02a1607
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserInterfaceDeclaration.txt
@@ -0,0 +1,120 @@
+  Line 52) wrappedNode.isInterface() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.isInterface()
+  Line 63) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 65) methods.add(new JavaParserMethodDeclaration((com.github.javaparser.ast.body.MethodDeclaration) member, typeSolver)) ==> java.util.Set.add(E)
+  Line 72) JavaParserFactory.getContext(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 82) getClass() ==> java.lang.Object.getClass()
+  Line 82) o.getClass() ==> java.lang.Object.getClass()
+  Line 86) wrappedNode.equals(that.wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 93) wrappedNode.hashCode() ==> com.github.javaparser.ast.Node.hashCode()
+  Line 98) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 98) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 108) wrappedNode.getAnnotations() ==> com.github.javaparser.ast.body.BodyDeclaration.getAnnotations()
+  Line 109) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName().equals(canonicalName) ==> java.lang.String.equals(java.lang.Object)
+  Line 109) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 109) solveType(annotationExpr.getName().getId(), typeSolver).getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 109) solveType(annotationExpr.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 109) annotationExpr.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 109) annotationExpr.getName() ==> com.github.javaparser.ast.expr.AnnotationExpr.getName()
+  Line 124) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 125) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 126) interfaces.add(new ReferenceTypeImpl(solveType(t.getName().getId(), typeSolver).getCorrespondingDeclaration().asInterface(), typeSolver)) ==> java.util.List.add(E)
+  Line 126) solveType(t.getName().getId(), typeSolver).getCorrespondingDeclaration().asInterface() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asInterface()
+  Line 126) solveType(t.getName().getId(), typeSolver).getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 126) solveType(t.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 126) t.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 126) t.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 134) javaParserTypeAdapter.getPackageName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getPackageName()
+  Line 139) javaParserTypeAdapter.getClassName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getClassName()
+  Line 144) javaParserTypeAdapter.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getQualifiedName()
+  Line 149) javaParserTypeAdapter.isAssignableBy(other) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 154) javaParserTypeAdapter.isAssignableBy(type) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 160) this.getQualifiedName().equals(other.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 160) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.getQualifiedName()
+  Line 160) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 163) this.wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 164) wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 165) new SymbolSolver(typeSolver).solveType(type) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveType(com.github.javaparser.ast.type.Type)
+  Line 166) ancestor.canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 172) this.wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 173) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 174) new SymbolSolver(typeSolver).solveType(type) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveType(com.github.javaparser.ast.type.Type)
+  Line 175) ancestor.canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 192) wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 195) field.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 196) fields.add(new JavaParserFieldDeclaration(vd, typeSolver)) ==> java.util.ArrayList.add(E)
+  Line 201) getAncestors().forEach(a -> {
+    if (a.getTypeDeclaration() != this) {
+        fields.addAll(a.getTypeDeclaration().getAllFields());
+    }
+}) ==> java.lang.Iterable.forEach(java.util.function.Consumer<? super T>)
+  Line 201) getAncestors() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.getAncestors()
+  Line 202) a.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 203) fields.addAll(a.getTypeDeclaration().getAllFields()) ==> java.util.ArrayList.addAll(java.util.Collection<? extends E>)
+  Line 203) a.getTypeDeclaration().getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 203) a.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 220) this.wrappedNode.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 220) this.wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 220) this.wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 221) SymbolReference.solved(this) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 223) javaParserTypeAdapter.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 224) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 228) wrappedNode.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 229) name.startsWith(prefix) ==> java.lang.String.startsWith(java.lang.String)
+  Line 229) name.length() ==> java.lang.String.length()
+  Line 229) prefix.length() ==> java.lang.String.length()
+  Line 230) new JavaParserInterfaceDeclaration(this.wrappedNode, typeSolver).solveType(name.substring(prefix.length()), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 230) name.substring(prefix.length()) ==> java.lang.String.substring(int)
+  Line 230) prefix.length() ==> java.lang.String.length()
+  Line 233) getContext().getParent().solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 233) getContext().getParent() ==> com.github.javaparser.symbolsolver.core.resolution.Context.getParent()
+  Line 233) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.getContext()
+  Line 239) wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 240) wrappedNode.getExtendedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getExtendedTypes()
+  Line 241) ancestors.add(toReferenceType(extended)) ==> java.util.List.add(E)
+  Line 241) toReferenceType(extended) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 244) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 245) wrappedNode.getImplementedTypes() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getImplementedTypes()
+  Line 246) ancestors.add(toReferenceType(implemented)) ==> java.util.List.add(E)
+  Line 246) toReferenceType(implemented) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.toReferenceType(com.github.javaparser.ast.type.ClassOrInterfaceType)
+  Line 254) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 255) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 257) this.wrappedNode.getTypeParameters().stream().map((tp) -> new JavaParserTypeParameter(tp, typeSolver)).collect(Collectors.toList()) ==> ERROR
+  Line 257) this.wrappedNode.getTypeParameters().stream().map((tp) -> new JavaParserTypeParameter(tp, typeSolver)) ==> ERROR
+  Line 257) this.wrappedNode.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 257) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.getTypeParameters()
+  Line 259) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 274) Helper.toAccessLevel(wrappedNode.getModifiers()) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.toAccessLevel(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 274) wrappedNode.getModifiers() ==> com.github.javaparser.ast.body.TypeDeclaration.getModifiers()
+  Line 280) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.body.TypeDeclaration.getMembers()
+  Line 282) res.add(JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member)) ==> java.util.Set.add(E)
+  Line 282) JavaParserFacade.get(typeSolver).getTypeDeclaration((com.github.javaparser.ast.body.TypeDeclaration) member) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 282) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 290) javaParserTypeAdapter.containerType() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.containerType()
+  Line 299) classOrInterfaceType.toString().indexOf('.') ==> java.lang.String.indexOf(int)
+  Line 299) classOrInterfaceType.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 300) typeSolver.tryToSolveType(classOrInterfaceType.toString()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 300) classOrInterfaceType.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 302) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 303) solveType(classOrInterfaceType.toString(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 303) classOrInterfaceType.toString() ==> com.github.javaparser.ast.Node.toString()
+  Line 305) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 306) solveType(classOrInterfaceType.getName().getId(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 306) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 306) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 308) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 309) classOrInterfaceType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 309) classOrInterfaceType.getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 311) classOrInterfaceType.getTypeArguments().isPresent() ==> java.util.Optional.isPresent()
+  Line 311) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 312) ref.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 312) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 314) classOrInterfaceType.getTypeArguments().get().stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))).collect(Collectors.toList()) ==> ERROR
+  Line 314) classOrInterfaceType.getTypeArguments().get().stream().map(ta -> new LazyType(v -> JavaParserFacade.get(typeSolver).convert(ta, ta))) ==> ERROR
+  Line 314) classOrInterfaceType.getTypeArguments().get().stream() ==> java.util.Collection.stream()
+  Line 314) classOrInterfaceType.getTypeArguments().get() ==> java.util.Optional.get()
+  Line 314) classOrInterfaceType.getTypeArguments() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getTypeArguments()
+  Line 315) JavaParserFacade.get(typeSolver).convert(ta, ta) ==> ERROR
+  Line 315) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 316) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 317) ref.getCorrespondingDeclaration().asReferenceType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asReferenceType()
+  Line 317) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserMethodDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserMethodDeclaration.txt
new file mode 100644
index 0000000..7efa56d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserMethodDeclaration.txt
@@ -0,0 +1,30 @@
+  Line 58) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 59) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 62) JavaParserFactory.toTypeDeclaration(getParentNode(wrappedNode), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.toTypeDeclaration(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 62) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 68) JavaParserFacade.get(typeSolver).convert(wrappedNode.getType(), getContext()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 68) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 68) wrappedNode.getType() ==> com.github.javaparser.ast.body.MethodDeclaration.getType()
+  Line 68) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration.getContext()
+  Line 73) wrappedNode.getParameters().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 73) wrappedNode.getParameters() ==> com.github.javaparser.ast.body.CallableDeclaration.getParameters()
+  Line 78) getNumberOfParams() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration.getNumberOfParams()
+  Line 79) String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 79) getNumberOfParams() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration.getNumberOfParams()
+  Line 81) wrappedNode.getParameters().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 81) wrappedNode.getParameters() ==> com.github.javaparser.ast.body.CallableDeclaration.getParameters()
+  Line 89) new MethodDeclarationCommonLogic(this, typeSolver).resolveTypeVariables(context, parameterTypes) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 93) JavaParserFactory.getContext(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 98) wrappedNode.getBody().isPresent() ==> java.util.Optional.isPresent()
+  Line 98) wrappedNode.getBody() ==> com.github.javaparser.ast.body.MethodDeclaration.getBody()
+  Line 103) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 103) wrappedNode.getName() ==> com.github.javaparser.ast.body.CallableDeclaration.getName()
+  Line 123) this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)).collect(Collectors.toList()) ==> ERROR
+  Line 123) this.wrappedNode.getTypeParameters().stream().map((astTp) -> new JavaParserTypeParameter(astTp, typeSolver)) ==> ERROR
+  Line 123) this.wrappedNode.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 123) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.body.CallableDeclaration.getTypeParameters()
+  Line 123) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 128) wrappedNode.isDefault() ==> com.github.javaparser.ast.body.MethodDeclaration.isDefault()
+  Line 133) wrappedNode.isStatic() ==> com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier.isStatic()
+  Line 147) Helper.toAccessLevel(wrappedNode.getModifiers()) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.toAccessLevel(java.util.EnumSet<com.github.javaparser.ast.Modifier>)
+  Line 147) wrappedNode.getModifiers() ==> com.github.javaparser.ast.body.CallableDeclaration.getModifiers()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserParameterDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserParameterDeclaration.txt
new file mode 100644
index 0000000..73d6dc4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserParameterDeclaration.txt
@@ -0,0 +1,7 @@
+  Line 41) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 41) wrappedNode.getName() ==> com.github.javaparser.ast.body.Parameter.getName()
+  Line 56) wrappedNode.isVarArgs() ==> com.github.javaparser.ast.body.Parameter.isVarArgs()
+  Line 66) JavaParserFacade.get(typeSolver).convert(wrappedNode.getType(), wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 66) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 66) wrappedNode.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 67) isVariadic() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserParameterDeclaration.isVariadic()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserSymbolDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserSymbolDeclaration.txt
new file mode 100644
index 0000000..29350ee
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserSymbolDeclaration.txt
@@ -0,0 +1,46 @@
+  Line 67) variableDeclarator.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 67) variableDeclarator.getName() ==> com.github.javaparser.ast.body.VariableDeclarator.getName()
+  Line 72) getParentNode(parameter).getChildNodes() ==> com.github.javaparser.ast.Node.getChildNodes()
+  Line 72) getParentNode(parameter) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 83) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 84) getParentNode(node) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 85) call.getArguments().size() ==> com.github.javaparser.ast.NodeList.size()
+  Line 85) call.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 86) call.getArguments().get(i) ==> com.github.javaparser.ast.NodeList.get(int)
+  Line 86) call.getArguments() ==> com.github.javaparser.ast.expr.MethodCallExpr.getArguments()
+  Line 126) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 127) getParamPos(parameter) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.getParamPos(com.github.javaparser.ast.body.Parameter)
+  Line 128) JavaParserFacade.get(typeSolver).getType(getParentNode(wrappedNode)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(com.github.javaparser.ast.Node)
+  Line 128) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 128) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 133) wrappedNode.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 133) wrappedNode.getClass() ==> java.lang.Object.getClass()
+  Line 136) parameter.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 137) PrimitiveType.byName(((com.github.javaparser.ast.type.PrimitiveType) parameter.getType()).getType().name()) ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.byName(java.lang.String)
+  Line 137) ((com.github.javaparser.ast.type.PrimitiveType) parameter.getType()).getType().name() ==> java.lang.Enum.name()
+  Line 137) ((com.github.javaparser.ast.type.PrimitiveType) parameter.getType()).getType() ==> com.github.javaparser.ast.type.PrimitiveType.getType()
+  Line 137) parameter.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 139) JavaParserFacade.get(typeSolver).convertToUsage(parameter.getType(), wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 139) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 139) parameter.getType() ==> com.github.javaparser.ast.body.Parameter.getType()
+  Line 141) parameter.isVarArgs() ==> com.github.javaparser.ast.body.Parameter.isVarArgs()
+  Line 149) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 150) JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), JavaParserFactory.getContext(wrappedNode, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 150) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 150) variableDeclarator.getType() ==> com.github.javaparser.ast.body.VariableDeclarator.getType()
+  Line 150) JavaParserFactory.getContext(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 152) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 153) JavaParserFacade.get(typeSolver).convert(variableDeclarator.getType(), JavaParserFactory.getContext(wrappedNode, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(com.github.javaparser.ast.type.Type, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 153) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 153) variableDeclarator.getType() ==> com.github.javaparser.ast.body.VariableDeclarator.getType()
+  Line 153) JavaParserFactory.getContext(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 155) getParentNode(wrappedNode).getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 155) getParentNode(wrappedNode).getClass() ==> java.lang.Object.getClass()
+  Line 155) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 158) wrappedNode.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 158) wrappedNode.getClass() ==> java.lang.Object.getClass()
+  Line 164) this.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 164) this.getClass() ==> java.lang.Object.getClass()
+  Line 164) this.getWrappedNode().getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 164) this.getWrappedNode().getClass() ==> java.lang.Object.getClass()
+  Line 164) this.getWrappedNode() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.getWrappedNode()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeAdapter.txt
new file mode 100644
index 0000000..b9da1dc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeAdapter.txt
@@ -0,0 +1,48 @@
+  Line 39) Helper.getPackageName(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getPackageName(com.github.javaparser.ast.Node)
+  Line 43) Helper.getClassName("", wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 47) Helper.containerName(getParentNode(wrappedNode)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.containerName(com.github.javaparser.ast.Node)
+  Line 47) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 48) containerName.isEmpty() ==> java.lang.String.isEmpty()
+  Line 49) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 49) wrappedNode.getName() ==> com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.getName()
+  Line 51) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 51) wrappedNode.getName() ==> com.github.javaparser.ast.nodeTypes.NodeWithSimpleName.getName()
+  Line 56) other.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllAncestors()
+  Line 57) ancestorsOfOther.add(new ReferenceTypeImpl(other, typeSolver)) ==> java.util.List.add(E)
+  Line 59) ancestorOfOther.getQualifiedName().equals(this.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 59) ancestorOfOther.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 59) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.getQualifiedName()
+  Line 67) type.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 70) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 71) typeSolver.solveType(type.describe()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 71) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 72) isAssignableBy(other) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 79) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.getTypeParameters()
+  Line 80) this.wrappedNode.getTypeParameters() ==> com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters.getTypeParameters()
+  Line 81) typeParameter.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 81) typeParameter.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 81) typeParameter.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 82) SymbolReference.solved(new JavaParserTypeVariableDeclaration(typeParameter, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 88) this.wrappedNode.getMembers() ==> com.github.javaparser.ast.nodeTypes.NodeWithMembers.getMembers()
+  Line 91) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 92) internalType.getName().getId().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 92) internalType.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 92) internalType.getName() ==> com.github.javaparser.ast.body.TypeDeclaration.getName()
+  Line 94) SymbolReference.solved(new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 96) SymbolReference.solved(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 100) name.startsWith(prefix) ==> java.lang.String.startsWith(java.lang.String)
+  Line 100) name.length() ==> java.lang.String.length()
+  Line 100) prefix.length() ==> java.lang.String.length()
+  Line 102) new JavaParserClassDeclaration((com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) internalType, typeSolver).solveType(name.substring(prefix.length()), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 102) name.substring(prefix.length()) ==> java.lang.String.substring(int)
+  Line 102) prefix.length() ==> java.lang.String.length()
+  Line 104) new SymbolSolver(typeSolver).solveTypeInType(new JavaParserEnumDeclaration((com.github.javaparser.ast.body.EnumDeclaration) internalType, typeSolver), name.substring(prefix.length())) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveTypeInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String)
+  Line 104) name.substring(prefix.length()) ==> java.lang.String.substring(int)
+  Line 104) prefix.length() ==> java.lang.String.length()
+  Line 111) SymbolReference.unsolved(TypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 115) wrappedNode.getParentNode() ==> com.github.javaparser.ast.Node.getParentNode()
+  Line 116) parent.isPresent() ==> java.util.Optional.isPresent()
+  Line 117) Optional.of(JavaParserFactory.toTypeDeclaration(parent.get(), typeSolver)) ==> java.util.Optional.of(T)
+  Line 117) JavaParserFactory.toTypeDeclaration(parent.get(), typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.toTypeDeclaration(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 117) parent.get() ==> java.util.Optional.get()
+  Line 118) Optional.empty() ==> java.util.Optional.empty()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeParameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeParameter.txt
new file mode 100644
index 0000000..da6454b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeParameter.txt
@@ -0,0 +1,45 @@
+  Line 56) Collections.emptySet() ==> java.util.Collections.emptySet()
+  Line 60) getContext().solveMethod(name, parameterTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 60) getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter.getContext()
+  Line 70) wrappedNode.equals(that.wrappedNode) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 77) wrappedNode.hashCode() ==> com.github.javaparser.ast.Node.hashCode()
+  Line 78) typeSolver.hashCode() ==> java.lang.Object.hashCode()
+  Line 84) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 84) wrappedNode.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 89) isAssignableBy(new ReferenceTypeImpl(other, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 94) getContainer() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter.getContainer()
+  Line 96) ((ReferenceTypeDeclaration) container).getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 98) ((JavaParserConstructorDeclaration) container).getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 100) ((JavaParserMethodDeclaration) container).getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 106) getContainer() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter.getContainer()
+  Line 108) ((ReferenceTypeDeclaration) container).getId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getId()
+  Line 110) ((JavaParserConstructorDeclaration) container).getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 112) ((JavaParserMethodDeclaration) container).getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 118) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 121) JavaParserFacade.get(typeSolver).getTypeDeclaration(jpTypeDeclaration) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 121) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 124) jpConstructorDeclaration.getAncestorOfType(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.class) ==> com.github.javaparser.HasParentNode.getAncestorOfType(java.lang.Class<N>)
+  Line 125) jpTypeDeclaration.isPresent() ==> java.util.Optional.isPresent()
+  Line 126) JavaParserFacade.get(typeSolver).getTypeDeclaration(jpTypeDeclaration.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)
+  Line 126) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 126) jpTypeDeclaration.get() ==> java.util.Optional.get()
+  Line 127) typeDeclaration.isClass() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isClass()
+  Line 128) typeDeclaration.asClass() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.asClass()
+  Line 140) String.format("%s.%s", getContainerQualifiedName(), getName()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 140) getContainerQualifiedName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter.getContainerQualifiedName()
+  Line 140) getName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter.getName()
+  Line 145) wrappedNode.getTypeBound().stream().map((astB) -> toBound(astB, typeSolver)).collect(Collectors.toList()) ==> ERROR
+  Line 145) wrappedNode.getTypeBound().stream().map((astB) -> toBound(astB, typeSolver)) ==> ERROR
+  Line 145) wrappedNode.getTypeBound().stream() ==> java.util.Collection.stream()
+  Line 145) wrappedNode.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 145) toBound(astB, typeSolver) ==> ERROR
+  Line 145) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 149) JavaParserFacade.get(typeSolver).convertToUsage(classOrInterfaceType, classOrInterfaceType) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(com.github.javaparser.ast.type.Type, com.github.javaparser.ast.Node)
+  Line 149) JavaParserFacade.get(typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 150) Bound.extendsBound(type) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 199) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 213) wrappedNode.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 213) wrappedNode.getTypeBound() ==> com.github.javaparser.ast.type.TypeParameter.getTypeBound()
+  Line 218) getContainer() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeParameter.getContainer()
+  Line 220) Optional.of((ReferenceTypeDeclaration) container) ==> java.util.Optional.of(T)
+  Line 222) Optional.empty() ==> java.util.Optional.empty()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeVariableDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeVariableDeclaration.txt
new file mode 100644
index 0000000..c02ccbc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarations_JavaParserTypeVariableDeclaration.txt
@@ -0,0 +1,13 @@
+  Line 54) isAssignableBy(new ReferenceTypeImpl(other, typeSolver)) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 59) Helper.getPackageName(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getPackageName(com.github.javaparser.ast.Node)
+  Line 64) Helper.getClassName("", wrappedNode) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.Helper.getClassName(java.lang.String, com.github.javaparser.ast.Node)
+  Line 69) getName() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration.getName()
+  Line 79) wrappedNode.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 93) type.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 94) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 127) Collections.emptySet() ==> java.util.Collections.emptySet()
+  Line 132) wrappedNode.getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 132) wrappedNode.getName() ==> com.github.javaparser.ast.type.TypeParameter.getName()
+  Line 167) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 185) asTypeParameter().containerType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.containerType()
+  Line 185) asTypeParameter() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration.asTypeParameter()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_AbstractSymbolDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_AbstractSymbolDeclarator.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_AbstractSymbolDeclarator.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_FieldSymbolDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_FieldSymbolDeclarator.txt
new file mode 100644
index 0000000..4d0f131
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_FieldSymbolDeclarator.txt
@@ -0,0 +1,3 @@
+  Line 40) wrappedNode.getVariables() ==> com.github.javaparser.ast.body.FieldDeclaration.getVariables()
+  Line 41) symbols.add(JavaParserSymbolDeclaration.field(v, typeSolver)) ==> java.util.List.add(E)
+  Line 41) JavaParserSymbolDeclaration.field(v, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.field(com.github.javaparser.ast.body.VariableDeclarator, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_NoSymbolDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_NoSymbolDeclarator.txt
new file mode 100644
index 0000000..f9460d3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_NoSymbolDeclarator.txt
@@ -0,0 +1 @@
+  Line 37) Collections.emptyList() ==> java.util.Collections.emptyList()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_ParameterSymbolDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_ParameterSymbolDeclarator.txt
new file mode 100644
index 0000000..dfdfce9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_ParameterSymbolDeclarator.txt
@@ -0,0 +1,2 @@
+  Line 39) symbols.add(JavaParserSymbolDeclaration.parameter(wrappedNode, typeSolver)) ==> java.util.List.add(E)
+  Line 39) JavaParserSymbolDeclaration.parameter(wrappedNode, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserSymbolDeclaration.parameter(com.github.javaparser.ast.body.Parameter, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_VariableSymbolDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_VariableSymbolDeclarator.txt
new file mode 100644
index 0000000..e0d28d3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javaparsermodel_declarators_VariableSymbolDeclarator.txt
@@ -0,0 +1,7 @@
+  Line 38) getParentNode(wrappedNode) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode(com.github.javaparser.ast.Node)
+  Line 45) wrappedNode.getVariables().stream().map(v -> JavaParserSymbolDeclaration.localVar(v, typeSolver)).collect(Collectors.toCollection(() -> new LinkedList<>())) ==> ERROR
+  Line 45) wrappedNode.getVariables().stream().map(v -> JavaParserSymbolDeclaration.localVar(v, typeSolver)) ==> ERROR
+  Line 45) wrappedNode.getVariables().stream() ==> java.util.Collection.stream()
+  Line 45) wrappedNode.getVariables() ==> com.github.javaparser.ast.expr.VariableDeclarationExpr.getVariables()
+  Line 46) JavaParserSymbolDeclaration.localVar(v, typeSolver) ==> ERROR
+  Line 48) Collectors.toCollection(() -> new LinkedList<>()) ==> java.util.stream.Collectors.toCollection(java.util.function.Supplier<C>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistClassDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistClassDeclaration.txt
new file mode 100644
index 0000000..ebeec81
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistClassDeclaration.txt
@@ -0,0 +1,128 @@
+  Line 59) ctClass.isInterface() ==> javassist.CtClass.isInterface()
+  Line 59) ctClass.isAnnotation() ==> javassist.CtClass.isAnnotation()
+  Line 59) ctClass.isPrimitive() ==> javassist.CtClass.isPrimitive()
+  Line 59) ctClass.isEnum() ==> javassist.CtClass.isEnum()
+  Line 60) ctClass.toString() ==> javassist.CtClass.toString()
+  Line 69) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 69) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 79) javassistTypeDeclarationAdapter.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getDeclaredMethods()
+  Line 84) isAssignableBy(new ReferenceTypeImpl(other, typeSolver)) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 90) getClass() ==> java.lang.Object.getClass()
+  Line 90) o.getClass() ==> java.lang.Object.getClass()
+  Line 94) ctClass.equals(that.ctClass) ==> java.lang.Object.equals(java.lang.Object)
+  Line 101) ctClass.hashCode() ==> java.lang.Object.hashCode()
+  Line 106) ctClass.getPackageName() ==> javassist.CtClass.getPackageName()
+  Line 111) ctClass.getName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 111) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 112) getPackageName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.getPackageName()
+  Line 113) className.substring(getPackageName().length() + 1, className.length()) ==> java.lang.String.substring(int, int)
+  Line 113) getPackageName().length() ==> java.lang.String.length()
+  Line 113) getPackageName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.getPackageName()
+  Line 113) className.length() ==> java.lang.String.length()
+  Line 120) ctClass.getName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 120) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 125) JavassistUtils.getMethodUsage(ctClass, name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.getMethodUsage(javassist.CtClass, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 130) ctClass.getDeclaredFields() ==> javassist.CtClass.getDeclaredFields()
+  Line 131) field.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 131) field.getName() ==> javassist.CtField.getName()
+  Line 132) SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 137) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 139) new JavassistClassDeclaration(superClass, typeSolver).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 140) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 149) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 150) new JavassistInterfaceDeclaration(interfaze, typeSolver).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 151) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 159) SymbolReference.unsolved(ValueDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 165) getSuperClass() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.getSuperClass()
+  Line 166) ancestors.add(getSuperClass()) ==> java.util.List.add(E)
+  Line 166) getSuperClass() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.getSuperClass()
+  Line 168) ancestors.addAll(getInterfaces()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 168) getInterfaces() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.getInterfaces()
+  Line 175) Modifier.isStatic(m.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 175) m.getModifiers() ==> javassist.CtBehavior.getModifiers()
+  Line 176) ctClass.getDeclaredMethods() ==> javassist.CtClass.getDeclaredMethods()
+  Line 177) method.getMethodInfo().getAttribute(SyntheticAttribute.tag) ==> javassist.bytecode.MethodInfo.getAttribute(java.lang.String)
+  Line 177) method.getMethodInfo() ==> javassist.CtBehavior.getMethodInfo()
+  Line 178) method.getMethodInfo().getAccessFlags() ==> javassist.bytecode.MethodInfo.getAccessFlags()
+  Line 178) method.getMethodInfo() ==> javassist.CtBehavior.getMethodInfo()
+  Line 179) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 179) method.getName() ==> javassist.CtMethod.getName()
+  Line 179) staticOnlyCheck.test(method) ==> java.util.function.Predicate.test(T)
+  Line 180) candidates.add(new JavassistMethodDeclaration(method, typeSolver)) ==> java.util.List.add(E)
+  Line 185) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 187) new JavassistClassDeclaration(superClass, typeSolver).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 188) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 189) candidates.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 189) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 197) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 198) new JavassistInterfaceDeclaration(interfaze, typeSolver).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 199) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 200) candidates.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 200) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 207) MethodResolutionLogic.findMostApplicable(candidates, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 216) type.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 221) isFunctionalInterface() ==> com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration.isFunctionalInterface()
+  Line 225) type.describe().equals(this.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 225) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 225) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.getQualifiedName()
+  Line 229) this.ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 230) new JavassistClassDeclaration(this.ctClass.getSuperclass(), typeSolver).isAssignableBy(type) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 230) this.ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 233) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 234) new JavassistInterfaceDeclaration(interfaze, typeSolver).isAssignableBy(type) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 251) javassistTypeDeclarationAdapter.getDeclaredFields() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getDeclaredFields()
+  Line 256) ctClass.getSimpleName().replace('$', '.').split("\\.") ==> java.lang.String.split(java.lang.String)
+  Line 256) ctClass.getSimpleName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 256) ctClass.getSimpleName() ==> javassist.CtClass.getSimpleName()
+  Line 277) ctClass.isInterface() ==> javassist.CtClass.isInterface()
+  Line 283) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 284) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 284) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 286) ctClass.getGenericSignature() ==> javassist.CtClass.getGenericSignature()
+  Line 287) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 290) SignatureAttribute.toClassSignature(ctClass.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toClassSignature(java.lang.String)
+  Line 290) ctClass.getGenericSignature() ==> javassist.CtClass.getGenericSignature()
+  Line 291) JavassistUtils.signatureTypeToType(classSignature.getSuperClass(), typeSolver, this).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 291) JavassistUtils.signatureTypeToType(classSignature.getSuperClass(), typeSolver, this) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.signatureTypeToType(javassist.bytecode.SignatureAttribute.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 291) classSignature.getSuperClass() ==> javassist.bytecode.SignatureAttribute.ClassSignature.getSuperClass()
+  Line 302) ctClass.getGenericSignature() ==> javassist.CtClass.getGenericSignature()
+  Line 303) Arrays.stream(ctClass.getInterfaces()).map(i -> new JavassistInterfaceDeclaration(i, typeSolver)).map(i -> new ReferenceTypeImpl(i, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 303) Arrays.stream(ctClass.getInterfaces()).map(i -> new JavassistInterfaceDeclaration(i, typeSolver)).map(i -> new ReferenceTypeImpl(i, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 303) Arrays.stream(ctClass.getInterfaces()).map(i -> new JavassistInterfaceDeclaration(i, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 303) Arrays.stream(ctClass.getInterfaces()) ==> java.util.Arrays.stream(T[])
+  Line 303) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 306) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 308) SignatureAttribute.toClassSignature(ctClass.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toClassSignature(java.lang.String)
+  Line 308) ctClass.getGenericSignature() ==> javassist.CtClass.getGenericSignature()
+  Line 309) Arrays.stream(classSignature.getInterfaces()).map(i -> JavassistUtils.signatureTypeToType(i, typeSolver, this).asReferenceType()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 309) Arrays.stream(classSignature.getInterfaces()).map(i -> JavassistUtils.signatureTypeToType(i, typeSolver, this).asReferenceType()) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 309) Arrays.stream(classSignature.getInterfaces()) ==> java.util.Arrays.stream(T[])
+  Line 309) classSignature.getInterfaces() ==> javassist.bytecode.SignatureAttribute.ClassSignature.getInterfaces()
+  Line 310) JavassistUtils.signatureTypeToType(i, typeSolver, this).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 310) JavassistUtils.signatureTypeToType(i, typeSolver, this) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.signatureTypeToType(javassist.bytecode.SignatureAttribute.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 311) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 322) ctClass.isInterface() ==> javassist.CtClass.isInterface()
+  Line 327) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 332) javassistTypeDeclarationAdapter.getTypeParameters() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getTypeParameters()
+  Line 337) JavassistFactory.modifiersToAccessLevel(ctClass.getModifiers()) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.modifiersToAccessLevel(int)
+  Line 337) ctClass.getModifiers() ==> javassist.CtClass.getModifiers()
+  Line 342) javassistTypeDeclarationAdapter.getConstructors() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getConstructors()
+  Line 347) javassistTypeDeclarationAdapter.containerType() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.containerType()
+  Line 357) Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 357) Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 357) Arrays.stream(ctClass.getDeclaredClasses()) ==> java.util.Arrays.stream(T[])
+  Line 357) ctClass.getDeclaredClasses() ==> javassist.CtClass.getDeclaredClasses()
+  Line 357) JavassistFactory.toTypeDeclaration(itype, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.toTypeDeclaration(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 357) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 370) this.internalTypes().stream().filter(f -> f.getName().endsWith(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 370) this.internalTypes().stream().filter(f -> f.getName().endsWith(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 370) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 370) this.internalTypes() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.internalTypes()
+  Line 370) f.getName().endsWith(name) ==> java.lang.String.endsWith(java.lang.String)
+  Line 370) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 371) type.orElseThrow(() -> new UnsolvedSymbolException("Internal type not found: " + name)) ==> java.util.Optional.orElseThrow(java.util.function.Supplier<? extends X>)
+  Line 381) this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 381) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 381) this.internalTypes() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.internalTypes()
+  Line 381) f.getName().endsWith(name) ==> java.lang.String.endsWith(java.lang.String)
+  Line 381) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistConstructorDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistConstructorDeclaration.txt
new file mode 100644
index 0000000..8cb3547
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistConstructorDeclaration.txt
@@ -0,0 +1,22 @@
+  Line 52) ctConstructor.getName() ==> javassist.CtConstructor.getName()
+  Line 72) ctConstructor.getDeclaringClass() ==> javassist.CtMember.getDeclaringClass()
+  Line 78) ctConstructor.getParameterTypes() ==> javassist.CtBehavior.getParameterTypes()
+  Line 88) ctConstructor.getModifiers() ==> javassist.CtBehavior.getModifiers()
+  Line 89) ctConstructor.getParameterTypes() ==> javassist.CtBehavior.getParameterTypes()
+  Line 91) ctConstructor.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 92) SignatureAttribute.toMethodSignature(ctConstructor.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toMethodSignature(java.lang.String)
+  Line 92) ctConstructor.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 93) methodSignature.getParameterTypes() ==> javassist.bytecode.SignatureAttribute.MethodSignature.getParameterTypes()
+  Line 94) JavassistUtils.signatureTypeToType(signatureType, typeSolver, this) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.signatureTypeToType(javassist.bytecode.SignatureAttribute.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 96) ctConstructor.getParameterTypes() ==> javassist.CtBehavior.getParameterTypes()
+  Line 108) ctConstructor.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 109) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 111) SignatureAttribute.toMethodSignature(ctConstructor.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toMethodSignature(java.lang.String)
+  Line 111) ctConstructor.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 112) Arrays.stream(methodSignature.getTypeParameters()).map((jasTp) -> new JavassistTypeParameter(jasTp, this, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 112) Arrays.stream(methodSignature.getTypeParameters()).map((jasTp) -> new JavassistTypeParameter(jasTp, this, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 112) Arrays.stream(methodSignature.getTypeParameters()) ==> java.util.Arrays.stream(T[])
+  Line 112) methodSignature.getTypeParameters() ==> javassist.bytecode.SignatureAttribute.MethodSignature.getTypeParameters()
+  Line 112) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 120) JavassistFactory.modifiersToAccessLevel(ctConstructor.getModifiers()) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.modifiersToAccessLevel(int)
+  Line 120) ctConstructor.getModifiers() ==> javassist.CtBehavior.getModifiers()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistEnumDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistEnumDeclaration.txt
new file mode 100644
index 0000000..f8c8b22
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistEnumDeclaration.txt
@@ -0,0 +1,81 @@
+  Line 53) ctClass.isEnum() ==> javassist.CtClass.isEnum()
+  Line 54) ctClass.toString() ==> javassist.CtClass.toString()
+  Line 63) JavassistFactory.modifiersToAccessLevel(ctClass.getModifiers()) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.modifiersToAccessLevel(int)
+  Line 63) ctClass.getModifiers() ==> javassist.CtClass.getModifiers()
+  Line 68) ctClass.getPackageName() ==> javassist.CtClass.getPackageName()
+  Line 73) ctClass.getName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 73) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 74) getPackageName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration.getPackageName()
+  Line 75) name.substring(getPackageName().length() + 1, name.length()) ==> java.lang.String.substring(int, int)
+  Line 75) getPackageName().length() ==> java.lang.String.length()
+  Line 75) getPackageName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration.getPackageName()
+  Line 75) name.length() ==> java.lang.String.length()
+  Line 82) ctClass.getName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 82) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 91) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 94) JavassistFactory.typeUsageFor(superClass, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.typeUsageFor(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 96) superClassTypeUsage.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 97) ancestors.add(superClassTypeUsage.asReferenceType()) ==> java.util.List.add(E)
+  Line 97) superClassTypeUsage.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 101) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 102) JavassistFactory.typeUsageFor(interfaze, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.typeUsageFor(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 104) interfazeTypeUsage.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 105) ancestors.add(interfazeTypeUsage.asReferenceType()) ==> java.util.List.add(E)
+  Line 105) interfazeTypeUsage.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 109) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 117) javassistTypeDeclarationAdapter.getDeclaredFields().stream().filter(f -> f.getName().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 117) javassistTypeDeclarationAdapter.getDeclaredFields().stream().filter(f -> f.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 117) javassistTypeDeclarationAdapter.getDeclaredFields().stream() ==> java.util.Collection.stream()
+  Line 117) javassistTypeDeclarationAdapter.getDeclaredFields() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getDeclaredFields()
+  Line 117) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 117) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 119) field.orElseThrow(() -> new RuntimeException("Field " + name + " does not exist in " + ctClass.getName() + ".")) ==> java.util.Optional.orElseThrow(java.util.function.Supplier<? extends X>)
+  Line 119) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 124) javassistTypeDeclarationAdapter.getDeclaredFields().stream().anyMatch(f -> f.getName().equals(name)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 124) javassistTypeDeclarationAdapter.getDeclaredFields().stream() ==> java.util.Collection.stream()
+  Line 124) javassistTypeDeclarationAdapter.getDeclaredFields() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getDeclaredFields()
+  Line 124) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 124) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 129) javassistTypeDeclarationAdapter.getDeclaredFields() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getDeclaredFields()
+  Line 134) javassistTypeDeclarationAdapter.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getDeclaredMethods()
+  Line 154) ctClass.getSimpleName().replace('$', '.').split("\\.") ==> java.lang.String.split(java.lang.String)
+  Line 154) ctClass.getSimpleName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 154) ctClass.getSimpleName() ==> javassist.CtClass.getSimpleName()
+  Line 160) javassistTypeDeclarationAdapter.getTypeParameters() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getTypeParameters()
+  Line 165) javassistTypeDeclarationAdapter.containerType() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.containerType()
+  Line 170) Modifier.isStatic(m.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 170) m.getModifiers() ==> javassist.CtBehavior.getModifiers()
+  Line 171) ctClass.getDeclaredMethods() ==> javassist.CtClass.getDeclaredMethods()
+  Line 172) method.getMethodInfo().getAttribute(SyntheticAttribute.tag) ==> javassist.bytecode.MethodInfo.getAttribute(java.lang.String)
+  Line 172) method.getMethodInfo() ==> javassist.CtBehavior.getMethodInfo()
+  Line 173) method.getMethodInfo().getAccessFlags() ==> javassist.bytecode.MethodInfo.getAccessFlags()
+  Line 173) method.getMethodInfo() ==> javassist.CtBehavior.getMethodInfo()
+  Line 174) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 174) method.getName() ==> javassist.CtMethod.getName()
+  Line 174) staticOnlyCheck.test(method) ==> java.util.function.Predicate.test(T)
+  Line 175) candidates.add(new JavassistMethodDeclaration(method, typeSolver)) ==> java.util.List.add(E)
+  Line 180) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 182) new JavassistClassDeclaration(superClass, typeSolver).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 183) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 184) candidates.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 184) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 191) MethodResolutionLogic.findMostApplicable(candidates, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 195) JavassistUtils.getMethodUsage(ctClass, name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.getMethodUsage(javassist.CtClass, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 205) Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 205) Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 205) Arrays.stream(ctClass.getDeclaredClasses()) ==> java.util.Arrays.stream(T[])
+  Line 205) ctClass.getDeclaredClasses() ==> javassist.CtClass.getDeclaredClasses()
+  Line 205) JavassistFactory.toTypeDeclaration(itype, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.toTypeDeclaration(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 205) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 218) this.internalTypes().stream().filter(f -> f.getName().endsWith(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 218) this.internalTypes().stream().filter(f -> f.getName().endsWith(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 218) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 218) this.internalTypes() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration.internalTypes()
+  Line 218) f.getName().endsWith(name) ==> java.lang.String.endsWith(java.lang.String)
+  Line 218) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 219) type.orElseThrow(() -> new UnsolvedSymbolException("Internal type not found: " + name)) ==> java.util.Optional.orElseThrow(java.util.function.Supplier<? extends X>)
+  Line 229) this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 229) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 229) this.internalTypes() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration.internalTypes()
+  Line 229) f.getName().endsWith(name) ==> java.lang.String.endsWith(java.lang.String)
+  Line 229) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistFactory.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistFactory.txt
new file mode 100644
index 0000000..ad09e9d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistFactory.txt
@@ -0,0 +1,17 @@
+  Line 33) ctClazz.isArray() ==> javassist.CtClass.isArray()
+  Line 34) typeUsageFor(ctClazz.getComponentType(), typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.typeUsageFor(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 34) ctClazz.getComponentType() ==> javassist.CtClass.getComponentType()
+  Line 35) ctClazz.isPrimitive() ==> javassist.CtClass.isPrimitive()
+  Line 36) ctClazz.getName().equals("void") ==> java.lang.String.equals(java.lang.Object)
+  Line 36) ctClazz.getName() ==> javassist.CtClass.getName()
+  Line 39) PrimitiveType.byName(ctClazz.getName()) ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.byName(java.lang.String)
+  Line 39) ctClazz.getName() ==> javassist.CtClass.getName()
+  Line 42) ctClazz.isInterface() ==> javassist.CtClass.isInterface()
+  Line 45) ctClazz.isEnum() ==> javassist.CtClass.isEnum()
+  Line 59) ctClazz.isInterface() ==> javassist.CtClass.isInterface()
+  Line 61) ctClazz.isEnum() ==> javassist.CtClass.isEnum()
+  Line 63) ctClazz.isAnnotation() ==> javassist.CtClass.isAnnotation()
+  Line 65) ctClazz.isArray() ==> javassist.CtClass.isArray()
+  Line 73) Modifier.isPublic(modifiers) ==> java.lang.reflect.Modifier.isPublic(int)
+  Line 75) Modifier.isProtected(modifiers) ==> java.lang.reflect.Modifier.isProtected(int)
+  Line 77) Modifier.isPrivate(modifiers) ==> java.lang.reflect.Modifier.isPrivate(int)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistFieldDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistFieldDeclaration.txt
new file mode 100644
index 0000000..ae533ba
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistFieldDeclaration.txt
@@ -0,0 +1,9 @@
+  Line 44) JavassistFactory.typeUsageFor(ctField.getType(), typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.typeUsageFor(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 44) ctField.getType() ==> javassist.CtField.getType()
+  Line 52) Modifier.isStatic(ctField.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 52) ctField.getModifiers() ==> javassist.CtField.getModifiers()
+  Line 57) ctField.getName() ==> javassist.CtField.getName()
+  Line 77) JavassistFactory.modifiersToAccessLevel(ctField.getModifiers()) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.modifiersToAccessLevel(int)
+  Line 77) ctField.getModifiers() ==> javassist.CtField.getModifiers()
+  Line 82) JavassistFactory.toTypeDeclaration(ctField.getDeclaringClass(), typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.toTypeDeclaration(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 82) ctField.getDeclaringClass() ==> javassist.CtField.getDeclaringClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistInterfaceDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistInterfaceDeclaration.txt
new file mode 100644
index 0000000..d1dd2cd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistInterfaceDeclaration.txt
@@ -0,0 +1,104 @@
+  Line 54) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 60) ctClass.isInterface() ==> javassist.CtClass.isInterface()
+  Line 61) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 71) Arrays.stream(ctClass.getInterfaces()).map(i -> new JavassistInterfaceDeclaration(i, typeSolver)).map(i -> new ReferenceTypeImpl(i, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 71) Arrays.stream(ctClass.getInterfaces()).map(i -> new JavassistInterfaceDeclaration(i, typeSolver)).map(i -> new ReferenceTypeImpl(i, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 71) Arrays.stream(ctClass.getInterfaces()).map(i -> new JavassistInterfaceDeclaration(i, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 71) Arrays.stream(ctClass.getInterfaces()) ==> java.util.Arrays.stream(T[])
+  Line 71) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 72) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 80) ctClass.getPackageName() ==> javassist.CtClass.getPackageName()
+  Line 85) ctClass.getName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 85) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 86) getPackageName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.getPackageName()
+  Line 87) className.substring(getPackageName().length() + 1, className.length()) ==> java.lang.String.substring(int, int)
+  Line 87) getPackageName().length() ==> java.lang.String.length()
+  Line 87) getPackageName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.getPackageName()
+  Line 87) className.length() ==> java.lang.String.length()
+  Line 94) ctClass.getName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 94) ctClass.getName() ==> javassist.CtClass.getName()
+  Line 101) JavassistUtils.getMethodUsage(ctClass, name, argumentsTypes, typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.getMethodUsage(javassist.CtClass, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 107) Modifier.isStatic(m.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 107) m.getModifiers() ==> javassist.CtBehavior.getModifiers()
+  Line 108) ctClass.getDeclaredMethods() ==> javassist.CtClass.getDeclaredMethods()
+  Line 109) method.getMethodInfo().getAttribute(SyntheticAttribute.tag) ==> javassist.bytecode.MethodInfo.getAttribute(java.lang.String)
+  Line 109) method.getMethodInfo() ==> javassist.CtBehavior.getMethodInfo()
+  Line 110) method.getMethodInfo().getAccessFlags() ==> javassist.bytecode.MethodInfo.getAccessFlags()
+  Line 110) method.getMethodInfo() ==> javassist.CtBehavior.getMethodInfo()
+  Line 111) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 111) method.getName() ==> javassist.CtMethod.getName()
+  Line 111) staticOnlyCheck.test(method) ==> java.util.function.Predicate.test(T)
+  Line 112) candidates.add(new JavassistMethodDeclaration(method, typeSolver)) ==> java.util.List.add(E)
+  Line 117) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 119) new JavassistClassDeclaration(superClass, typeSolver).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 120) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 121) candidates.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 121) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 129) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 130) new JavassistInterfaceDeclaration(interfaze, typeSolver).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 131) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 132) candidates.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 132) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 139) MethodResolutionLogic.findMostApplicable(candidates, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 149) javassistTypeDeclarationAdapter.getDeclaredFields() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getDeclaredFields()
+  Line 161) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 162) JavassistFactory.typeUsageFor(interfaze, typeSolver).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 162) JavassistFactory.typeUsageFor(interfaze, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.typeUsageFor(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 163) ancestors.add(superInterfaze) ==> java.util.List.add(E)
+  Line 168) ancestors.stream().filter(a -> a.getQualifiedName() != Object.class.getCanonicalName()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 168) ancestors.stream().filter(a -> a.getQualifiedName() != Object.class.getCanonicalName()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 168) ancestors.stream() ==> java.util.Collection.stream()
+  Line 168) a.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 168) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 169) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 170) ancestors.add(new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver)) ==> java.util.List.add(E)
+  Line 170) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 170) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 176) Arrays.stream(ctClass.getDeclaredMethods()).map(m -> new JavassistMethodDeclaration(m, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 176) Arrays.stream(ctClass.getDeclaredMethods()).map(m -> new JavassistMethodDeclaration(m, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 176) Arrays.stream(ctClass.getDeclaredMethods()) ==> java.util.Arrays.stream(T[])
+  Line 176) ctClass.getDeclaredMethods() ==> javassist.CtClass.getDeclaredMethods()
+  Line 178) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 184) ctClass.getAnnotations() ==> javassist.CtClass.getAnnotations()
+  Line 185) annotationRaw.getClass().getCanonicalName().equals(canonicalName) ==> java.lang.String.equals(java.lang.Object)
+  Line 185) annotationRaw.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 185) annotationRaw.getClass() ==> java.lang.Object.getClass()
+  Line 188) Arrays.stream(annotationRaw.getClass().getInterfaces()).anyMatch(it -> it.getCanonicalName().equals(canonicalName)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 188) Arrays.stream(annotationRaw.getClass().getInterfaces()) ==> java.util.Arrays.stream(T[])
+  Line 188) annotationRaw.getClass().getInterfaces() ==> java.lang.Class.getInterfaces()
+  Line 188) annotationRaw.getClass() ==> java.lang.Object.getClass()
+  Line 188) it.getCanonicalName().equals(canonicalName) ==> java.lang.String.equals(java.lang.Object)
+  Line 188) it.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 200) ctClass.getSimpleName().replace('$', '.').split("\\.") ==> java.lang.String.split(java.lang.String)
+  Line 200) ctClass.getSimpleName().replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 200) ctClass.getSimpleName() ==> javassist.CtClass.getSimpleName()
+  Line 206) javassistTypeDeclarationAdapter.getTypeParameters() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.getTypeParameters()
+  Line 211) JavassistFactory.modifiersToAccessLevel(ctClass.getModifiers()) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.modifiersToAccessLevel(int)
+  Line 211) ctClass.getModifiers() ==> javassist.CtClass.getModifiers()
+  Line 222) ctClass.getDeclaredFields() ==> javassist.CtClass.getDeclaredFields()
+  Line 223) field.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 223) field.getName() ==> javassist.CtField.getName()
+  Line 224) SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 229) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 230) new JavassistInterfaceDeclaration(interfaze, typeSolver).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 231) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 239) SymbolReference.unsolved(ValueDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 244) javassistTypeDeclarationAdapter.containerType() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.containerType()
+  Line 254) Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 254) Arrays.stream(ctClass.getDeclaredClasses()).map(itype -> JavassistFactory.toTypeDeclaration(itype, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 254) Arrays.stream(ctClass.getDeclaredClasses()) ==> java.util.Arrays.stream(T[])
+  Line 254) ctClass.getDeclaredClasses() ==> javassist.CtClass.getDeclaredClasses()
+  Line 254) JavassistFactory.toTypeDeclaration(itype, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.toTypeDeclaration(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 254) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 267) this.internalTypes().stream().filter(f -> f.getName().endsWith(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 267) this.internalTypes().stream().filter(f -> f.getName().endsWith(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 267) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 267) this.internalTypes() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.internalTypes()
+  Line 267) f.getName().endsWith(name) ==> java.lang.String.endsWith(java.lang.String)
+  Line 267) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 268) type.orElseThrow(() -> new UnsolvedSymbolException("Internal type not found: " + name)) ==> java.util.Optional.orElseThrow(java.util.function.Supplier<? extends X>)
+  Line 278) this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 278) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 278) this.internalTypes() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.internalTypes()
+  Line 278) f.getName().endsWith(name) ==> java.lang.String.endsWith(java.lang.String)
+  Line 278) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistMethodDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistMethodDeclaration.txt
new file mode 100644
index 0000000..2010001
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistMethodDeclaration.txt
@@ -0,0 +1,33 @@
+  Line 51) ctMethod.getDeclaringClass().isInterface() ==> javassist.CtClass.isInterface()
+  Line 51) ctMethod.getDeclaringClass() ==> javassist.CtMember.getDeclaringClass()
+  Line 51) isAbstract() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistMethodDeclaration.isAbstract()
+  Line 56) Modifier.isStatic(ctMethod.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 56) ctMethod.getModifiers() ==> javassist.CtBehavior.getModifiers()
+  Line 68) ctMethod.getName() ==> javassist.CtMethod.getName()
+  Line 88) ctMethod.getDeclaringClass().isInterface() ==> javassist.CtClass.isInterface()
+  Line 88) ctMethod.getDeclaringClass() ==> javassist.CtMember.getDeclaringClass()
+  Line 89) ctMethod.getDeclaringClass() ==> javassist.CtMember.getDeclaringClass()
+  Line 91) ctMethod.getDeclaringClass() ==> javassist.CtMember.getDeclaringClass()
+  Line 98) JavassistFactory.typeUsageFor(ctMethod.getReturnType(), typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.typeUsageFor(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 98) ctMethod.getReturnType() ==> javassist.CtMethod.getReturnType()
+  Line 108) ctMethod.getParameterTypes() ==> javassist.CtBehavior.getParameterTypes()
+  Line 118) ctMethod.getModifiers() ==> javassist.CtBehavior.getModifiers()
+  Line 119) ctMethod.getParameterTypes() ==> javassist.CtBehavior.getParameterTypes()
+  Line 121) ctMethod.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 122) SignatureAttribute.toMethodSignature(ctMethod.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toMethodSignature(java.lang.String)
+  Line 122) ctMethod.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 123) methodSignature.getParameterTypes() ==> javassist.bytecode.SignatureAttribute.MethodSignature.getParameterTypes()
+  Line 124) JavassistUtils.signatureTypeToType(signatureType, typeSolver, this) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.signatureTypeToType(javassist.bytecode.SignatureAttribute.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 126) ctMethod.getParameterTypes() ==> javassist.CtBehavior.getParameterTypes()
+  Line 140) new MethodDeclarationCommonLogic(this, typeSolver).resolveTypeVariables(context, parameterTypes) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 145) Modifier.isAbstract(ctMethod.getModifiers()) ==> java.lang.reflect.Modifier.isAbstract(int)
+  Line 145) ctMethod.getModifiers() ==> javassist.CtBehavior.getModifiers()
+  Line 151) ctMethod.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 152) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 154) SignatureAttribute.toMethodSignature(ctMethod.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toMethodSignature(java.lang.String)
+  Line 154) ctMethod.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 155) Arrays.stream(methodSignature.getTypeParameters()).map((jasTp) -> new JavassistTypeParameter(jasTp, this, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 155) Arrays.stream(methodSignature.getTypeParameters()).map((jasTp) -> new JavassistTypeParameter(jasTp, this, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 155) Arrays.stream(methodSignature.getTypeParameters()) ==> java.util.Arrays.stream(T[])
+  Line 155) methodSignature.getTypeParameters() ==> javassist.bytecode.SignatureAttribute.MethodSignature.getTypeParameters()
+  Line 155) Collectors.toList() ==> java.util.stream.Collectors.toList()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistParameterDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistParameterDeclaration.txt
new file mode 100644
index 0000000..4a6626f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistParameterDeclaration.txt
@@ -0,0 +1 @@
+  Line 33) JavassistFactory.typeUsageFor(type, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.typeUsageFor(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistTypeDeclarationAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistTypeDeclarationAdapter.txt
new file mode 100644
index 0000000..a269a44
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistTypeDeclarationAdapter.txt
@@ -0,0 +1,32 @@
+  Line 41) Arrays.stream(ctClass.getDeclaredMethods()).map(m -> new JavassistMethodDeclaration(m, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 41) Arrays.stream(ctClass.getDeclaredMethods()).map(m -> new JavassistMethodDeclaration(m, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 41) Arrays.stream(ctClass.getDeclaredMethods()) ==> java.util.Arrays.stream(T[])
+  Line 41) ctClass.getDeclaredMethods() ==> javassist.CtClass.getDeclaredMethods()
+  Line 42) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 46) Arrays.stream(ctClass.getConstructors()).map(m -> new JavassistConstructorDeclaration(m, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 46) Arrays.stream(ctClass.getConstructors()).map(m -> new JavassistConstructorDeclaration(m, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 46) Arrays.stream(ctClass.getConstructors()) ==> java.util.Arrays.stream(T[])
+  Line 46) ctClass.getConstructors() ==> javassist.CtClass.getConstructors()
+  Line 47) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 52) collectDeclaredFields(ctClass, fieldDecls) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.collectDeclaredFields(javassist.CtClass, java.util.List<com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration>)
+  Line 58) Arrays.stream(ctClass.getDeclaredFields()).forEach(f -> fieldDecls.add(new JavassistFieldDeclaration(f, typeSolver))) ==> java.util.stream.Stream.forEach(java.util.function.Consumer<? super T>)
+  Line 58) Arrays.stream(ctClass.getDeclaredFields()) ==> java.util.Arrays.stream(T[])
+  Line 58) ctClass.getDeclaredFields() ==> javassist.CtClass.getDeclaredFields()
+  Line 59) fieldDecls.add(new JavassistFieldDeclaration(f, typeSolver)) ==> java.util.List.add(E)
+  Line 61) collectDeclaredFields(ctClass.getSuperclass(), fieldDecls) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeDeclarationAdapter.collectDeclaredFields(javassist.CtClass, java.util.List<com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration>)
+  Line 61) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 69) ctClass.getGenericSignature() ==> javassist.CtClass.getGenericSignature()
+  Line 70) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 74) SignatureAttribute.toClassSignature(ctClass.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toClassSignature(java.lang.String)
+  Line 74) ctClass.getGenericSignature() ==> javassist.CtClass.getGenericSignature()
+  Line 75) Arrays.<SignatureAttribute.TypeParameter>stream(classSignature.getParameters()).map((tp) -> new JavassistTypeParameter(tp, JavassistFactory.toTypeDeclaration(ctClass, typeSolver), typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 75) Arrays.<SignatureAttribute.TypeParameter>stream(classSignature.getParameters()).map((tp) -> new JavassistTypeParameter(tp, JavassistFactory.toTypeDeclaration(ctClass, typeSolver), typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 75) Arrays.<SignatureAttribute.TypeParameter>stream(classSignature.getParameters()) ==> java.util.Arrays.stream(T[])
+  Line 75) classSignature.getParameters() ==> javassist.bytecode.SignatureAttribute.ClassSignature.getParameters()
+  Line 76) JavassistFactory.toTypeDeclaration(ctClass, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.toTypeDeclaration(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 77) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 86) ctClass.getDeclaringClass() ==> javassist.CtClass.getDeclaringClass()
+  Line 87) Optional.empty() ==> java.util.Optional.empty()
+  Line 88) Optional.of(JavassistFactory.toTypeDeclaration(ctClass.getDeclaringClass(), typeSolver)) ==> java.util.Optional.of(T)
+  Line 88) JavassistFactory.toTypeDeclaration(ctClass.getDeclaringClass(), typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.toTypeDeclaration(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 88) ctClass.getDeclaringClass() ==> javassist.CtClass.getDeclaringClass()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistTypeParameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistTypeParameter.txt
new file mode 100644
index 0000000..16c3137
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistTypeParameter.txt
@@ -0,0 +1,23 @@
+  Line 53) getQualifiedName().equals(that.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 53) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 53) that.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 56) declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 56) that.declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 59) declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 59) that.declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 69) wrapped.getName() ==> javassist.bytecode.SignatureAttribute.TypeParameter.getName()
+  Line 75) wrapped.getName() ==> javassist.bytecode.SignatureAttribute.TypeParameter.getName()
+  Line 81) ((ReferenceTypeDeclaration) this.container).getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 83) ((MethodLikeDeclaration) this.container).getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedName()
+  Line 90) getContainerQualifiedName() ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistTypeParameter.getContainerQualifiedName()
+  Line 101) wrapped.getClassBound() ==> javassist.bytecode.SignatureAttribute.TypeParameter.getClassBound()
+  Line 101) wrapped.getClassBound().toString().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 101) wrapped.getClassBound().toString() ==> java.lang.Object.toString()
+  Line 101) wrapped.getClassBound() ==> javassist.bytecode.SignatureAttribute.TypeParameter.getClassBound()
+  Line 101) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 102) wrapped.getClassBound().toString() ==> java.lang.Object.toString()
+  Line 102) wrapped.getClassBound() ==> javassist.bytecode.SignatureAttribute.TypeParameter.getClassBound()
+  Line 104) wrapped.getInterfaceBound() ==> javassist.bytecode.SignatureAttribute.TypeParameter.getInterfaceBound()
+  Line 105) ot.toString() ==> java.lang.Object.toString()
+  Line 113) Optional.of((ReferenceTypeDeclaration) container) ==> java.util.Optional.of(T)
+  Line 115) Optional.empty() ==> java.util.Optional.empty()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistUtils.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistUtils.txt
new file mode 100644
index 0000000..07a5990
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_javassistmodel_JavassistUtils.txt
@@ -0,0 +1,77 @@
+  Line 44) ctClass.getDeclaredMethods() ==> javassist.CtClass.getDeclaredMethods()
+  Line 45) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 45) method.getName() ==> javassist.CtMethod.getName()
+  Line 48) argumentsTypes.size() ==> java.util.List.size()
+  Line 48) methodUsage.getNoParams() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getNoParams()
+  Line 53) method.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 54) SignatureAttribute.toMethodSignature(method.getGenericSignature()) ==> javassist.bytecode.SignatureAttribute.toMethodSignature(java.lang.String)
+  Line 54) method.getGenericSignature() ==> javassist.CtBehavior.getGenericSignature()
+  Line 55) parseTypeParameters(classSignature.getReturnType().toString(), typeSolver, invokationContext) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.parseTypeParameters(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 55) classSignature.getReturnType().toString() ==> java.lang.Object.toString()
+  Line 55) classSignature.getReturnType() ==> javassist.bytecode.SignatureAttribute.MethodSignature.getReturnType()
+  Line 56) methodUsage.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 59) newReturnType.asReferenceType().transformTypeParameters(tp -> parametersOfReturnType.remove(0)) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.transformTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer)
+  Line 59) newReturnType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 59) parametersOfReturnType.remove(0) ==> java.util.List.remove(int)
+  Line 61) methodUsage.replaceReturnType(newReturnType) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceReturnType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 63) Optional.of(methodUsage) ==> java.util.Optional.of(T)
+  Line 71) ctClass.getSuperclass() ==> javassist.CtClass.getSuperclass()
+  Line 73) new JavassistClassDeclaration(superClass, typeSolver).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, null) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 74) ref.isPresent() ==> java.util.Optional.isPresent()
+  Line 83) ctClass.getInterfaces() ==> javassist.CtClass.getInterfaces()
+  Line 84) new JavassistInterfaceDeclaration(interfaze, typeSolver).solveMethodAsUsage(name, argumentsTypes, typeSolver, invokationContext, null) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 85) ref.isPresent() ==> java.util.Optional.isPresent()
+  Line 93) Optional.empty() ==> java.util.Optional.empty()
+  Line 98) signature.contains("<") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 99) signature.substring(signature.indexOf('<') + 1) ==> java.lang.String.substring(int)
+  Line 99) signature.indexOf('<') ==> java.lang.String.indexOf(int)
+  Line 100) signature.endsWith(">") ==> java.lang.String.endsWith(java.lang.String)
+  Line 103) signature.substring(0, signature.length() - 1) ==> java.lang.String.substring(int, int)
+  Line 103) signature.length() ==> java.lang.String.length()
+  Line 104) signature.contains(",") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 107) signature.contains("<") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 110) signature.contains(">") ==> java.lang.String.contains(java.lang.CharSequence)
+  Line 114) types.add(new SymbolSolver(typeSolver).solveTypeUsage(signature, invokationContext)) ==> java.util.List.add(E)
+  Line 114) new SymbolSolver(typeSolver).solveTypeUsage(signature, invokationContext) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveTypeUsage(java.lang.String, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 117) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 124) classType.getTypeArguments() ==> javassist.bytecode.SignatureAttribute.ClassType.getTypeArguments()
+  Line 124) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 124) Arrays.stream(classType.getTypeArguments()).map(ta -> typeArgumentToType(ta, typeSolver, typeParametrizable)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 124) Arrays.stream(classType.getTypeArguments()).map(ta -> typeArgumentToType(ta, typeSolver, typeParametrizable)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 124) Arrays.stream(classType.getTypeArguments()) ==> java.util.Arrays.stream(T[])
+  Line 124) classType.getTypeArguments() ==> javassist.bytecode.SignatureAttribute.ClassType.getTypeArguments()
+  Line 124) typeArgumentToType(ta, typeSolver, typeParametrizable) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.typeArgumentToType(javassist.bytecode.SignatureAttribute.TypeArgument, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 124) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 126) classType.getDeclaringClass() ==> javassist.bytecode.SignatureAttribute.ClassType.getDeclaringClass()
+  Line 127) classType.getDeclaringClass().getName() ==> javassist.bytecode.SignatureAttribute.ClassType.getName()
+  Line 127) classType.getDeclaringClass() ==> javassist.bytecode.SignatureAttribute.ClassType.getDeclaringClass()
+  Line 127) classType.getName() ==> javassist.bytecode.SignatureAttribute.ClassType.getName()
+  Line 128) classType.getName() ==> javassist.bytecode.SignatureAttribute.ClassType.getName()
+  Line 129) typeSolver.solveType(internalNameToCanonicalName(typeName)) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 130) internalNameToCanonicalName(typeName) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.internalNameToCanonicalName(java.lang.String)
+  Line 134) typeParametrizable.findTypeParameter(typeVariableSignature.getName()) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.findTypeParameter(java.lang.String)
+  Line 134) typeVariableSignature.getName() ==> javassist.bytecode.SignatureAttribute.TypeVariable.getName()
+  Line 135) typeParameterDeclarationOpt.isPresent() ==> java.util.Optional.isPresent()
+  Line 138) typeParameterDeclarationOpt.get() ==> java.util.Optional.get()
+  Line 141) signatureType.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 141) signatureType.getClass() ==> java.lang.Object.getClass()
+  Line 146) typeName.replaceAll("\\$", ".") ==> java.lang.String.replaceAll(java.lang.String, java.lang.String)
+  Line 150) typeArgument.jvmTypeName() ==> javassist.bytecode.SignatureAttribute.Type.jvmTypeName()
+  Line 151) getGenericParameterByName(typeName, typeParametrizable) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.getGenericParameterByName(java.lang.String, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 152) type.orElseGet(() -> new ReferenceTypeImpl(typeSolver.solveType(internalNameToCanonicalName(typeName)), typeSolver)) ==> java.util.Optional.orElseGet(java.util.function.Supplier<? extends T>)
+  Line 153) typeSolver.solveType(internalNameToCanonicalName(typeName)) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 153) internalNameToCanonicalName(typeName) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.internalNameToCanonicalName(java.lang.String)
+  Line 158) typeParametrizable.findTypeParameter(typeName) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.findTypeParameter(java.lang.String)
+  Line 159) tp.map(TypeVariable::new) ==> java.util.Optional.map(java.util.function.Function<? super T, ? extends U>)
+  Line 163) typeArgument.isWildcard() ==> javassist.bytecode.SignatureAttribute.TypeArgument.isWildcard()
+  Line 164) typeArgument.getType() ==> javassist.bytecode.SignatureAttribute.TypeArgument.getType()
+  Line 166) typeArgument.getKind() ==> javassist.bytecode.SignatureAttribute.TypeArgument.getKind()
+  Line 167) Wildcard.extendsBound(objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable)) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 167) objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.objectTypeArgumentToType(javassist.bytecode.SignatureAttribute.ObjectType, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 167) typeArgument.getType() ==> javassist.bytecode.SignatureAttribute.TypeArgument.getType()
+  Line 168) typeArgument.getKind() ==> javassist.bytecode.SignatureAttribute.TypeArgument.getKind()
+  Line 169) Wildcard.superBound(objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable)) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 169) objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.objectTypeArgumentToType(javassist.bytecode.SignatureAttribute.ObjectType, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 169) typeArgument.getType() ==> javassist.bytecode.SignatureAttribute.TypeArgument.getType()
+  Line 174) objectTypeArgumentToType(typeArgument.getType(), typeSolver, typeParametrizable) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistUtils.objectTypeArgumentToType(javassist.bytecode.SignatureAttribute.ObjectType, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable)
+  Line 174) typeArgument.getType() ==> javassist.bytecode.SignatureAttribute.TypeArgument.getType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_model_typesystem_LazyType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_model_typesystem_LazyType.txt
new file mode 100644
index 0000000..24aacab
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_model_typesystem_LazyType.txt
@@ -0,0 +1,39 @@
+  Line 18) provider.apply(null) ==> java.util.function.Function.apply(T)
+  Line 25) getType().isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 25) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 30) getType().arrayLevel() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.arrayLevel()
+  Line 30) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 35) getType().isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 35) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 40) getType().isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 40) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 45) getType().isReference() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReference()
+  Line 45) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 50) getType().isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 50) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 55) getType().isVoid() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isVoid()
+  Line 55) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 60) getType().isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 60) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 65) getType().isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 65) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 70) getType().asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 70) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 75) getType().asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 75) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 80) getType().asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 80) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 85) getType().asTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeVariable()
+  Line 85) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 90) getType().asPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asPrimitive()
+  Line 90) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 95) getType().asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 95) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 100) getType().describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 100) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 105) getType().replaceTypeVariables(tp, replaced, inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 105) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 110) getType().replaceTypeVariables(tp, replaced) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 110) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
+  Line 115) getType().isAssignableBy(other) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 115) getType() ==> com.github.javaparser.symbolsolver.model.typesystem.LazyType.getType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_model_typesystem_ReferenceTypeImpl.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_model_typesystem_ReferenceTypeImpl.txt
new file mode 100644
index 0000000..fb95743
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_model_typesystem_ReferenceTypeImpl.txt
@@ -0,0 +1,53 @@
+  Line 42) typeDeclaration.getTypeParameters().stream().map(tp -> new TypeVariable(tp)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 42) typeDeclaration.getTypeParameters().stream().map(tp -> new TypeVariable(tp)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 42) typeDeclaration.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 42) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 44) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 69) javaParserTypeVariableDeclaration.asTypeParameter() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserTypeVariableDeclaration.asTypeParameter()
+  Line 71) this.typeDeclaration.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 71) this.typeDeclaration.getClass() ==> java.lang.Object.getClass()
+  Line 80) this.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 83) other.isVoid() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isVoid()
+  Line 83) this.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 83) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 83) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 87) other.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 88) this.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 88) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 88) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 92) isCorrespondingBoxingType(other.describe()) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isCorrespondingBoxingType(java.lang.String)
+  Line 92) other.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 95) typeSolver.tryToSolveType(other.asPrimitive().getBoxTypeQName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 95) other.asPrimitive().getBoxTypeQName() ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.getBoxTypeQName()
+  Line 95) other.asPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asPrimitive()
+  Line 96) type.getCorrespondingDeclaration().canBeAssignedTo(super.typeDeclaration) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 96) type.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 100) this.getTypeDeclaration().hasAnnotation(FunctionalInterface.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasAnnotation(java.lang.String)
+  Line 100) this.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 100) FunctionalInterface.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 103) compareConsideringTypeParameters(otherRef) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.compareConsideringTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType)
+  Line 106) otherRef.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 107) compareConsideringTypeParameters(otherAncestor) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.compareConsideringTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType)
+  Line 112) other.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 113) other.asTypeVariable().asTypeParameter().getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 113) other.asTypeVariable().asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.asTypeParameter()
+  Line 113) other.asTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeVariable()
+  Line 114) bound.isExtends() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.isExtends()
+  Line 115) this.isAssignableBy(bound.getType()) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 115) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 121) other.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 122) isAssignableBy(other.asConstraintType().getBound()) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 122) other.asConstraintType().getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 122) other.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
+  Line 123) other.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 124) this.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 124) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 124) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 126) other.asWildcard().isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 126) other.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 127) isAssignableBy(other.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 127) other.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 127) other.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 140) getTypeDeclaration().getDeclaredMethods() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getDeclaredMethods()
+  Line 140) getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 142) methods.add(methodUsage) ==> java.util.Set.add(E)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_MyObjectProvider.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_MyObjectProvider.txt
new file mode 100644
index 0000000..e0e306c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_MyObjectProvider.txt
@@ -0,0 +1,3 @@
+  Line 29) typeSolver.solveType(qualifiedName) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 30) typeDeclaration.getTypeParameters().isEmpty() ==> java.util.List.isEmpty()
+  Line 30) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionClassAdapter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionClassAdapter.txt
new file mode 100644
index 0000000..f77342a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionClassAdapter.txt
@@ -0,0 +1,89 @@
+  Line 36) clazz.getGenericSuperclass() ==> java.lang.Class.getGenericSuperclass()
+  Line 39) clazz.getGenericSuperclass() ==> java.lang.Class.getGenericSuperclass()
+  Line 42) Arrays.stream(parameterizedType.getActualTypeArguments()).map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 42) Arrays.stream(parameterizedType.getActualTypeArguments()).map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 42) Arrays.stream(parameterizedType.getActualTypeArguments()) ==> java.util.Arrays.stream(T[])
+  Line 42) parameterizedType.getActualTypeArguments() ==> java.lang.reflect.ParameterizedType.getActualTypeArguments()
+  Line 43) ReflectionFactory.typeUsageFor(t, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 44) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 45) clazz.getSuperclass() ==> java.lang.Class.getSuperclass()
+  Line 47) clazz.getSuperclass() ==> java.lang.Class.getSuperclass()
+  Line 52) clazz.getGenericInterfaces() ==> java.lang.Class.getGenericInterfaces()
+  Line 55) Arrays.stream(parameterizedType.getActualTypeArguments()).map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 55) Arrays.stream(parameterizedType.getActualTypeArguments()).map((t) -> ReflectionFactory.typeUsageFor(t, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 55) Arrays.stream(parameterizedType.getActualTypeArguments()) ==> java.util.Arrays.stream(T[])
+  Line 55) parameterizedType.getActualTypeArguments() ==> java.lang.reflect.ParameterizedType.getActualTypeArguments()
+  Line 56) ReflectionFactory.typeUsageFor(t, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 57) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 58) interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class<?>) ((ParameterizedType) superInterface).getRawType(), typeSolver), typeParameters, typeSolver)) ==> java.util.List.add(E)
+  Line 58) ((ParameterizedType) superInterface).getRawType() ==> java.lang.reflect.ParameterizedType.getRawType()
+  Line 60) interfaces.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration((Class<?>) superInterface, typeSolver), typeSolver)) ==> java.util.List.add(E)
+  Line 68) getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getSuperClass()
+  Line 69) getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getSuperClass()
+  Line 70) ancestors.add(superClass) ==> java.util.List.add(E)
+  Line 73) ancestors.add(object) ==> java.util.List.add(E)
+  Line 75) ancestors.addAll(getInterfaces()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 75) getInterfaces() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getInterfaces()
+  Line 76) ancestors.size() ==> java.util.List.size()
+  Line 77) ancestors.get(i) ==> java.util.List.get(int)
+  Line 78) ancestor.hasName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.hasName()
+  Line 78) ancestor.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 78) ancestor.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 78) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 79) ancestors.remove(i) ==> java.util.List.remove(int)
+  Line 87) clazz.getDeclaredFields() ==> java.lang.Class.getDeclaredFields()
+  Line 88) field.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 88) field.getName() ==> java.lang.reflect.Field.getName()
+  Line 92) typeDeclaration.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllAncestors()
+  Line 93) ancestor.getTypeDeclaration().hasField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasField(java.lang.String)
+  Line 93) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 94) ancestor.getTypeDeclaration().getField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getField(java.lang.String)
+  Line 94) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 95) reflectionFieldDeclaration.replaceType(ancestor.getFieldType(name).get()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFieldDeclaration.replaceType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 95) ancestor.getFieldType(name).get() ==> java.util.Optional.get()
+  Line 95) ancestor.getFieldType(name) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getFieldType(java.lang.String)
+  Line 102) clazz.getDeclaredFields() ==> java.lang.Class.getDeclaredFields()
+  Line 103) field.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 103) field.getName() ==> java.lang.reflect.Field.getName()
+  Line 107) getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getSuperClass()
+  Line 111) superclass.getTypeDeclaration().hasField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasField(java.lang.String)
+  Line 111) superclass.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 117) clazz.getDeclaredFields() ==> java.lang.Class.getDeclaredFields()
+  Line 118) fields.add(new ReflectionFieldDeclaration(field, typeSolver)) ==> java.util.ArrayList.add(E)
+  Line 120) typeDeclaration.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllAncestors()
+  Line 121) fields.addAll(ancestor.getTypeDeclaration().getAllFields()) ==> java.util.ArrayList.addAll(java.util.Collection<? extends E>)
+  Line 121) ancestor.getTypeDeclaration().getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 121) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 127) Arrays.stream(clazz.getDeclaredMethods()).filter(m -> !m.isSynthetic() && !m.isBridge()).map(m -> new ReflectionMethodDeclaration(m, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 127) Arrays.stream(clazz.getDeclaredMethods()).filter(m -> !m.isSynthetic() && !m.isBridge()).map(m -> new ReflectionMethodDeclaration(m, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 127) Arrays.stream(clazz.getDeclaredMethods()).filter(m -> !m.isSynthetic() && !m.isBridge()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 127) Arrays.stream(clazz.getDeclaredMethods()) ==> java.util.Arrays.stream(T[])
+  Line 127) clazz.getDeclaredMethods() ==> java.lang.Class.getDeclaredMethods()
+  Line 128) m.isSynthetic() ==> java.lang.reflect.Method.isSynthetic()
+  Line 128) m.isBridge() ==> java.lang.reflect.Method.isBridge()
+  Line 130) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 135) this.clazz.getTypeParameters() ==> java.lang.Class.getTypeParameters()
+  Line 136) params.add(new ReflectionTypeParameter(tv, true, typeSolver)) ==> java.util.List.add(E)
+  Line 146) isFunctionalInterface() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.isFunctionalInterface()
+  Line 148) type.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 151) type.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 154) type.describe().equals(typeDeclaration.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 154) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 154) typeDeclaration.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 159) otherTypeDeclaration.getTypeDeclaration().canBeAssignedTo(typeDeclaration) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 159) otherTypeDeclaration.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 166) clazz.getDeclaredAnnotations() ==> java.lang.Class.getDeclaredAnnotations()
+  Line 167) a.annotationType().getCanonicalName().equals(canonicalName) ==> java.lang.String.equals(java.lang.Object)
+  Line 167) a.annotationType().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 167) a.annotationType() ==> java.lang.annotation.Annotation.annotationType()
+  Line 175) FunctionalInterfaceLogic.getFunctionalMethod(typeDeclaration).isPresent() ==> java.util.Optional.isPresent()
+  Line 175) FunctionalInterfaceLogic.getFunctionalMethod(typeDeclaration) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 179) Arrays.stream(clazz.getConstructors()).map(m -> new ReflectionConstructorDeclaration(m, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 179) Arrays.stream(clazz.getConstructors()).map(m -> new ReflectionConstructorDeclaration(m, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 179) Arrays.stream(clazz.getConstructors()) ==> java.util.Arrays.stream(T[])
+  Line 179) clazz.getConstructors() ==> java.lang.Class.getConstructors()
+  Line 181) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 185) clazz.getDeclaringClass() ==> java.lang.Class.getDeclaringClass()
+  Line 187) Optional.empty() ==> java.util.Optional.empty()
+  Line 188) Optional.of(ReflectionFactory.typeDeclarationFor(declaringClass, typeSolver)) ==> java.util.Optional.of(T)
+  Line 188) ReflectionFactory.typeDeclarationFor(declaringClass, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeDeclarationFor(java.lang.Class<?>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionClassDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionClassDeclaration.txt
new file mode 100644
index 0000000..6b7eb56
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionClassDeclaration.txt
@@ -0,0 +1,121 @@
+  Line 62) clazz.isInterface() ==> java.lang.Class.isInterface()
+  Line 65) clazz.isPrimitive() ==> java.lang.Class.isPrimitive()
+  Line 68) clazz.isArray() ==> java.lang.Class.isArray()
+  Line 71) clazz.isEnum() ==> java.lang.Class.isEnum()
+  Line 85) reflectionClassAdapter.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getDeclaredMethods()
+  Line 90) reflectionClassAdapter.getAncestors() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getAncestors()
+  Line 96) getClass() ==> java.lang.Object.getClass()
+  Line 96) o.getClass() ==> java.lang.Object.getClass()
+  Line 100) clazz.getCanonicalName().equals(that.clazz.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 100) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 100) that.clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 107) clazz.hashCode() ==> java.lang.Object.hashCode()
+  Line 113) clazz.getPackage() ==> java.lang.Class.getPackage()
+  Line 114) clazz.getPackage().getName() ==> java.lang.Package.getName()
+  Line 114) clazz.getPackage() ==> java.lang.Class.getPackage()
+  Line 121) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 122) getPackageName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getPackageName()
+  Line 123) canonicalName.substring(getPackageName().length() + 1, canonicalName.length()) ==> java.lang.String.substring(int, int)
+  Line 123) getPackageName().length() ==> java.lang.String.length()
+  Line 123) getPackageName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getPackageName()
+  Line 123) canonicalName.length() ==> java.lang.String.length()
+  Line 130) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 136) Modifier.isStatic(m.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 136) m.getModifiers() ==> java.lang.reflect.Method.getModifiers()
+  Line 137) Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)).filter(staticFilter).sorted(new MethodComparator()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 137) Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)).filter(staticFilter).sorted(new MethodComparator()) ==> java.util.stream.Stream.sorted(java.util.Comparator<? super T>)
+  Line 137) Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)).filter(staticFilter) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 137) Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 137) Arrays.stream(clazz.getDeclaredMethods()) ==> java.util.Arrays.stream(T[])
+  Line 137) clazz.getDeclaredMethods() ==> java.lang.Class.getDeclaredMethods()
+  Line 137) m.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 137) m.getName() ==> java.lang.reflect.Method.getName()
+  Line 138) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 139) method.isBridge() ==> java.lang.reflect.Method.isBridge()
+  Line 139) method.isSynthetic() ==> java.lang.reflect.Method.isSynthetic()
+  Line 141) methods.add(methodDeclaration) ==> java.util.List.add(E)
+  Line 143) getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getSuperClass()
+  Line 144) getSuperClass().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 144) getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getSuperClass()
+  Line 145) MethodResolutionLogic.solveMethodInType(superClass, name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 146) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 147) methods.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 147) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 150) getInterfaces() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getInterfaces()
+  Line 151) MethodResolutionLogic.solveMethodInType(interfaceDeclaration.getTypeDeclaration(), name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 151) interfaceDeclaration.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 152) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 153) methods.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 153) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 156) MethodResolutionLogic.findMostApplicable(methods, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 162) getId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getId()
+  Line 173) Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)).sorted(new MethodComparator()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 173) Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)).sorted(new MethodComparator()) ==> java.util.stream.Stream.sorted(java.util.Comparator<? super T>)
+  Line 173) Arrays.stream(clazz.getDeclaredMethods()).filter((m) -> m.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 173) Arrays.stream(clazz.getDeclaredMethods()) ==> java.util.Arrays.stream(T[])
+  Line 173) clazz.getDeclaredMethods() ==> java.lang.Class.getDeclaredMethods()
+  Line 173) m.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 173) m.getName() ==> java.lang.reflect.Method.getName()
+  Line 173) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 174) method.isBridge() ==> java.lang.reflect.Method.isBridge()
+  Line 174) method.isSynthetic() ==> java.lang.reflect.Method.isSynthetic()
+  Line 177) getTypeParameters().size() ==> java.util.List.size()
+  Line 177) getTypeParameters() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getTypeParameters()
+  Line 177) typeParameterValues.size() ==> java.util.List.size()
+  Line 178) getTypeParameters().get(i) ==> java.util.List.get(int)
+  Line 178) getTypeParameters() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getTypeParameters()
+  Line 179) typeParameterValues.get(i) ==> java.util.List.get(int)
+  Line 180) methodUsage.replaceTypeParameter(tpToReplace, newValue) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceTypeParameter(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 182) methods.add(methodUsage) ==> java.util.List.add(E)
+  Line 184) getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getSuperClass()
+  Line 185) getSuperClass().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 185) getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getSuperClass()
+  Line 186) ContextHelper.solveMethodAsUsage(superClass, name, argumentsTypes, typeSolver, invokationContext, typeParameterValues) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ContextHelper.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 187) ref.isPresent() ==> java.util.Optional.isPresent()
+  Line 188) methods.add(ref.get()) ==> java.util.List.add(E)
+  Line 188) ref.get() ==> java.util.Optional.get()
+  Line 191) getInterfaces() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getInterfaces()
+  Line 192) ContextHelper.solveMethodAsUsage(interfaceDeclaration.getTypeDeclaration(), name, argumentsTypes, typeSolver, invokationContext, typeParameterValues) ==> com.github.javaparser.symbolsolver.javaparsermodel.contexts.ContextHelper.solveMethodAsUsage(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 192) interfaceDeclaration.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 193) ref.isPresent() ==> java.util.Optional.isPresent()
+  Line 194) methods.add(ref.get()) ==> java.util.List.add(E)
+  Line 194) ref.get() ==> java.util.Optional.get()
+  Line 197) MethodResolutionLogic.findMostApplicableUsage(methods, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicableUsage(java.util.List<com.github.javaparser.symbolsolver.model.methods.MethodUsage>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 204) isFunctionalInterface() ==> com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration.isFunctionalInterface()
+  Line 206) other.getQualifiedName().equals(getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 206) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 206) getQualifiedName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.getQualifiedName()
+  Line 209) this.clazz.getSuperclass() ==> java.lang.Class.getSuperclass()
+  Line 210) new ReflectionClassDeclaration(clazz.getSuperclass(), typeSolver).canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 210) clazz.getSuperclass() ==> java.lang.Class.getSuperclass()
+  Line 213) clazz.getInterfaces() ==> java.lang.Class.getInterfaces()
+  Line 214) new ReflectionInterfaceDeclaration(interfaze, typeSolver).canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 224) reflectionClassAdapter.isAssignableBy(type) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 234) reflectionClassAdapter.getField(name) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getField(java.lang.String)
+  Line 239) reflectionClassAdapter.getAllFields() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getAllFields()
+  Line 244) clazz.getFields() ==> java.lang.Class.getFields()
+  Line 245) field.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 245) field.getName() ==> java.lang.reflect.Field.getName()
+  Line 246) SymbolReference.solved(new ReflectionFieldDeclaration(field, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 249) SymbolReference.unsolved(ValueDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 254) reflectionClassAdapter.hasDirectlyAnnotation(canonicalName) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.hasDirectlyAnnotation(java.lang.String)
+  Line 259) reflectionClassAdapter.hasField(name) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.hasField(java.lang.String)
+  Line 264) isAssignableBy(new ReferenceTypeImpl(other, typeSolver)) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 269) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 289) clazz.isInterface() ==> java.lang.Class.isInterface()
+  Line 294) reflectionClassAdapter.getSuperClass() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getSuperClass()
+  Line 299) reflectionClassAdapter.getInterfaces() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getInterfaces()
+  Line 304) clazz.isInterface() ==> java.lang.Class.isInterface()
+  Line 309) reflectionClassAdapter.getTypeParameters() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getTypeParameters()
+  Line 314) ReflectionFactory.modifiersToAccessLevel(this.clazz.getModifiers()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.modifiersToAccessLevel(int)
+  Line 314) this.clazz.getModifiers() ==> java.lang.Class.getModifiers()
+  Line 319) reflectionClassAdapter.getConstructors() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getConstructors()
+  Line 324) reflectionClassAdapter.containerType() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.containerType()
+  Line 329) Arrays.stream(this.clazz.getDeclaredClasses()).map(ic -> ReflectionFactory.typeDeclarationFor(ic, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 329) Arrays.stream(this.clazz.getDeclaredClasses()).map(ic -> ReflectionFactory.typeDeclarationFor(ic, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 329) Arrays.stream(this.clazz.getDeclaredClasses()) ==> java.util.Arrays.stream(T[])
+  Line 329) this.clazz.getDeclaredClasses() ==> java.lang.Class.getDeclaredClasses()
+  Line 330) ReflectionFactory.typeDeclarationFor(ic, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeDeclarationFor(java.lang.Class<?>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 331) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 340) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 340) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionConstructorDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionConstructorDeclaration.txt
new file mode 100644
index 0000000..8a179d6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionConstructorDeclaration.txt
@@ -0,0 +1,17 @@
+  Line 43) constructor.getDeclaringClass() ==> java.lang.reflect.Constructor.getDeclaringClass()
+  Line 48) constructor.getParameterCount() ==> java.lang.reflect.Constructor.getParameterCount()
+  Line 53) getNumberOfParams() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionConstructorDeclaration.getNumberOfParams()
+  Line 54) String.format("No param with index %d. Number of params: %d", i, getNumberOfParams()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 54) getNumberOfParams() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionConstructorDeclaration.getNumberOfParams()
+  Line 57) constructor.isVarArgs() ==> java.lang.reflect.Constructor.isVarArgs()
+  Line 58) constructor.getParameterCount() ==> java.lang.reflect.Constructor.getParameterCount()
+  Line 60) constructor.getParameterTypes() ==> java.lang.reflect.Constructor.getParameterTypes()
+  Line 60) constructor.getGenericParameterTypes() ==> java.lang.reflect.Constructor.getGenericParameterTypes()
+  Line 65) constructor.getName() ==> java.lang.reflect.Constructor.getName()
+  Line 70) ReflectionFactory.modifiersToAccessLevel(constructor.getModifiers()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.modifiersToAccessLevel(int)
+  Line 70) constructor.getModifiers() ==> java.lang.reflect.Constructor.getModifiers()
+  Line 75) Arrays.stream(constructor.getTypeParameters()).map((refTp) -> new ReflectionTypeParameter(refTp, false, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 75) Arrays.stream(constructor.getTypeParameters()).map((refTp) -> new ReflectionTypeParameter(refTp, false, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 75) Arrays.stream(constructor.getTypeParameters()) ==> java.util.Arrays.stream(T[])
+  Line 75) constructor.getTypeParameters() ==> java.lang.reflect.Constructor.getTypeParameters()
+  Line 75) Collectors.toList() ==> java.util.stream.Collectors.toList()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionEnumDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionEnumDeclaration.txt
new file mode 100644
index 0000000..13a8fc9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionEnumDeclaration.txt
@@ -0,0 +1,44 @@
+  Line 52) clazz.isInterface() ==> java.lang.Class.isInterface()
+  Line 55) clazz.isPrimitive() ==> java.lang.Class.isPrimitive()
+  Line 58) clazz.isArray() ==> java.lang.Class.isArray()
+  Line 61) clazz.isEnum() ==> java.lang.Class.isEnum()
+  Line 75) ReflectionFactory.modifiersToAccessLevel(this.clazz.getModifiers()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.modifiersToAccessLevel(int)
+  Line 75) this.clazz.getModifiers() ==> java.lang.Class.getModifiers()
+  Line 80) reflectionClassAdapter.containerType() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.containerType()
+  Line 85) clazz.getPackage() ==> java.lang.Class.getPackage()
+  Line 86) clazz.getPackage().getName() ==> java.lang.Package.getName()
+  Line 86) clazz.getPackage() ==> java.lang.Class.getPackage()
+  Line 93) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 94) getPackageName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration.getPackageName()
+  Line 95) canonicalName.substring(getPackageName().length() + 1, canonicalName.length()) ==> java.lang.String.substring(int, int)
+  Line 95) getPackageName().length() ==> java.lang.String.length()
+  Line 95) getPackageName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration.getPackageName()
+  Line 95) canonicalName.length() ==> java.lang.String.length()
+  Line 102) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 107) reflectionClassAdapter.getAncestors() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getAncestors()
+  Line 112) reflectionClassAdapter.getField(name) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getField(java.lang.String)
+  Line 117) reflectionClassAdapter.hasField(name) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.hasField(java.lang.String)
+  Line 122) reflectionClassAdapter.getAllFields() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getAllFields()
+  Line 127) reflectionClassAdapter.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getDeclaredMethods()
+  Line 132) reflectionClassAdapter.isAssignableBy(type) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 137) isAssignableBy(new ReferenceTypeImpl(other, typeSolver)) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 142) reflectionClassAdapter.hasDirectlyAnnotation(qualifiedName) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.hasDirectlyAnnotation(java.lang.String)
+  Line 147) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 152) reflectionClassAdapter.getTypeParameters() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getTypeParameters()
+  Line 156) ReflectionMethodResolutionLogic.solveMethod(name, parameterTypes, staticOnly, typeSolver, this, clazz) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodResolutionLogic.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.lang.Class)
+  Line 161) ReflectionMethodResolutionLogic.solveMethodAsUsage(name, parameterTypes, typeSolver, invokationContext, typeParameterValues, this, clazz) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodResolutionLogic.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.lang.Class)
+  Line 163) res.isPresent() ==> java.util.Optional.isPresent()
+  Line 166) res.get() ==> java.util.Optional.get()
+  Line 170) methodUsage.getParamType(i) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 173) parameters.add(inferenceContext.addPair(formalType, actualType)) ==> java.util.List.add(E)
+  Line 173) inferenceContext.addPair(formalType, actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 177) inferenceContext.addSingle(methodUsage.returnType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 177) methodUsage.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 178) parameters.size() ==> java.util.List.size()
+  Line 179) methodUsage.replaceParamType(j, inferenceContext.resolve(parameters.get(j))) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceParamType(int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 179) inferenceContext.resolve(parameters.get(j)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 179) parameters.get(j) ==> java.util.List.get(int)
+  Line 181) methodUsage.replaceReturnType(inferenceContext.resolve(returnType)) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceReturnType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 181) inferenceContext.resolve(returnType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 182) Optional.of(methodUsage) ==> java.util.Optional.of(T)
+  Line 184) Optional.empty() ==> java.util.Optional.empty()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionFactory.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionFactory.txt
new file mode 100644
index 0000000..71f67fe
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionFactory.txt
@@ -0,0 +1,48 @@
+  Line 39) clazz.isArray() ==> java.lang.Class.isArray()
+  Line 41) clazz.isPrimitive() ==> java.lang.Class.isPrimitive()
+  Line 43) clazz.isInterface() ==> java.lang.Class.isInterface()
+  Line 45) clazz.isEnum() ==> java.lang.Class.isEnum()
+  Line 55) tv.getGenericDeclaration() ==> java.lang.reflect.TypeVariable.getGenericDeclaration()
+  Line 60) typeUsageFor(pt.getRawType(), typeSolver).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 60) typeUsageFor(pt.getRawType(), typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 60) pt.getRawType() ==> java.lang.reflect.ParameterizedType.getRawType()
+  Line 62) actualTypes.addAll(Arrays.asList(pt.getActualTypeArguments())) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 62) Arrays.asList(pt.getActualTypeArguments()) ==> java.util.Arrays.asList(T...)
+  Line 62) pt.getActualTypeArguments() ==> java.lang.reflect.ParameterizedType.getActualTypeArguments()
+  Line 64) rawType.transformTypeParameters(tp -> typeUsageFor(actualTypes.remove(0), typeSolver)).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 64) rawType.transformTypeParameters(tp -> typeUsageFor(actualTypes.remove(0), typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.transformTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer)
+  Line 64) typeUsageFor(actualTypes.remove(0), typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 64) actualTypes.remove(0) ==> java.util.List.remove(int)
+  Line 68) c.isPrimitive() ==> java.lang.Class.isPrimitive()
+  Line 69) c.getName().equals(Void.TYPE.getName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 69) c.getName() ==> java.lang.Class.getName()
+  Line 69) Void.TYPE.getName() ==> java.lang.Class.getName()
+  Line 72) PrimitiveType.byName(c.getName()) ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.byName(java.lang.String)
+  Line 72) c.getName() ==> java.lang.Class.getName()
+  Line 74) c.isArray() ==> java.lang.Class.isArray()
+  Line 75) typeUsageFor(c.getComponentType(), typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 75) c.getComponentType() ==> java.lang.Class.getComponentType()
+  Line 77) typeDeclarationFor(c, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeDeclarationFor(java.lang.Class<?>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 81) typeUsageFor(genericArrayType.getGenericComponentType(), typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 81) genericArrayType.getGenericComponentType() ==> java.lang.reflect.GenericArrayType.getGenericComponentType()
+  Line 84) wildcardType.getLowerBounds() ==> java.lang.reflect.WildcardType.getLowerBounds()
+  Line 84) wildcardType.getUpperBounds() ==> java.lang.reflect.WildcardType.getUpperBounds()
+  Line 85) wildcardType.getUpperBounds() ==> java.lang.reflect.WildcardType.getUpperBounds()
+  Line 85) wildcardType.getUpperBounds()[0].getTypeName().equals("java.lang.Object") ==> java.lang.String.equals(java.lang.Object)
+  Line 85) wildcardType.getUpperBounds()[0].getTypeName() ==> java.lang.reflect.Type.getTypeName()
+  Line 85) wildcardType.getUpperBounds() ==> java.lang.reflect.WildcardType.getUpperBounds()
+  Line 89) wildcardType.getLowerBounds() ==> java.lang.reflect.WildcardType.getLowerBounds()
+  Line 90) wildcardType.getLowerBounds() ==> java.lang.reflect.WildcardType.getLowerBounds()
+  Line 93) Wildcard.superBound(typeUsageFor(wildcardType.getLowerBounds()[0], typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 93) typeUsageFor(wildcardType.getLowerBounds()[0], typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 93) wildcardType.getLowerBounds() ==> java.lang.reflect.WildcardType.getLowerBounds()
+  Line 95) wildcardType.getUpperBounds() ==> java.lang.reflect.WildcardType.getUpperBounds()
+  Line 96) wildcardType.getUpperBounds() ==> java.lang.reflect.WildcardType.getUpperBounds()
+  Line 99) Wildcard.extendsBound(typeUsageFor(wildcardType.getUpperBounds()[0], typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 99) typeUsageFor(wildcardType.getUpperBounds()[0], typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 99) wildcardType.getUpperBounds() ==> java.lang.reflect.WildcardType.getUpperBounds()
+  Line 103) type.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 103) type.getClass() ==> java.lang.Object.getClass()
+  Line 108) Modifier.isPublic(modifiers) ==> java.lang.reflect.Modifier.isPublic(int)
+  Line 110) Modifier.isProtected(modifiers) ==> java.lang.reflect.Modifier.isProtected(int)
+  Line 112) Modifier.isPrivate(modifiers) ==> java.lang.reflect.Modifier.isPrivate(int)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionFieldDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionFieldDeclaration.txt
new file mode 100644
index 0000000..9c929b2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionFieldDeclaration.txt
@@ -0,0 +1,10 @@
+  Line 40) calcType() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFieldDeclaration.calcType()
+  Line 56) ReflectionFactory.typeUsageFor(field.getGenericType(), typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 56) field.getGenericType() ==> java.lang.reflect.Field.getGenericType()
+  Line 61) field.getName() ==> java.lang.reflect.Field.getName()
+  Line 66) Modifier.isStatic(field.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 66) field.getModifiers() ==> java.lang.reflect.Field.getModifiers()
+  Line 76) ReflectionFactory.typeDeclarationFor(field.getDeclaringClass(), typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeDeclarationFor(java.lang.Class<?>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 76) field.getDeclaringClass() ==> java.lang.reflect.Field.getDeclaringClass()
+  Line 95) ReflectionFactory.modifiersToAccessLevel(field.getModifiers()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.modifiersToAccessLevel(int)
+  Line 95) field.getModifiers() ==> java.lang.reflect.Field.getModifiers()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionInterfaceDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionInterfaceDeclaration.txt
new file mode 100644
index 0000000..6ee2485
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionInterfaceDeclaration.txt
@@ -0,0 +1,81 @@
+  Line 56) clazz.isInterface() ==> java.lang.Class.isInterface()
+  Line 71) isAssignableBy(new ReferenceTypeImpl(other, typeSolver)) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 76) clazz.getPackage() ==> java.lang.Class.getPackage()
+  Line 77) clazz.getPackage().getName() ==> java.lang.Package.getName()
+  Line 77) clazz.getPackage() ==> java.lang.Class.getPackage()
+  Line 84) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 85) getPackageName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.getPackageName()
+  Line 86) canonicalName.substring(getPackageName().length() + 1, canonicalName.length()) ==> java.lang.String.substring(int, int)
+  Line 86) getPackageName().length() ==> java.lang.String.length()
+  Line 86) getPackageName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.getPackageName()
+  Line 86) canonicalName.length() ==> java.lang.String.length()
+  Line 93) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 98) ReflectionMethodResolutionLogic.solveMethod(name, parameterTypes, staticOnly, typeSolver, this, clazz) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodResolutionLogic.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.lang.Class)
+  Line 105) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 120) clazz.getCanonicalName().equals(that.clazz.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 120) clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 120) that.clazz.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 122) getTypeParameters().equals(that.getTypeParameters()) ==> java.util.List.equals(java.lang.Object)
+  Line 122) getTypeParameters() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.getTypeParameters()
+  Line 122) that.getTypeParameters() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.getTypeParameters()
+  Line 131) clazz.hashCode() ==> java.lang.Object.hashCode()
+  Line 135) ReflectionMethodResolutionLogic.solveMethodAsUsage(name, parameterTypes, typeSolver, invokationContext, typeParameterValues, this, clazz) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodResolutionLogic.solveMethodAsUsage(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.lang.Class)
+  Line 137) res.isPresent() ==> java.util.Optional.isPresent()
+  Line 140) res.get() ==> java.util.Optional.get()
+  Line 144) methodUsage.getParamType(i) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 147) parameters.add(inferenceContext.addPair(formalType, actualType)) ==> java.util.List.add(E)
+  Line 147) inferenceContext.addPair(formalType, actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addPair(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 151) inferenceContext.addSingle(methodUsage.returnType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.addSingle(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 151) methodUsage.returnType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.returnType()
+  Line 152) parameters.size() ==> java.util.List.size()
+  Line 153) methodUsage.replaceParamType(j, inferenceContext.resolve(parameters.get(j))) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceParamType(int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 153) inferenceContext.resolve(parameters.get(j)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 153) parameters.get(j) ==> java.util.List.get(int)
+  Line 155) methodUsage.replaceReturnType(inferenceContext.resolve(returnType)) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceReturnType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 155) inferenceContext.resolve(returnType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 156) Optional.of(methodUsage) ==> java.util.Optional.of(T)
+  Line 158) Optional.empty() ==> java.util.Optional.empty()
+  Line 168) isFunctionalInterface() ==> com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration.isFunctionalInterface()
+  Line 170) other.getQualifiedName().equals(getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 170) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 170) getQualifiedName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.getQualifiedName()
+  Line 173) this.clazz.getSuperclass() ==> java.lang.Class.getSuperclass()
+  Line 174) new ReflectionInterfaceDeclaration(clazz.getSuperclass(), typeSolver).canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 174) clazz.getSuperclass() ==> java.lang.Class.getSuperclass()
+  Line 177) clazz.getInterfaces() ==> java.lang.Class.getInterfaces()
+  Line 178) new ReflectionInterfaceDeclaration(interfaze, typeSolver).canBeAssignedTo(other) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 183) other.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 183) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 183) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 196) isFunctionalInterface() ==> com.github.javaparser.symbolsolver.logic.AbstractTypeDeclaration.isFunctionalInterface()
+  Line 198) type.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 201) type.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 204) type.describe().equals(getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 204) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 204) getQualifiedName() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.getQualifiedName()
+  Line 209) otherTypeDeclaration.getTypeDeclaration().canBeAssignedTo(this) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.canBeAssignedTo(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 209) otherTypeDeclaration.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 222) reflectionClassAdapter.getField(name) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getField(java.lang.String)
+  Line 227) reflectionClassAdapter.getAllFields() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getAllFields()
+  Line 232) clazz.getFields() ==> java.lang.Class.getFields()
+  Line 233) field.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 233) field.getName() ==> java.lang.reflect.Field.getName()
+  Line 234) SymbolReference.solved(new ReflectionFieldDeclaration(field, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 237) SymbolReference.unsolved(ValueDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 242) reflectionClassAdapter.getAncestors() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getAncestors()
+  Line 247) reflectionClassAdapter.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getDeclaredMethods()
+  Line 252) reflectionClassAdapter.hasField(name) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.hasField(java.lang.String)
+  Line 257) clazz.getSimpleName() ==> java.lang.Class.getSimpleName()
+  Line 268) clazz.getInterfaces() ==> java.lang.Class.getInterfaces()
+  Line 269) res.add(new ReferenceTypeImpl(new ReflectionInterfaceDeclaration(i, typeSolver), typeSolver)) ==> java.util.List.add(E)
+  Line 276) reflectionClassAdapter.containerType() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.containerType()
+  Line 281) Arrays.stream(this.clazz.getDeclaredClasses()).map(ic -> ReflectionFactory.typeDeclarationFor(ic, typeSolver)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 281) Arrays.stream(this.clazz.getDeclaredClasses()).map(ic -> ReflectionFactory.typeDeclarationFor(ic, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 281) Arrays.stream(this.clazz.getDeclaredClasses()) ==> java.util.Arrays.stream(T[])
+  Line 281) this.clazz.getDeclaredClasses() ==> java.lang.Class.getDeclaredClasses()
+  Line 282) ReflectionFactory.typeDeclarationFor(ic, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeDeclarationFor(java.lang.Class<?>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 283) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 293) reflectionClassAdapter.hasDirectlyAnnotation(canonicalName) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.hasDirectlyAnnotation(java.lang.String)
+  Line 298) reflectionClassAdapter.getTypeParameters() ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassAdapter.getTypeParameters()
+  Line 303) ReflectionFactory.modifiersToAccessLevel(this.clazz.getModifiers()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.modifiersToAccessLevel(int)
+  Line 303) this.clazz.getModifiers() ==> java.lang.Class.getModifiers()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionMethodDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionMethodDeclaration.txt
new file mode 100644
index 0000000..f8a3230
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionMethodDeclaration.txt
@@ -0,0 +1,30 @@
+  Line 42) method.isSynthetic() ==> java.lang.reflect.Method.isSynthetic()
+  Line 42) method.isBridge() ==> java.lang.reflect.Method.isBridge()
+  Line 50) method.getName() ==> java.lang.reflect.Method.getName()
+  Line 77) method.getDeclaringClass().isInterface() ==> java.lang.Class.isInterface()
+  Line 77) method.getDeclaringClass() ==> java.lang.reflect.Method.getDeclaringClass()
+  Line 78) method.getDeclaringClass() ==> java.lang.reflect.Method.getDeclaringClass()
+  Line 80) method.getDeclaringClass().isEnum() ==> java.lang.Class.isEnum()
+  Line 80) method.getDeclaringClass() ==> java.lang.reflect.Method.getDeclaringClass()
+  Line 81) method.getDeclaringClass() ==> java.lang.reflect.Method.getDeclaringClass()
+  Line 83) method.getDeclaringClass() ==> java.lang.reflect.Method.getDeclaringClass()
+  Line 89) ReflectionFactory.typeUsageFor(method.getGenericReturnType(), typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 89) method.getGenericReturnType() ==> java.lang.reflect.Method.getGenericReturnType()
+  Line 94) method.getParameterTypes() ==> java.lang.reflect.Method.getParameterTypes()
+  Line 100) method.isVarArgs() ==> java.lang.reflect.Method.isVarArgs()
+  Line 101) method.getParameterCount() ==> java.lang.reflect.Method.getParameterCount()
+  Line 103) method.getParameterTypes() ==> java.lang.reflect.Method.getParameterTypes()
+  Line 103) method.getGenericParameterTypes() ==> java.lang.reflect.Method.getGenericParameterTypes()
+  Line 108) Arrays.stream(method.getTypeParameters()).map((refTp) -> new ReflectionTypeParameter(refTp, false, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 108) Arrays.stream(method.getTypeParameters()).map((refTp) -> new ReflectionTypeParameter(refTp, false, typeSolver)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 108) Arrays.stream(method.getTypeParameters()) ==> java.util.Arrays.stream(T[])
+  Line 108) method.getTypeParameters() ==> java.lang.reflect.Method.getTypeParameters()
+  Line 108) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 112) new MethodDeclarationCommonLogic(this, typeSolver).resolveTypeVariables(context, parameterTypes) ==> com.github.javaparser.symbolsolver.declarations.common.MethodDeclarationCommonLogic.resolveTypeVariables(com.github.javaparser.symbolsolver.core.resolution.Context, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 117) Modifier.isAbstract(method.getModifiers()) ==> java.lang.reflect.Modifier.isAbstract(int)
+  Line 117) method.getModifiers() ==> java.lang.reflect.Method.getModifiers()
+  Line 122) method.isDefault() ==> java.lang.reflect.Method.isDefault()
+  Line 127) Modifier.isStatic(method.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 127) method.getModifiers() ==> java.lang.reflect.Method.getModifiers()
+  Line 132) ReflectionFactory.modifiersToAccessLevel(this.method.getModifiers()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.modifiersToAccessLevel(int)
+  Line 132) this.method.getModifiers() ==> java.lang.reflect.Method.getModifiers()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionMethodResolutionLogic.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionMethodResolutionLogic.txt
new file mode 100644
index 0000000..e7a4975
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionMethodResolutionLogic.txt
@@ -0,0 +1,85 @@
+  Line 49) Modifier.isStatic(m.getModifiers()) ==> java.lang.reflect.Modifier.isStatic(int)
+  Line 49) m.getModifiers() ==> java.lang.reflect.Method.getModifiers()
+  Line 50) clazz.getMethods() ==> java.lang.Class.getMethods()
+  Line 51) method.isBridge() ==> java.lang.reflect.Method.isBridge()
+  Line 51) method.isSynthetic() ==> java.lang.reflect.Method.isSynthetic()
+  Line 51) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 51) method.getName() ==> java.lang.reflect.Method.getName()
+  Line 51) staticOnlyCheck.test(method) ==> java.util.function.Predicate.test(T)
+  Line 53) methods.add(methodDeclaration) ==> java.util.List.add(E)
+  Line 56) scopeType.getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 57) MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, parameterTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 57) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 58) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 59) methods.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 59) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 63) scopeType.getAncestors().isEmpty() ==> java.util.List.isEmpty()
+  Line 63) scopeType.getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 65) MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, parameterTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 65) objectClass.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 66) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 67) methods.add(ref.getCorrespondingDeclaration()) ==> java.util.List.add(E)
+  Line 67) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 70) MethodResolutionLogic.findMostApplicable(methods, name, parameterTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 76) typeParameterValues.size() ==> java.util.List.size()
+  Line 76) scopeType.getTypeParameters().size() ==> java.util.List.size()
+  Line 76) scopeType.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 78) scopeType.getTypeParameters().isEmpty() ==> java.util.List.isEmpty()
+  Line 78) scopeType.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 81) scopeType.getTypeParameters().size() ==> java.util.List.size()
+  Line 81) scopeType.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 82) typeParameterValues.add(new ReferenceTypeImpl(new ReflectionClassDeclaration(Object.class, typeSolver), typeSolver)) ==> java.util.List.add(E)
+  Line 87) clazz.getMethods() ==> java.lang.Class.getMethods()
+  Line 88) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 88) method.getName() ==> java.lang.reflect.Method.getName()
+  Line 88) method.isBridge() ==> java.lang.reflect.Method.isBridge()
+  Line 88) method.isSynthetic() ==> java.lang.reflect.Method.isSynthetic()
+  Line 90) replaceParams(typeParameterValues, scopeType, methodDeclaration) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodResolutionLogic.replaceParams(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration)
+  Line 91) methods.add(methodUsage) ==> java.util.List.add(E)
+  Line 96) scopeType.getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 97) MethodResolutionLogic.solveMethodInType(ancestor.getTypeDeclaration(), name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 97) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 98) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 99) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 100) replaceParams(typeParameterValues, ancestor.getTypeDeclaration(), correspondingDeclaration) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodResolutionLogic.replaceParams(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration)
+  Line 100) ancestor.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 101) methods.add(methodUsage) ==> java.util.List.add(E)
+  Line 105) scopeType.getAncestors().isEmpty() ==> java.util.List.isEmpty()
+  Line 105) scopeType.getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 107) MethodResolutionLogic.solveMethodInType(objectClass.getTypeDeclaration(), name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 107) objectClass.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 108) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 109) replaceParams(typeParameterValues, objectClass.getTypeDeclaration(), ref.getCorrespondingDeclaration()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionMethodResolutionLogic.replaceParams(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration)
+  Line 109) objectClass.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 109) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 110) methods.add(usage) ==> java.util.List.add(E)
+  Line 115) argumentsTypes.stream().map((pt) -> {
+    int i = 0;
+    for (TypeParameterDeclaration tp : scopeType.getTypeParameters()) {
+        pt = pt.replaceTypeVariables(tp, finalTypeParameterValues.get(i));
+        i++;
+    }
+    return pt;
+}).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 115) argumentsTypes.stream().map((pt) -> {
+    int i = 0;
+    for (TypeParameterDeclaration tp : scopeType.getTypeParameters()) {
+        pt = pt.replaceTypeVariables(tp, finalTypeParameterValues.get(i));
+        i++;
+    }
+    return pt;
+}) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 115) argumentsTypes.stream() ==> java.util.Collection.stream()
+  Line 117) scopeType.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 118) pt.replaceTypeVariables(tp, finalTypeParameterValues.get(i)) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 118) finalTypeParameterValues.get(i) ==> java.util.List.get(int)
+  Line 122) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 123) MethodResolutionLogic.findMostApplicableUsage(methods, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicableUsage(java.util.List<com.github.javaparser.symbolsolver.model.methods.MethodUsage>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 131) typeParameterValues.size() ==> java.util.List.size()
+  Line 131) typeParametrizable.getTypeParameters().size() ==> java.util.List.size()
+  Line 131) typeParametrizable.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 132) typeParametrizable.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 133) methodUsage.replaceTypeParameter(tp, typeParameterValues.get(i)) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceTypeParameter(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 133) typeParameterValues.get(i) ==> java.util.List.get(int)
+  Line 138) methodDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 139) methodUsage.replaceTypeParameter(methodTypeParameter, new TypeVariable(methodTypeParameter)) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceTypeParameter(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionParameterDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionParameterDeclaration.txt
new file mode 100644
index 0000000..5e1a33b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionParameterDeclaration.txt
@@ -0,0 +1 @@
+  Line 73) ReflectionFactory.typeUsageFor(genericType, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionTypeParameter.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionTypeParameter.txt
new file mode 100644
index 0000000..39aa151
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_ReflectionTypeParameter.txt
@@ -0,0 +1,25 @@
+  Line 44) typeVariable.getGenericDeclaration() ==> java.lang.reflect.TypeVariable.getGenericDeclaration()
+  Line 46) ReflectionFactory.typeDeclarationFor((Class) genericDeclaration, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeDeclarationFor(java.lang.Class<?>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 63) getQualifiedName().equals(that.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 63) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 63) that.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 66) declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 66) that.declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 69) declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 69) that.declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 78) typeVariable.hashCode() ==> java.lang.Object.hashCode()
+  Line 79) container.hashCode() ==> java.lang.Object.hashCode()
+  Line 85) typeVariable.getName() ==> java.lang.reflect.TypeVariable.getName()
+  Line 91) ((ReferenceTypeDeclaration) container).getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 93) ((MethodLikeDeclaration) container).getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 100) ((ReferenceTypeDeclaration) container).getId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getId()
+  Line 102) ((MethodLikeDeclaration) container).getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 113) Arrays.stream(typeVariable.getBounds()).map((refB) -> Bound.extendsBound(ReflectionFactory.typeUsageFor(refB, typeSolver))).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 113) Arrays.stream(typeVariable.getBounds()).map((refB) -> Bound.extendsBound(ReflectionFactory.typeUsageFor(refB, typeSolver))) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 113) Arrays.stream(typeVariable.getBounds()) ==> java.util.Arrays.stream(T[])
+  Line 113) typeVariable.getBounds() ==> java.lang.reflect.TypeVariable.getBounds()
+  Line 113) Bound.extendsBound(ReflectionFactory.typeUsageFor(refB, typeSolver)) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 113) ReflectionFactory.typeUsageFor(refB, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeUsageFor(java.lang.reflect.Type, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 113) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 126) Optional.of((ReferenceTypeDeclaration) container) ==> java.util.Optional.of(T)
+  Line 128) Optional.empty() ==> java.util.Optional.empty()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_ClassComparator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_ClassComparator.txt
new file mode 100644
index 0000000..fdb9ae9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_ClassComparator.txt
@@ -0,0 +1,15 @@
+  Line 13) o1.getCanonicalName().compareTo(o2.getCanonicalName()) ==> java.lang.String.compareTo(java.lang.String)
+  Line 13) o1.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 13) o2.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 15) Boolean.compare(o1.isAnnotation(), o2.isAnnotation()) ==> java.lang.Boolean.compare(boolean, boolean)
+  Line 15) o1.isAnnotation() ==> java.lang.Class.isAnnotation()
+  Line 15) o2.isAnnotation() ==> java.lang.Class.isAnnotation()
+  Line 17) Boolean.compare(o1.isArray(), o2.isArray()) ==> java.lang.Boolean.compare(boolean, boolean)
+  Line 17) o1.isArray() ==> java.lang.Class.isArray()
+  Line 17) o2.isArray() ==> java.lang.Class.isArray()
+  Line 19) Boolean.compare(o1.isEnum(), o2.isEnum()) ==> java.lang.Boolean.compare(boolean, boolean)
+  Line 19) o1.isEnum() ==> java.lang.Class.isEnum()
+  Line 19) o2.isEnum() ==> java.lang.Class.isEnum()
+  Line 21) Boolean.compare(o1.isInterface(), o2.isInterface()) ==> java.lang.Boolean.compare(boolean, boolean)
+  Line 21) o1.isInterface() ==> java.lang.Class.isInterface()
+  Line 21) o2.isInterface() ==> java.lang.Class.isInterface()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_MethodComparator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_MethodComparator.txt
new file mode 100644
index 0000000..c900b94
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_MethodComparator.txt
@@ -0,0 +1,12 @@
+  Line 13) o1.getName().compareTo(o2.getName()) ==> java.lang.String.compareTo(java.lang.String)
+  Line 13) o1.getName() ==> java.lang.reflect.Method.getName()
+  Line 13) o2.getName() ==> java.lang.reflect.Method.getName()
+  Line 15) o1.getParameterCount() ==> java.lang.reflect.Method.getParameterCount()
+  Line 15) o2.getParameterCount() ==> java.lang.reflect.Method.getParameterCount()
+  Line 17) o1.getParameterCount() ==> java.lang.reflect.Method.getParameterCount()
+  Line 18) new ParameterComparator().compare(o1.getParameters()[i], o2.getParameters()[i]) ==> com.github.javaparser.symbolsolver.reflectionmodel.comparators.ParameterComparator.compare(java.lang.reflect.Parameter, java.lang.reflect.Parameter)
+  Line 18) o1.getParameters() ==> java.lang.reflect.Executable.getParameters()
+  Line 18) o2.getParameters() ==> java.lang.reflect.Executable.getParameters()
+  Line 21) new ClassComparator().compare(o1.getReturnType(), o2.getReturnType()) ==> com.github.javaparser.symbolsolver.reflectionmodel.comparators.ClassComparator.compare(java.lang.Class<?>, java.lang.Class<?>)
+  Line 21) o1.getReturnType() ==> java.lang.reflect.Method.getReturnType()
+  Line 21) o2.getReturnType() ==> java.lang.reflect.Method.getReturnType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_ParameterComparator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_ParameterComparator.txt
new file mode 100644
index 0000000..e4ab629
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_reflectionmodel_comparators_ParameterComparator.txt
@@ -0,0 +1,6 @@
+  Line 13) o1.getName().compareTo(o2.getName()) ==> java.lang.String.compareTo(java.lang.String)
+  Line 13) o1.getName() ==> java.lang.reflect.Parameter.getName()
+  Line 13) o2.getName() ==> java.lang.reflect.Parameter.getName()
+  Line 15) new ClassComparator().compare(o1.getType(), o2.getType()) ==> com.github.javaparser.symbolsolver.reflectionmodel.comparators.ClassComparator.compare(java.lang.Class<?>, java.lang.Class<?>)
+  Line 15) o1.getType() ==> java.lang.reflect.Parameter.getType()
+  Line 15) o2.getType() ==> java.lang.reflect.Parameter.getType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_ConstructorResolutionLogic.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_ConstructorResolutionLogic.txt
new file mode 100644
index 0000000..e45c8b8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_ConstructorResolutionLogic.txt
@@ -0,0 +1,110 @@
+  Line 38) argumentsTypes.subList(0, startVariadic) ==> java.util.List.subList(int, int)
+  Line 39) argumentsTypes.subList(startVariadic, argumentsTypes.size()) ==> java.util.List.subList(int, int)
+  Line 39) argumentsTypes.size() ==> java.util.List.size()
+  Line 40) variadicValues.isEmpty() ==> java.util.List.isEmpty()
+  Line 42) res.add(variadicType) ==> java.util.List.add(E)
+  Line 44) findCommonType(variadicValues) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.findCommonType(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 45) res.add(new ArrayType(componentType)) ==> java.util.List.add(E)
+  Line 51) variadicValues.isEmpty() ==> java.util.List.isEmpty()
+  Line 55) variadicValues.get(0) ==> java.util.List.get(int)
+  Line 60) isApplicable(constructor, argumentsTypes, typeSolver, false) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.isApplicable(com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 65) constructor.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 66) constructor.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 67) constructor.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 67) argumentsTypes.size() ==> java.util.List.size()
+  Line 69) constructor.getLastParam().getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 69) constructor.getLastParam() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getLastParam()
+  Line 70) argumentsTypes.get(pos) ==> java.util.List.get(int)
+  Line 71) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 72) constructor.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 73) MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.replaceTypeParam(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 75) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 76) actualType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 77) expectedType.isAssignableBy(actualType.asArrayType().getComponentType()) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 77) actualType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 77) actualType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 78) argumentsTypes.set(pos, actualType.asArrayType().getComponentType()) ==> java.util.List.set(int, E)
+  Line 78) actualType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 78) actualType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 80) groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType()) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.groupVariadicParamValues(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 81) constructor.getLastParam().getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 81) constructor.getLastParam() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getLastParam()
+  Line 86) argumentsTypes.size() ==> java.util.List.size()
+  Line 90) groupVariadicParamValues(argumentsTypes, pos, constructor.getLastParam().getType()) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.groupVariadicParamValues(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 90) constructor.getLastParam().getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 90) constructor.getLastParam() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getLastParam()
+  Line 94) constructor.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 94) argumentsTypes.size() ==> java.util.List.size()
+  Line 99) constructor.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 100) constructor.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 100) constructor.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 101) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 102) expectedType.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 102) expectedType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 103) expectedType.asTypeParameter().declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 103) expectedType.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 104) matchedParameters.put(expectedType.asTypeParameter().getName(), actualType) ==> java.util.Map.put(K, V)
+  Line 104) expectedType.asTypeParameter().getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 104) expectedType.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 108) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 108) constructor.getParam(i).isVariadic() ==> com.github.javaparser.symbolsolver.model.declarations.ParameterDeclaration.isVariadic()
+  Line 108) constructor.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 109) new ArrayType(expectedType).isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 110) expectedType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 111) actualType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 112) MethodResolutionLogic.isAssignableMatchTypeParameters(expectedType.asReferenceType(), actualType.asReferenceType(), matchedParameters) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isAssignableMatchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.util.Map<java.lang.String, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 113) expectedType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 113) actualType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 116) constructor.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 117) typeParameters.addAll(constructor.declaringType().getTypeParameters()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 117) constructor.declaringType().getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 117) constructor.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration.declaringType()
+  Line 119) MethodResolutionLogic.replaceTypeParam(expectedType, tp, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.replaceTypeParam(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 122) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 123) actualType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 123) expectedType.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 127) constructor.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 127) constructor.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 128) new ArrayType(expectedType).isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 149) findMostApplicable(constructors, argumentsTypes, typeSolver, false) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration>, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 150) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 153) findMostApplicable(constructors, argumentsTypes, typeSolver, true) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration>, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 157) constructors.stream().filter((m) -> isApplicable(m, argumentsTypes, typeSolver, wildcardTolerance)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 157) constructors.stream().filter((m) -> isApplicable(m, argumentsTypes, typeSolver, wildcardTolerance)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 157) constructors.stream() ==> java.util.Collection.stream()
+  Line 157) isApplicable(m, argumentsTypes, typeSolver, wildcardTolerance) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.isApplicable(com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 157) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 158) applicableConstructors.isEmpty() ==> java.util.List.isEmpty()
+  Line 159) SymbolReference.unsolved(ConstructorDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 161) applicableConstructors.size() ==> java.util.List.size()
+  Line 162) SymbolReference.solved(applicableConstructors.get(0)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 162) applicableConstructors.get(0) ==> java.util.List.get(int)
+  Line 164) applicableConstructors.get(0) ==> java.util.List.get(int)
+  Line 167) applicableConstructors.size() ==> java.util.List.size()
+  Line 168) applicableConstructors.get(i) ==> java.util.List.get(int)
+  Line 169) isMoreSpecific(winningCandidate, other, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.isMoreSpecific(com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration, com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 171) isMoreSpecific(other, winningCandidate, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.ConstructorResolutionLogic.isMoreSpecific(com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration, com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 175) winningCandidate.declaringType().getQualifiedName().equals(other.declaringType().getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 175) winningCandidate.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 175) winningCandidate.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration.declaringType()
+  Line 176) other.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 176) other.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.ConstructorDeclaration.declaringType()
+  Line 185) MethodResolutionLogic.isExactMatch(winningCandidate, argumentsTypes) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isExactMatch(com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 186) MethodResolutionLogic.isExactMatch(other, argumentsTypes) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isExactMatch(com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 193) SymbolReference.solved(winningCandidate) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 200) constructorA.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 200) constructorB.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 203) constructorA.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 203) constructorB.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 206) constructorA.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 207) constructorA.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 207) constructorA.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 208) constructorB.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 208) constructorB.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 210) tdB.isAssignableBy(tdA) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 210) tdA.isAssignableBy(tdB) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 214) tdA.isAssignableBy(tdB) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 214) tdB.isAssignableBy(tdA) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 219) constructorA.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 219) tdA.arrayLevel() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.arrayLevel()
+  Line 219) tdB.arrayLevel() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.arrayLevel()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_MethodResolutionLogic.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_MethodResolutionLogic.txt
new file mode 100644
index 0000000..0c37bf7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_MethodResolutionLogic.txt
@@ -0,0 +1,416 @@
+  Line 45) argumentsTypes.subList(0, startVariadic) ==> java.util.List.subList(int, int)
+  Line 46) argumentsTypes.subList(startVariadic, argumentsTypes.size()) ==> java.util.List.subList(int, int)
+  Line 46) argumentsTypes.size() ==> java.util.List.size()
+  Line 47) variadicValues.isEmpty() ==> java.util.List.isEmpty()
+  Line 49) res.add(variadicType) ==> java.util.List.add(E)
+  Line 51) findCommonType(variadicValues) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findCommonType(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 52) res.add(new ArrayType(componentType)) ==> java.util.List.add(E)
+  Line 58) variadicValues.isEmpty() ==> java.util.List.isEmpty()
+  Line 62) variadicValues.get(0) ==> java.util.List.get(int)
+  Line 66) isApplicable(method, name, argumentsTypes, typeSolver, false) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isApplicable(com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 70) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 70) method.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 73) method.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 74) method.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 75) method.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 75) argumentsTypes.size() ==> java.util.List.size()
+  Line 77) method.getLastParam().getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 77) method.getLastParam() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getLastParam()
+  Line 78) argumentsTypes.get(pos) ==> java.util.List.get(int)
+  Line 79) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 80) method.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 81) replaceTypeParam(expectedType, tp, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.replaceTypeParam(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 83) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 84) actualType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 84) expectedType.isAssignableBy(actualType.asArrayType().getComponentType()) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 84) actualType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 84) actualType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 85) argumentsTypes.set(pos, actualType.asArrayType().getComponentType()) ==> java.util.List.set(int, E)
+  Line 85) actualType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 85) actualType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 87) groupVariadicParamValues(argumentsTypes, pos, method.getLastParam().getType()) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.groupVariadicParamValues(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 87) method.getLastParam().getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 87) method.getLastParam() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getLastParam()
+  Line 92) argumentsTypes.size() ==> java.util.List.size()
+  Line 95) groupVariadicParamValues(argumentsTypes, pos, method.getLastParam().getType()) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.groupVariadicParamValues(java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 95) method.getLastParam().getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 95) method.getLastParam() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getLastParam()
+  Line 99) method.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 99) argumentsTypes.size() ==> java.util.List.size()
+  Line 104) method.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 105) method.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 105) method.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 106) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 107) expectedType.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 107) expectedType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 107) expectedType.asTypeParameter().declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 107) expectedType.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 108) matchedParameters.put(expectedType.asTypeParameter().getName(), actualType) ==> java.util.Map.put(K, V)
+  Line 108) expectedType.asTypeParameter().getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 108) expectedType.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 111) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 112) method.getParam(i).isVariadic() ==> com.github.javaparser.symbolsolver.model.declarations.ParameterDeclaration.isVariadic()
+  Line 112) method.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 112) new ArrayType(expectedType).isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 113) expectedType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 113) actualType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 114) isAssignableMatchTypeParameters(expectedType.asReferenceType(), actualType.asReferenceType(), matchedParameters) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isAssignableMatchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.util.Map<java.lang.String, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 115) expectedType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 116) actualType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 120) method.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 121) typeParameters.addAll(method.declaringType().getTypeParameters()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 121) method.declaringType().getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 121) method.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 123) replaceTypeParam(expectedType, tp, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.replaceTypeParam(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 126) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 127) actualType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 127) expectedType.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 131) method.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 131) method.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 132) new ArrayType(expectedType).isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 145) expected.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 145) actual.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 146) isAssignableMatchTypeParameters(expected.asReferenceType(), actual.asReferenceType(), matchedParameters) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isAssignableMatchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.util.Map<java.lang.String, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 146) expected.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 146) actual.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 147) expected.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 148) matchedParameters.put(expected.asTypeParameter().getName(), actual) ==> java.util.Map.put(K, V)
+  Line 148) expected.asTypeParameter().getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 148) expected.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 151) expected.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 151) expected.getClass() ==> java.lang.Object.getClass()
+  Line 151) actual.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 151) actual.getClass() ==> java.lang.Object.getClass()
+  Line 157) actual.getQualifiedName().equals(expected.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 157) actual.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 157) expected.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 158) isAssignableMatchTypeParametersMatchingQName(expected, actual, matchedParameters) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isAssignableMatchTypeParametersMatchingQName(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.util.Map<java.lang.String, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 160) actual.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 162) isAssignableMatchTypeParametersMatchingQName(expected, ancestor, matchedParameters) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isAssignableMatchTypeParametersMatchingQName(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.util.Map<java.lang.String, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 173) expected.getQualifiedName().equals(actual.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 173) expected.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 173) actual.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 176) expected.typeParametersValues().size() ==> java.util.List.size()
+  Line 176) expected.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 176) actual.typeParametersValues().size() ==> java.util.List.size()
+  Line 176) actual.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 180) expected.typeParametersValues().size() ==> java.util.List.size()
+  Line 180) expected.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 181) expected.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 181) expected.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 182) actual.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 182) actual.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 186) expectedParam.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 186) actualParam.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 187) expectedParam.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 188) actualParam.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 190) isAssignableMatchTypeParametersMatchingQName(r1, r2, matchedParameters) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isAssignableMatchTypeParametersMatchingQName(com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, com.github.javaparser.symbolsolver.model.typesystem.ReferenceType, java.util.Map<java.lang.String, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 193) expectedParam.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 194) expectedParam.asTypeParameter().getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 194) expectedParam.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 195) actualParam.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 195) actualParam.asTypeParameter().getName().equals(expectedParamName) ==> java.lang.String.equals(java.lang.Object)
+  Line 195) actualParam.asTypeParameter().getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 195) actualParam.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 196) matchedParameters.containsKey(expectedParamName) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 197) matchedParameters.get(expectedParamName) ==> java.util.Map.get(java.lang.Object)
+  Line 198) matchedParameter.isAssignableBy(actualParam) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 200) actualParam.isAssignableBy(matchedParameter) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 201) matchedParameters.put(expectedParamName, actualParam) ==> java.util.Map.put(K, V)
+  Line 206) matchedParameters.put(expectedParamName, actualParam) ==> java.util.Map.put(K, V)
+  Line 209) expectedParam.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 210) expectedParam.equals(actualParam) ==> java.lang.Object.equals(java.lang.Object)
+  Line 213) expectedParam.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 214) expectedParam.asWildcard().isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 214) expectedParam.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 215) isAssignableMatchTypeParameters(expectedParam.asWildcard().getBoundedType(), actual, matchedParameters) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isAssignableMatchTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<java.lang.String, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 215) expectedParam.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 215) expectedParam.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 220) expectedParam.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 227) type.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 228) type.describe().equals(tp.getName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 228) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 228) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 229) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 230) bounds.size() ==> java.util.List.size()
+  Line 232) bounds.size() ==> java.util.List.size()
+  Line 233) bounds.get(0).getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 233) bounds.get(0) ==> java.util.List.get(int)
+  Line 235) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 235) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 239) type.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 241) type.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 242) replaceTypeParam(type.asArrayType().getComponentType(), tp, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.replaceTypeParam(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 242) type.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 242) type.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 243) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 244) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 245) result.transformTypeParameters(typeParam -> replaceTypeParam(typeParam, tp, typeSolver)).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 245) result.transformTypeParameters(typeParam -> replaceTypeParam(typeParam, tp, typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.transformTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer)
+  Line 245) replaceTypeParam(typeParam, tp, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.replaceTypeParam(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 247) type.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 248) type.describe().equals(tp.getName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 248) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 248) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 249) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 250) bounds.size() ==> java.util.List.size()
+  Line 252) bounds.size() ==> java.util.List.size()
+  Line 253) bounds.get(0).getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 253) bounds.get(0) ==> java.util.List.get(int)
+  Line 255) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 255) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 260) type.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 260) type.getClass() ==> java.lang.Object.getClass()
+  Line 265) method.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 265) method.getName() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getName()
+  Line 269) method.getNoParams() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getNoParams()
+  Line 269) argumentsTypes.size() ==> java.util.List.size()
+  Line 272) method.getNoParams() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getNoParams()
+  Line 273) method.getParamType(i) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 275) method.getParamType(i) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 276) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 278) method.getDeclaration().getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 278) method.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 279) typeParameters.addAll(method.declaringType().getTypeParameters()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 279) method.declaringType().getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 279) method.declaringType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.declaringType()
+  Line 281) expectedType.describe().equals(actualType.describe()) ==> java.lang.String.equals(java.lang.Object)
+  Line 281) expectedType.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 281) actualType.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 286) method.getParamTypes().size() ==> java.util.List.size()
+  Line 286) method.getParamTypes() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamTypes()
+  Line 287) method.getDeclaration().getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 287) method.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 288) parameter.getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 289) parameter.isVariadic() ==> com.github.javaparser.symbolsolver.model.declarations.ParameterDeclaration.isVariadic()
+  Line 290) parameterType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 290) parameterType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 292) inferTypes(argumentsTypes.get(j), parameterType, derivedValues) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 292) argumentsTypes.get(j) ==> java.util.List.get(int)
+  Line 295) derivedValues.entrySet() ==> java.util.Map.entrySet()
+  Line 296) entry.getKey() ==> java.util.Map.Entry.getKey()
+  Line 297) expectedTypeWithInference.replaceTypeVariables(tp, entry.getValue()) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 297) entry.getValue() ==> java.util.Map.Entry.getValue()
+  Line 301) tp.getBounds(typeSolver).isEmpty() ==> java.util.List.isEmpty()
+  Line 301) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 303) expectedType.replaceTypeVariables(tp, Wildcard.extendsBound(new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver))) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 303) Wildcard.extendsBound(new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 303) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 303) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 304) tp.getBounds(typeSolver).size() ==> java.util.List.size()
+  Line 304) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 305) tp.getBounds(typeSolver).get(0) ==> java.util.List.get(int)
+  Line 305) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 306) bound.isExtends() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.isExtends()
+  Line 308) expectedType.replaceTypeVariables(tp, Wildcard.extendsBound(bound.getType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 308) Wildcard.extendsBound(bound.getType()) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 308) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 311) expectedType.replaceTypeVariables(tp, Wildcard.superBound(bound.getType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 311) Wildcard.superBound(bound.getType()) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 311) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 319) tp.getBounds(typeSolver).isEmpty() ==> java.util.List.isEmpty()
+  Line 319) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 320) expectedType2.replaceTypeVariables(tp, new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 320) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 320) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 321) tp.getBounds(typeSolver).size() ==> java.util.List.size()
+  Line 321) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 322) tp.getBounds(typeSolver).get(0) ==> java.util.List.get(int)
+  Line 322) tp.getBounds(typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 323) bound.isExtends() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.isExtends()
+  Line 324) expectedType2.replaceTypeVariables(tp, bound.getType()) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 324) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 326) expectedType2.replaceTypeVariables(tp, new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver)) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 326) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 326) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 332) expectedType.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 333) expectedType2.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 334) expectedTypeWithInference.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 335) expectedTypeWithoutSubstitutions.isAssignableBy(actualType) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 347) ((JavaParserMethodDeclaration) m1).getWrappedNode().equals(((JavaParserMethodDeclaration) m2).getWrappedNode()) ==> com.github.javaparser.ast.Node.equals(java.lang.Object)
+  Line 347) ((JavaParserMethodDeclaration) m1).getWrappedNode() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration.getWrappedNode()
+  Line 347) ((JavaParserMethodDeclaration) m2).getWrappedNode() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration.getWrappedNode()
+  Line 353) s.addAll(methods) ==> java.util.Set.addAll(java.util.Collection<? extends E>)
+  Line 357) md.getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 358) usedSignatures.contains(signature) ==> java.util.Set.contains(java.lang.Object)
+  Line 359) usedSignatures.add(signature) ==> java.util.Set.add(E)
+  Line 360) res.add(md) ==> java.util.List.add(E)
+  Line 374) findMostApplicable(methods, name, argumentsTypes, typeSolver, false) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 375) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 378) findMostApplicable(methods, name, argumentsTypes, typeSolver, true) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.findMostApplicable(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 382) getMethodsWithoutDuplicates(methods).stream().filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver, wildcardTolerance)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 382) getMethodsWithoutDuplicates(methods).stream().filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver, wildcardTolerance)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 382) getMethodsWithoutDuplicates(methods).stream() ==> java.util.Collection.stream()
+  Line 382) getMethodsWithoutDuplicates(methods) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.getMethodsWithoutDuplicates(java.util.List<com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration>)
+  Line 382) isApplicable(m, name, argumentsTypes, typeSolver, wildcardTolerance) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isApplicable(com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver, boolean)
+  Line 382) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 383) applicableMethods.isEmpty() ==> java.util.List.isEmpty()
+  Line 384) SymbolReference.unsolved(MethodDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 387) applicableMethods.size() ==> java.util.List.size()
+  Line 389) argumentsTypes.size() ==> java.util.List.size()
+  Line 390) argumentsTypes.get(i).isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 390) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 391) nullParamIndexes.add(i) ==> java.util.List.add(E)
+  Line 394) nullParamIndexes.isEmpty() ==> java.util.List.isEmpty()
+  Line 399) methDecl.getParam(nullParamIndex.intValue()).getType().isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 399) methDecl.getParam(nullParamIndex.intValue()).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 399) methDecl.getParam(nullParamIndex.intValue()) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 399) nullParamIndex.intValue() ==> java.lang.Integer.intValue()
+  Line 400) removeCandidates.add(methDecl) ==> java.util.Set.add(E)
+  Line 404) removeCandidates.isEmpty() ==> java.util.Set.isEmpty()
+  Line 404) removeCandidates.size() ==> java.util.Set.size()
+  Line 404) applicableMethods.size() ==> java.util.List.size()
+  Line 405) applicableMethods.removeAll(removeCandidates) ==> java.util.List.removeAll(java.util.Collection<? extends java.lang.Object>)
+  Line 409) applicableMethods.size() ==> java.util.List.size()
+  Line 410) SymbolReference.solved(applicableMethods.get(0)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 410) applicableMethods.get(0) ==> java.util.List.get(int)
+  Line 412) applicableMethods.get(0) ==> java.util.List.get(int)
+  Line 415) applicableMethods.size() ==> java.util.List.size()
+  Line 416) applicableMethods.get(i) ==> java.util.List.get(int)
+  Line 417) isMoreSpecific(winningCandidate, other, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isMoreSpecific(com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration, com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 419) isMoreSpecific(other, winningCandidate, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isMoreSpecific(com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration, com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 423) winningCandidate.declaringType().getQualifiedName().equals(other.declaringType().getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 423) winningCandidate.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 423) winningCandidate.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 423) other.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 423) other.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 432) isExactMatch(winningCandidate, argumentsTypes) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isExactMatch(com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 433) isExactMatch(other, argumentsTypes) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isExactMatch(com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 440) SymbolReference.solved(winningCandidate) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 445) method.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 446) method.getParam(i).getType().equals(argumentsTypes.get(i)) ==> java.lang.Object.equals(java.lang.Object)
+  Line 446) method.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 446) method.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 446) argumentsTypes.get(i) ==> java.util.List.get(int)
+  Line 455) methodA.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 455) methodB.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 458) methodA.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 458) methodB.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 461) methodA.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 462) methodA.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 462) methodA.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 463) methodB.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 463) methodB.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 465) tdB.isAssignableBy(tdA) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 465) tdA.isAssignableBy(tdB) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 469) tdA.isAssignableBy(tdB) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 469) tdB.isAssignableBy(tdA) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 475) argumentTypes.size() ==> java.util.List.size()
+  Line 477) methodA.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 477) methodB.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 479) argumentTypes.get(lastIndex).isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 479) argumentTypes.get(lastIndex) ==> java.util.List.get(int)
+  Line 483) argumentTypes.get(lastIndex).isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 483) argumentTypes.get(lastIndex) ==> java.util.List.get(int)
+  Line 487) methodA.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 487) methodB.hasVariadicParameter() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.hasVariadicParameter()
+  Line 490) argumentTypes.get(lastIndex).isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 490) argumentTypes.get(lastIndex) ==> java.util.List.get(int)
+  Line 494) argumentTypes.get(lastIndex).isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 494) argumentTypes.get(lastIndex) ==> java.util.List.get(int)
+  Line 505) methodA.getNoParams() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getNoParams()
+  Line 506) methodA.getParamType(i) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 507) methodB.getParamType(i) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamType(int)
+  Line 509) tdA.isAssignableBy(tdB) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 510) tdB.isAssignableBy(tdA) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 525) methods.stream().filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 525) methods.stream().filter((m) -> isApplicable(m, name, argumentsTypes, typeSolver)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 525) methods.stream() ==> java.util.Collection.stream()
+  Line 525) isApplicable(m, name, argumentsTypes, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isApplicable(com.github.javaparser.symbolsolver.model.methods.MethodUsage, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 525) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 527) applicableMethods.isEmpty() ==> java.util.List.isEmpty()
+  Line 528) Optional.empty() ==> java.util.Optional.empty()
+  Line 530) applicableMethods.size() ==> java.util.List.size()
+  Line 531) Optional.of(applicableMethods.get(0)) ==> java.util.Optional.of(T)
+  Line 531) applicableMethods.get(0) ==> java.util.List.get(int)
+  Line 533) applicableMethods.get(0) ==> java.util.List.get(int)
+  Line 534) applicableMethods.size() ==> java.util.List.size()
+  Line 535) applicableMethods.get(i) ==> java.util.List.get(int)
+  Line 536) isMoreSpecific(winningCandidate, other, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isMoreSpecific(com.github.javaparser.symbolsolver.model.methods.MethodUsage, com.github.javaparser.symbolsolver.model.methods.MethodUsage, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 538) isMoreSpecific(other, winningCandidate, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.isMoreSpecific(com.github.javaparser.symbolsolver.model.methods.MethodUsage, com.github.javaparser.symbolsolver.model.methods.MethodUsage, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 541) winningCandidate.declaringType().getQualifiedName().equals(other.declaringType().getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 541) winningCandidate.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 541) winningCandidate.declaringType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.declaringType()
+  Line 541) other.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 541) other.declaringType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.declaringType()
+  Line 542) areOverride(winningCandidate, other) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.areOverride(com.github.javaparser.symbolsolver.model.methods.MethodUsage, com.github.javaparser.symbolsolver.model.methods.MethodUsage)
+  Line 543) winningCandidate.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 543) winningCandidate.declaringType() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.declaringType()
+  Line 551) Optional.of(winningCandidate) ==> java.util.Optional.of(T)
+  Line 556) winningCandidate.getName().equals(other.getName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 556) winningCandidate.getName() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getName()
+  Line 556) other.getName() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getName()
+  Line 559) winningCandidate.getNoParams() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getNoParams()
+  Line 559) other.getNoParams() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getNoParams()
+  Line 562) winningCandidate.getNoParams() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getNoParams()
+  Line 563) winningCandidate.getParamTypes().get(i).equals(other.getParamTypes().get(i)) ==> java.lang.Object.equals(java.lang.Object)
+  Line 563) winningCandidate.getParamTypes().get(i) ==> java.util.List.get(int)
+  Line 563) winningCandidate.getParamTypes() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamTypes()
+  Line 563) other.getParamTypes().get(i) ==> java.util.List.get(int)
+  Line 563) other.getParamTypes() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getParamTypes()
+  Line 571) solveMethodInType(typeDeclaration, name, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.solveMethodInType(com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration, java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 587) ((JavaParserClassDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getContext()
+  Line 588) ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 591) ((JavaParserInterfaceDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.getContext()
+  Line 592) ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 595) name.equals("values") ==> java.lang.String.equals(java.lang.Object)
+  Line 595) argumentsTypes.isEmpty() ==> java.util.List.isEmpty()
+  Line 596) SymbolReference.solved(new JavaParserEnumDeclaration.ValuesMethod((JavaParserEnumDeclaration) typeDeclaration, typeSolver)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 598) ((JavaParserEnumDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.getContext()
+  Line 599) ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 602) ((ReflectionClassDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 605) ((ReflectionInterfaceDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 608) ((ReflectionEnumDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionEnumDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 611) ((JavassistInterfaceDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistInterfaceDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 614) ((JavassistClassDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 617) ((JavassistEnumDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean)
+  Line 619) typeDeclaration.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 619) typeDeclaration.getClass() ==> java.lang.Object.getClass()
+  Line 625) source.equals(target) ==> java.lang.Object.equals(java.lang.Object)
+  Line 628) source.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 628) target.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 629) source.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 630) target.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 631) sourceRefType.getQualifiedName().equals(targetRefType.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 631) sourceRefType.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 631) targetRefType.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 632) sourceRefType.isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 632) targetRefType.isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 633) sourceRefType.typeParametersValues().size() ==> java.util.List.size()
+  Line 633) sourceRefType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 634) inferTypes(sourceRefType.typeParametersValues().get(i), targetRefType.typeParametersValues().get(i), mappings) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 634) sourceRefType.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 634) sourceRefType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 634) targetRefType.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 634) targetRefType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 640) source.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 640) target.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 641) target.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 641) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 642) inferTypes(source, target.asWildcard().getBoundedType(), mappings) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 642) target.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 642) target.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 647) source.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 647) target.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 650) source.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 650) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 651) mappings.put(target.asTypeParameter(), source) ==> java.util.Map.put(K, V)
+  Line 651) target.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 655) source.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 655) target.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 656) source.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 656) source.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 657) inferTypes(source.asWildcard().getBoundedType(), target, mappings) ==> com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic.inferTypes(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 657) source.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 657) source.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 662) source.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 662) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 663) mappings.put(target.asTypeParameter(), source) ==> java.util.Map.put(K, V)
+  Line 663) target.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 666) source.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 666) target.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 667) mappings.put(target.asTypeParameter(), source) ==> java.util.Map.put(K, V)
+  Line 667) target.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 670) source.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 670) target.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 673) source.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_SymbolDeclarator.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_SymbolDeclarator.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_SymbolDeclarator.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_SymbolSolver.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_SymbolSolver.txt
new file mode 100644
index 0000000..abdaa0b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_SymbolSolver.txt
@@ -0,0 +1,40 @@
+  Line 58) context.solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 62) solveSymbol(name, JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 62) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 66) context.solveSymbolAsValue(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 70) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 71) solveSymbolAsValue(name, context) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolAsValue(java.lang.String, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 75) context.solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 79) solveType(name, JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveType(java.lang.String, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 79) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 83) context.solveMethod(methodName, argumentsTypes, false, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, boolean, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 84) decl.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 87) decl.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 91) solveMethod(methodName, argumentsTypes, JavaParserFactory.getContext(node, typeSolver)) ==> com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveMethod(java.lang.String, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.core.resolution.Context)
+  Line 91) JavaParserFactory.getContext(node, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 99) ((ClassOrInterfaceType) type).getName().getId() ==> com.github.javaparser.ast.nodeTypes.NodeWithIdentifier.getId()
+  Line 99) ((ClassOrInterfaceType) type).getName() ==> com.github.javaparser.ast.type.ClassOrInterfaceType.getName()
+  Line 100) JavaParserFactory.getContext(type, typeSolver).solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 100) JavaParserFactory.getContext(type, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 101) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 102) JavaParserFactory.getContext(type, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory.getContext(com.github.javaparser.ast.Node, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 104) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 106) type.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 106) type.getClass() ==> java.lang.Object.getClass()
+  Line 111) context.solveGenericType(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveGenericType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 112) genericType.isPresent() ==> java.util.Optional.isPresent()
+  Line 113) genericType.get() ==> java.util.Optional.get()
+  Line 115) typeSolver.solveType(name) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 128) ((JavaParserClassDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.getContext()
+  Line 129) ctx.solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 132) ((JavaParserInterfaceDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.getContext()
+  Line 133) ctx.solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 136) ((JavaParserEnumDeclaration) typeDeclaration).getContext() ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration.getContext()
+  Line 137) ctx.solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.core.resolution.Context.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 140) ((ReflectionClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionClassDeclaration.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 143) ((ReflectionInterfaceDeclaration) typeDeclaration).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 146) ((JavassistClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration.solveSymbol(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 148) SymbolReference.unsolved(ValueDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 157) ((JavaParserClassDeclaration) typeDeclaration).solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 160) ((JavaParserInterfaceDeclaration) typeDeclaration).solveType(name, typeSolver) ==> com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration.solveType(java.lang.String, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 162) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_CombinedTypeSolver.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_CombinedTypeSolver.txt
new file mode 100644
index 0000000..dc25ad4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_CombinedTypeSolver.txt
@@ -0,0 +1,9 @@
+  Line 37) add(el) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver.add(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 52) this.elements.add(typeSolver) ==> java.util.List.add(E)
+  Line 53) typeSolver.setParent(this) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.setParent(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 59) ts.tryToSolveType(name) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 60) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 64) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 69) tryToSolveType(name) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver.tryToSolveType(java.lang.String)
+  Line 70) res.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 71) res.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_JarTypeSolver.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_JarTypeSolver.txt
new file mode 100644
index 0000000..ddbe4d9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_JarTypeSolver.txt
@@ -0,0 +1,31 @@
+  Line 46) addPathToJar(pathToJar) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver.addPathToJar(java.lang.String)
+  Line 53) instance.addPathToJar(pathToJar) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver.addPathToJar(java.lang.String)
+  Line 60) classPool.appendClassPath(pathToJar) ==> javassist.ClassPool.appendClassPath(java.lang.String)
+  Line 61) classPool.appendSystemPath() ==> javassist.ClassPool.appendSystemPath()
+  Line 67) jarFile.entries() ==> java.util.jar.JarFile.entries()
+  Line 68) e.hasMoreElements() ==> java.util.Enumeration.hasMoreElements()
+  Line 69) e.nextElement() ==> java.util.Enumeration.nextElement()
+  Line 70) entry.isDirectory() ==> java.util.zip.ZipEntry.isDirectory()
+  Line 70) entry.getName().endsWith(".class") ==> java.lang.String.endsWith(java.lang.String)
+  Line 70) entry.getName() ==> java.util.zip.ZipEntry.getName()
+  Line 71) entryPathToClassName(entry.getName()) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver.entryPathToClassName(java.lang.String)
+  Line 71) entry.getName() ==> java.util.zip.ZipEntry.getName()
+  Line 72) classpathElements.put(name, new ClasspathElement(jarFile, entry, name)) ==> java.util.Map.put(K, V)
+  Line 88) entryPath.endsWith(".class") ==> java.lang.String.endsWith(java.lang.String)
+  Line 91) entryPath.substring(0, entryPath.length() - ".class".length()) ==> java.lang.String.substring(int, int)
+  Line 91) entryPath.length() ==> java.lang.String.length()
+  Line 91) ".class".length() ==> java.lang.String.length()
+  Line 92) className.replace('/', '.') ==> java.lang.String.replace(char, char)
+  Line 93) className.replace('$', '.') ==> java.lang.String.replace(char, char)
+  Line 100) classpathElements.containsKey(name) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 101) SymbolReference.solved(JavassistFactory.toTypeDeclaration(classpathElements.get(name).toCtClass(), getRoot())) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 102) JavassistFactory.toTypeDeclaration(classpathElements.get(name).toCtClass(), getRoot()) ==> com.github.javaparser.symbolsolver.javassistmodel.JavassistFactory.toTypeDeclaration(javassist.CtClass, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 102) classpathElements.get(name).toCtClass() ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver.ClasspathElement.toCtClass()
+  Line 102) classpathElements.get(name) ==> java.util.Map.get(java.lang.Object)
+  Line 102) getRoot() ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.getRoot()
+  Line 104) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 113) tryToSolveType(name) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver.tryToSolveType(java.lang.String)
+  Line 114) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 115) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 133) jarFile.getInputStream(entry) ==> java.util.jar.JarFile.getInputStream(java.util.zip.ZipEntry)
+  Line 134) classPool.makeClass(is) ==> javassist.ClassPool.makeClass(java.io.InputStream)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_JavaParserTypeSolver.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_JavaParserTypeSolver.txt
new file mode 100644
index 0000000..5ffaa4d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_JavaParserTypeSolver.txt
@@ -0,0 +1,48 @@
+  Line 72) parsedFiles.containsKey(srcFile.getAbsolutePath()) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 72) srcFile.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 73) parsedFiles.put(srcFile.getAbsolutePath(), JavaParser.parse(srcFile)) ==> java.util.Map.put(K, V)
+  Line 73) srcFile.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 73) JavaParser.parse(srcFile) ==> com.github.javaparser.JavaParser.parse(java.io.File)
+  Line 75) parsedFiles.get(srcFile.getAbsolutePath()) ==> java.util.Map.get(java.lang.Object)
+  Line 75) srcFile.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 79) parsedDirectories.containsKey(srcDirectory.getAbsolutePath()) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 79) srcDirectory.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 81) srcDirectory.listFiles() ==> java.io.File.listFiles()
+  Line 82) srcDirectory.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 84) file.getName().toLowerCase().endsWith(".java") ==> java.lang.String.endsWith(java.lang.String)
+  Line 84) file.getName().toLowerCase() ==> java.lang.String.toLowerCase()
+  Line 84) file.getName() ==> java.io.File.getName()
+  Line 85) units.add(parse(file)) ==> java.util.List.add(E)
+  Line 85) parse(file) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver.parse(java.io.File)
+  Line 88) parsedDirectories.put(srcDirectory.getAbsolutePath(), units) ==> java.util.Map.put(K, V)
+  Line 88) srcDirectory.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 91) parsedDirectories.get(srcDirectory.getAbsolutePath()) ==> java.util.Map.get(java.lang.Object)
+  Line 91) srcDirectory.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 96) srcDir.exists() ==> java.io.File.exists()
+  Line 96) srcDir.isDirectory() ==> java.io.File.isDirectory()
+  Line 97) srcDir.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 102) foundTypes.containsKey(name) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 103) SymbolReference.solved(foundTypes.get(name)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 103) foundTypes.get(name) ==> java.util.Map.get(java.lang.Object)
+  Line 105) tryToSolveTypeUncached(name) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver.tryToSolveTypeUncached(java.lang.String)
+  Line 106) result.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 107) foundTypes.put(name, result.getCorrespondingDeclaration()) ==> java.util.Map.put(K, V)
+  Line 107) result.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 114) name.split("\\.") ==> java.lang.String.split(java.lang.String)
+  Line 117) srcDir.getAbsolutePath() ==> java.io.File.getAbsolutePath()
+  Line 133) parse(srcFile) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver.parse(java.io.File)
+  Line 134) Navigator.findType(compilationUnit, typeName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findType(com.github.javaparser.ast.CompilationUnit, java.lang.String)
+  Line 135) astTypeDeclaration.isPresent() ==> java.util.Optional.isPresent()
+  Line 136) SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get())) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 136) JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 136) JavaParserFacade.get(this) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 136) astTypeDeclaration.get() ==> java.util.Optional.get()
+  Line 143) parseDirectory(srcFile.getParentFile()) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver.parseDirectory(java.io.File)
+  Line 143) srcFile.getParentFile() ==> java.io.File.getParentFile()
+  Line 145) Navigator.findType(compilationUnit, typeName) ==> com.github.javaparser.symbolsolver.javaparser.Navigator.findType(com.github.javaparser.ast.CompilationUnit, java.lang.String)
+  Line 146) astTypeDeclaration.isPresent() ==> java.util.Optional.isPresent()
+  Line 147) SymbolReference.solved(JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get())) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 147) JavaParserFacade.get(this).getTypeDeclaration(astTypeDeclaration.get()) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration<?>)
+  Line 147) JavaParserFacade.get(this) ==> com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.get(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 147) astTypeDeclaration.get() ==> java.util.Optional.get()
+  Line 155) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_MemoryTypeSolver.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_MemoryTypeSolver.txt
new file mode 100644
index 0000000..27733db
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_MemoryTypeSolver.txt
@@ -0,0 +1,9 @@
+  Line 51) parent.equals(that.parent) ==> java.lang.Object.equals(java.lang.Object)
+  Line 52) declarationMap.equals(that.declarationMap) ==> java.util.Map.equals(java.lang.Object)
+  Line 58) parent.hashCode() ==> java.lang.Object.hashCode()
+  Line 59) declarationMap.hashCode() ==> java.util.Map.hashCode()
+  Line 74) this.declarationMap.put(name, typeDeclaration) ==> java.util.Map.put(K, V)
+  Line 79) declarationMap.containsKey(name) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 80) SymbolReference.solved(declarationMap.get(name)) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 80) declarationMap.get(name) ==> java.util.Map.get(java.lang.Object)
+  Line 82) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_ReflectionTypeSolver.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_ReflectionTypeSolver.txt
new file mode 100644
index 0000000..5a27ad5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-core/com_github_javaparser_symbolsolver_resolution_typesolvers_ReflectionTypeSolver.txt
@@ -0,0 +1,26 @@
+  Line 55) name.startsWith("java.") ==> java.lang.String.startsWith(java.lang.String)
+  Line 55) name.startsWith("javax.") ==> java.lang.String.startsWith(java.lang.String)
+  Line 57) ReflectionTypeSolver.class.getClassLoader() ==> java.lang.Class.getClassLoader()
+  Line 65) classLoader.loadClass(name) ==> java.lang.ClassLoader.loadClass(java.lang.String)
+  Line 66) SymbolReference.solved(ReflectionFactory.typeDeclarationFor(clazz, getRoot())) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 66) ReflectionFactory.typeDeclarationFor(clazz, getRoot()) ==> com.github.javaparser.symbolsolver.reflectionmodel.ReflectionFactory.typeDeclarationFor(java.lang.Class<?>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 66) getRoot() ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.getRoot()
+  Line 69) name.lastIndexOf('.') ==> java.lang.String.lastIndexOf(int)
+  Line 71) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 73) name.substring(0, lastDot) ==> java.lang.String.substring(int, int)
+  Line 74) name.substring(lastDot + 1) ==> java.lang.String.substring(int)
+  Line 75) tryToSolveType(parentName) ==> com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver.tryToSolveType(java.lang.String)
+  Line 76) parent.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 77) parent.getCorrespondingDeclaration().internalTypes().stream().filter(it -> it.getName().equals(childName)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 77) parent.getCorrespondingDeclaration().internalTypes().stream().filter(it -> it.getName().equals(childName)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 77) parent.getCorrespondingDeclaration().internalTypes().stream() ==> java.util.Collection.stream()
+  Line 77) parent.getCorrespondingDeclaration().internalTypes() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.internalTypes()
+  Line 77) parent.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 78) it.getName().equals(childName) ==> java.lang.String.equals(java.lang.Object)
+  Line 78) it.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 79) innerClass.isPresent() ==> java.util.Optional.isPresent()
+  Line 80) SymbolReference.solved(innerClass.get()) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 80) innerClass.get() ==> java.util.Optional.get()
+  Line 82) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 85) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
+  Line 90) SymbolReference.unsolved(ReferenceTypeDeclaration.class) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_AbstractClassDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_AbstractClassDeclaration.txt
new file mode 100644
index 0000000..9da1ae7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_AbstractClassDeclaration.txt
@@ -0,0 +1,18 @@
+  Line 39) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 45) getSuperClass() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getSuperClass()
+  Line 47) superclasses.add(superClass) ==> java.util.List.add(E)
+  Line 48) superclasses.addAll(superClass.getAllClassesAncestors()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 48) superClass.getAllClassesAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllClassesAncestors()
+  Line 51) superclasses.removeIf(s -> s.getQualifiedName().equals(Object.class.getCanonicalName())) ==> java.util.Collection.removeIf(java.util.function.Predicate<? super E>)
+  Line 51) s.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 51) s.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 51) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 52) superclasses.add(object()) ==> java.util.List.add(E)
+  Line 52) object() ==> com.github.javaparser.symbolsolver.logic.AbstractClassDeclaration.object()
+  Line 60) getInterfaces() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getInterfaces()
+  Line 61) interfaces.add(interfaceDeclaration) ==> java.util.List.add(E)
+  Line 62) interfaces.addAll(interfaceDeclaration.getAllInterfacesAncestors()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 62) interfaceDeclaration.getAllInterfacesAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllInterfacesAncestors()
+  Line 64) this.getSuperClass() ==> com.github.javaparser.symbolsolver.model.declarations.ClassDeclaration.getSuperClass()
+  Line 66) interfaces.addAll(superClass.getAllInterfacesAncestors()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 66) superClass.getAllInterfacesAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllInterfacesAncestors()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_AbstractTypeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_AbstractTypeDeclaration.txt
new file mode 100644
index 0000000..da18ef9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_AbstractTypeDeclaration.txt
@@ -0,0 +1,13 @@
+  Line 42) getDeclaredMethods() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getDeclaredMethods()
+  Line 43) methods.add(new MethodUsage(methodDeclaration)) ==> java.util.Set.add(E)
+  Line 44) methodsSignatures.add(methodDeclaration.getSignature()) ==> java.util.Set.add(E)
+  Line 44) methodDeclaration.getSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getSignature()
+  Line 47) getAllAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllAncestors()
+  Line 48) ancestor.getDeclaredMethods() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getDeclaredMethods()
+  Line 49) mu.getDeclaration().getSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getSignature()
+  Line 49) mu.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 50) methodsSignatures.contains(signature) ==> java.util.Set.contains(java.lang.Object)
+  Line 51) methodsSignatures.add(signature) ==> java.util.Set.add(E)
+  Line 52) methods.add(mu) ==> java.util.Set.add(E)
+  Line 62) FunctionalInterfaceLogic.getFunctionalMethod(this).isPresent() ==> java.util.Optional.isPresent()
+  Line 62) FunctionalInterfaceLogic.getFunctionalMethod(this) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_ConfilictingGenericTypesException.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_ConfilictingGenericTypesException.txt
new file mode 100644
index 0000000..a8f5cff
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_ConfilictingGenericTypesException.txt
@@ -0,0 +1 @@
+  Line 11) String.format("No matching between %s (formal) and %s (actual)", formalType, actualType) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_FunctionalInterfaceLogic.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_FunctionalInterfaceLogic.txt
new file mode 100644
index 0000000..c135988
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_FunctionalInterfaceLogic.txt
@@ -0,0 +1,42 @@
+  Line 44) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 44) type.asReferenceType().getTypeDeclaration().isInterface() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isInterface()
+  Line 44) type.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 44) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 45) getFunctionalMethod(type.asReferenceType().getTypeDeclaration()) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getFunctionalMethod(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 45) type.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 45) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 47) Optional.empty() ==> java.util.Optional.empty()
+  Line 56) typeDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().isAbstract()).filter(m -> !declaredOnObject(m)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 56) typeDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().isAbstract()).filter(m -> !declaredOnObject(m)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 56) typeDeclaration.getAllMethods().stream().filter(m -> m.getDeclaration().isAbstract()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 56) typeDeclaration.getAllMethods().stream() ==> java.util.Collection.stream()
+  Line 56) typeDeclaration.getAllMethods() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllMethods()
+  Line 57) m.getDeclaration().isAbstract() ==> com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration.isAbstract()
+  Line 57) m.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
+  Line 60) declaredOnObject(m) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.declaredOnObject(com.github.javaparser.symbolsolver.model.methods.MethodUsage)
+  Line 61) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 63) methods.size() ==> java.util.Set.size()
+  Line 64) Optional.of(methods.iterator().next()) ==> java.util.Optional.of(T)
+  Line 64) methods.iterator().next() ==> java.util.Iterator.next()
+  Line 64) methods.iterator() ==> java.util.Set.iterator()
+  Line 66) Optional.empty() ==> java.util.Optional.empty()
+  Line 71) String.format("%s(%s)", m.getName(), String.join(", ", Arrays.stream(m.getParameters()).map(p -> toSignature(p)).collect(Collectors.toList()))) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 71) m.getName() ==> java.lang.reflect.Method.getName()
+  Line 71) String.join(", ", Arrays.stream(m.getParameters()).map(p -> toSignature(p)).collect(Collectors.toList())) ==> java.lang.String.join(java.lang.CharSequence, java.lang.Iterable<? extends java.lang.CharSequence>)
+  Line 71) Arrays.stream(m.getParameters()).map(p -> toSignature(p)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 71) Arrays.stream(m.getParameters()).map(p -> toSignature(p)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 71) Arrays.stream(m.getParameters()) ==> java.util.Arrays.stream(T[])
+  Line 71) m.getParameters() ==> java.lang.reflect.Executable.getParameters()
+  Line 71) toSignature(p) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.toSignature(java.lang.reflect.Parameter)
+  Line 71) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 75) p.getType().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 75) p.getType() ==> java.lang.reflect.Parameter.getType()
+  Line 78) Arrays.stream(Object.class.getDeclaredMethods()).map(method -> getSignature(method)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 78) Arrays.stream(Object.class.getDeclaredMethods()).map(method -> getSignature(method)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 78) Arrays.stream(Object.class.getDeclaredMethods()) ==> java.util.Arrays.stream(T[])
+  Line 78) Object.class.getDeclaredMethods() ==> java.lang.Class.getDeclaredMethods()
+  Line 79) getSignature(method) ==> com.github.javaparser.symbolsolver.logic.FunctionalInterfaceLogic.getSignature(java.lang.reflect.Method)
+  Line 80) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 83) OBJECT_METHODS_SIGNATURES.contains(m.getDeclaration().getSignature()) ==> java.util.List.contains(java.lang.Object)
+  Line 83) m.getDeclaration().getSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getSignature()
+  Line 83) m.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_InferenceContext.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_InferenceContext.txt
new file mode 100644
index 0000000..bf51ade
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_InferenceContext.txt
@@ -0,0 +1,169 @@
+  Line 44) inferenceVariableTypeMap.containsKey(tp.getName()) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 44) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 46) inferenceVariableTypes.add(inferenceVariableType) ==> java.util.List.add(E)
+  Line 47) inferenceVariableType.setCorrespondingTp(tp) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.setCorrespondingTp(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 48) inferenceVariableTypeMap.put(tp.getName(), inferenceVariableType) ==> java.util.Map.put(K, V)
+  Line 48) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 50) inferenceVariableTypeMap.get(tp.getName()) ==> java.util.Map.get(java.lang.Object)
+  Line 50) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 58) placeInferenceVariables(target) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 59) placeInferenceVariables(actual) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 60) registerCorrespondance(target, actual) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.registerCorrespondance(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 65) placeInferenceVariables(actual) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 69) formalType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 69) actualType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 70) formalType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 71) actualType.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 73) formalTypeAsReference.getQualifiedName().equals(actualTypeAsReference.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 73) formalTypeAsReference.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 73) actualTypeAsReference.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 74) actualTypeAsReference.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 75) formalTypeAsReference.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 76) ancestors.stream().filter((a) -> a.getQualifiedName().equals(formalParamTypeQName)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 76) ancestors.stream().filter((a) -> a.getQualifiedName().equals(formalParamTypeQName)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 76) ancestors.stream() ==> java.util.Collection.stream()
+  Line 76) a.getQualifiedName().equals(formalParamTypeQName) ==> java.lang.String.equals(java.lang.Object)
+  Line 76) a.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 76) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 77) correspondingFormalType.isEmpty() ==> java.util.List.isEmpty()
+  Line 78) formalTypeAsReference.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 79) actualTypeAsReference.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 80) ancestors.stream().filter(a -> a.getQualifiedName().equals(actualParamTypeQname)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 80) ancestors.stream().filter(a -> a.getQualifiedName().equals(actualParamTypeQname)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 80) ancestors.stream() ==> java.util.Collection.stream()
+  Line 80) a.getQualifiedName().equals(actualParamTypeQname) ==> java.lang.String.equals(java.lang.Object)
+  Line 80) a.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 80) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 81) correspondingActualType.isEmpty() ==> java.util.List.isEmpty()
+  Line 87) correspondingFormalType.get(0).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 87) correspondingFormalType.get(0) ==> java.util.List.get(int)
+  Line 90) formalTypeAsReference.getQualifiedName().equals(actualTypeAsReference.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 90) formalTypeAsReference.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 90) actualTypeAsReference.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 91) formalTypeAsReference.typeParametersValues().isEmpty() ==> java.util.List.isEmpty()
+  Line 91) formalTypeAsReference.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 92) actualTypeAsReference.isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 96) formalTypeAsReference.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 97) registerCorrespondance(formalTypeParameter, actualTypeAsReference.typeParametersValues().get(i)) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.registerCorrespondance(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 97) actualTypeAsReference.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 97) actualTypeAsReference.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 103) actualType.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 104) ((InferenceVariableType) formalType).registerEquivalentType(actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 106) ((InferenceVariableType) actualType).registerEquivalentType(formalType) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 108) actualType.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 110) actualType.equals(formalType) ==> java.lang.Object.equals(java.lang.Object)
+  Line 112) actualType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 112) formalType.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 113) registerCorrespondance(formalType.asArrayType().getComponentType(), actualType.asArrayType().getComponentType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.registerCorrespondance(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 113) formalType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 113) formalType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 113) actualType.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 113) actualType.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 114) formalType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 116) formalType.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 116) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 117) ((InferenceVariableType) actualType).registerEquivalentType(formalType.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 117) formalType.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 117) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 118) formalType.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 118) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 119) ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 119) formalType.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 119) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 122) actualType.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 123) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 124) actualType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 125) formalWildcard.isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 125) formalWildcard.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 126) formalWildcard.isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 126) actualWildcard.isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 127) ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualWildcard.getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 127) formalType.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 127) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 127) actualWildcard.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 128) formalWildcard.isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 128) actualWildcard.isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 129) ((InferenceVariableType) formalType.asWildcard().getBoundedType()).registerEquivalentType(actualWildcard.getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 129) formalType.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 129) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 129) actualWildcard.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 134) actualType.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 135) formalType.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 135) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 136) registerCorrespondance(formalType.asWildcard().getBoundedType(), actualType) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.registerCorrespondance(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 136) formalType.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 136) formalType.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 141) ((InferenceVariableType) actualType).registerEquivalentType(formalType) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 143) ((InferenceVariableType) actualType).registerEquivalentType(formalType) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 145) actualType.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 146) actualType.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
+  Line 147) constraintType.getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 148) ((InferenceVariableType) constraintType.getBound()).registerEquivalentType(formalType) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.registerEquivalentType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 148) constraintType.getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 150) actualType.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 151) formalType.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 154) registerCorrespondance(formalType, objectProvider.byName(actualType.asPrimitive().getBoxTypeQName())) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.registerCorrespondance(com.github.javaparser.symbolsolver.model.typesystem.Type, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 154) objectProvider.byName(actualType.asPrimitive().getBoxTypeQName()) ==> com.github.javaparser.symbolsolver.logic.ObjectProvider.byName(java.lang.String)
+  Line 154) actualType.asPrimitive().getBoxTypeQName() ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.getBoxTypeQName()
+  Line 154) actualType.asPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asPrimitive()
+  Line 157) formalType.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 157) actualType.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 162) type.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 163) type.asWildcard().isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 163) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 164) Wildcard.extendsBound(placeInferenceVariables(type.asWildcard().getBoundedType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 164) placeInferenceVariables(type.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 164) type.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 164) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 165) type.asWildcard().isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 165) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 166) Wildcard.superBound(placeInferenceVariables(type.asWildcard().getBoundedType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 166) placeInferenceVariables(type.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 166) type.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 166) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 170) type.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 171) inferenceVariableTypeForTp(type.asTypeParameter()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.inferenceVariableTypeForTp(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 171) type.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 172) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 173) type.asReferenceType().transformTypeParameters(tp -> placeInferenceVariables(tp)) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.transformTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer)
+  Line 173) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 173) placeInferenceVariables(tp) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 174) type.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 175) placeInferenceVariables(type.asArrayType().getComponentType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 175) type.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 175) type.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 176) type.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 176) type.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 176) type.isVoid() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isVoid()
+  Line 178) type.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 179) LambdaConstraintType.bound(placeInferenceVariables(type.asConstraintType().getBound())) ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.bound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 179) placeInferenceVariables(type.asConstraintType().getBound()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.placeInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 179) type.asConstraintType().getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 179) type.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
+  Line 183) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 190) inferenceVariableType.equivalentType() ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.equivalentType()
+  Line 191) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 192) type.asReferenceType().transformTypeParameters(tp -> resolve(tp)) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.transformTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer)
+  Line 192) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 192) resolve(tp) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 193) type.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 193) type.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 193) type.isVoid() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isVoid()
+  Line 195) type.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 196) resolve(type.asArrayType().getComponentType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 196) type.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 196) type.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 197) type.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 198) type.asWildcard().isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 198) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 199) Wildcard.extendsBound(resolve(type.asWildcard().getBoundedType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 199) resolve(type.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 199) type.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 199) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 200) type.asWildcard().isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 200) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 201) Wildcard.superBound(resolve(type.asWildcard().getBoundedType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 201) resolve(type.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceContext.resolve(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 201) type.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 201) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 206) type.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_InferenceVariableType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_InferenceVariableType.txt
new file mode 100644
index 0000000..1cfbf6a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_InferenceVariableType.txt
@@ -0,0 +1,53 @@
+  Line 53) this.equivalentTypes.add(type) ==> java.util.Set.add(E)
+  Line 81) wildcard.isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 82) inferenceVariableType.superTypes.add(wildcard.getBoundedType()) ==> java.util.Set.add(E)
+  Line 82) wildcard.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 84) wildcard.isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 86) inferenceVariableType.superTypes.add(wildcard.getBoundedType()) ==> java.util.Set.add(E)
+  Line 86) wildcard.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 102) considered.add(inferenceVariableType) ==> java.util.Set.add(E)
+  Line 104) result.addAll(inferenceVariableType.equivalentTypes.stream().filter(t -> !t.isTypeVariable() && !(t instanceof InferenceVariableType)).collect(Collectors.toSet())) ==> java.util.Set.addAll(java.util.Collection<? extends E>)
+  Line 104) inferenceVariableType.equivalentTypes.stream().filter(t -> !t.isTypeVariable() && !(t instanceof InferenceVariableType)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 104) inferenceVariableType.equivalentTypes.stream().filter(t -> !t.isTypeVariable() && !(t instanceof InferenceVariableType)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 104) inferenceVariableType.equivalentTypes.stream() ==> java.util.Collection.stream()
+  Line 104) t.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 104) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 105) inferenceVariableType.equivalentTypes.stream().filter(t -> t instanceof InferenceVariableType).forEach(t -> {
+    InferenceVariableType ivt = (InferenceVariableType) t;
+    if (!considered.contains(ivt)) {
+        result.addAll(concreteEquivalentTypesAlsoIndirectly(considered, ivt));
+    }
+}) ==> java.util.stream.Stream.forEach(java.util.function.Consumer<? super T>)
+  Line 105) inferenceVariableType.equivalentTypes.stream().filter(t -> t instanceof InferenceVariableType) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 105) inferenceVariableType.equivalentTypes.stream() ==> java.util.Collection.stream()
+  Line 107) considered.contains(ivt) ==> java.util.Set.contains(java.lang.Object)
+  Line 108) result.addAll(concreteEquivalentTypesAlsoIndirectly(considered, ivt)) ==> java.util.Set.addAll(java.util.Collection<? extends E>)
+  Line 108) concreteEquivalentTypesAlsoIndirectly(considered, ivt) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.concreteEquivalentTypesAlsoIndirectly(java.util.Set<com.github.javaparser.symbolsolver.logic.InferenceVariableType>, com.github.javaparser.symbolsolver.logic.InferenceVariableType)
+  Line 115) concreteEquivalentTypesAlsoIndirectly(new HashSet<>(), this) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.concreteEquivalentTypesAlsoIndirectly(java.util.Set<com.github.javaparser.symbolsolver.logic.InferenceVariableType>, com.github.javaparser.symbolsolver.logic.InferenceVariableType)
+  Line 116) concreteEquivalent.isEmpty() ==> java.util.Set.isEmpty()
+  Line 118) objectProvider.object() ==> com.github.javaparser.symbolsolver.logic.ObjectProvider.object()
+  Line 123) concreteEquivalent.size() ==> java.util.Set.size()
+  Line 124) concreteEquivalent.iterator().next() ==> java.util.Iterator.next()
+  Line 124) concreteEquivalent.iterator() ==> java.util.Set.iterator()
+  Line 126) equivalentTypes.stream().filter(t -> !t.isTypeVariable() && !hasInferenceVariables(t)).collect(Collectors.toSet()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 126) equivalentTypes.stream().filter(t -> !t.isTypeVariable() && !hasInferenceVariables(t)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 126) equivalentTypes.stream() ==> java.util.Collection.stream()
+  Line 127) t.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 127) hasInferenceVariables(t) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.hasInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 128) Collectors.toSet() ==> java.util.stream.Collectors.toSet()
+  Line 129) notTypeVariables.size() ==> java.util.Set.size()
+  Line 130) notTypeVariables.iterator().next() ==> java.util.Iterator.next()
+  Line 130) notTypeVariables.iterator() ==> java.util.Set.iterator()
+  Line 131) notTypeVariables.size() ==> java.util.Set.size()
+  Line 131) superTypes.isEmpty() ==> java.util.Set.isEmpty()
+  Line 132) superTypes.size() ==> java.util.Set.size()
+  Line 133) superTypes.iterator().next() ==> java.util.Iterator.next()
+  Line 133) superTypes.iterator() ==> java.util.Set.iterator()
+  Line 147) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 148) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 149) refType.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 150) hasInferenceVariables(t) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.hasInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 157) type.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 158) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 159) hasInferenceVariables(wildcardType.getBoundedType()) ==> com.github.javaparser.symbolsolver.logic.InferenceVariableType.hasInferenceVariables(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 159) wildcardType.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_ObjectProvider.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_ObjectProvider.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-logic/com_github_javaparser_symbolsolver_logic_ObjectProvider.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_AccessLevel.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_AccessLevel.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_AccessLevel.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_AnnotationDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_AnnotationDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_AnnotationDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ClassDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ClassDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ClassDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ConstructorDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ConstructorDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ConstructorDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_Declaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_Declaration.txt
new file mode 100644
index 0000000..ad95331
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_Declaration.txt
@@ -0,0 +1,4 @@
+  Line 70) String.format("%s is not a FieldDeclaration", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 77) String.format("%s is not a ParameterDeclaration", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 84) String.format("%s is not a TypeDeclaration", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 91) String.format("%s is not a MethodDeclaration", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_EnumDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_EnumDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_EnumDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_FieldDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_FieldDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_FieldDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_HasAccessLevel.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_HasAccessLevel.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_HasAccessLevel.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_InterfaceDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_InterfaceDeclaration.txt
new file mode 100644
index 0000000..146d79b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_InterfaceDeclaration.txt
@@ -0,0 +1,4 @@
+  Line 46) getInterfacesExtended() ==> com.github.javaparser.symbolsolver.model.declarations.InterfaceDeclaration.getInterfacesExtended()
+  Line 47) interfaces.add(interfaceDeclaration) ==> java.util.List.add(E)
+  Line 48) interfaces.addAll(interfaceDeclaration.getAllInterfacesAncestors()) ==> java.util.List.addAll(java.util.Collection<? extends E>)
+  Line 48) interfaceDeclaration.getAllInterfacesAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllInterfacesAncestors()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodAmbiguityException.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodAmbiguityException.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodAmbiguityException.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodLikeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodLikeDeclaration.txt
new file mode 100644
index 0000000..8e49e35
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_MethodLikeDeclaration.txt
@@ -0,0 +1,33 @@
+  Line 31) declaringType().getPackageName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getPackageName()
+  Line 31) declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 38) declaringType().getClassName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getClassName()
+  Line 38) declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 46) declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 46) declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 46) this.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 54) sb.append(getName()) ==> java.lang.StringBuffer.append(java.lang.String)
+  Line 54) getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 55) sb.append("(") ==> java.lang.StringBuffer.append(java.lang.String)
+  Line 56) getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 58) sb.append(", ") ==> java.lang.StringBuffer.append(java.lang.String)
+  Line 60) sb.append(getParam(i).describeType()) ==> java.lang.StringBuffer.append(java.lang.String)
+  Line 60) getParam(i).describeType() ==> com.github.javaparser.symbolsolver.model.declarations.ParameterDeclaration.describeType()
+  Line 60) getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 62) sb.append(")") ==> java.lang.StringBuffer.append(java.lang.String)
+  Line 63) sb.toString() ==> java.lang.StringBuffer.toString()
+  Line 71) declaringType().getId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getId()
+  Line 71) declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 71) this.getSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getSignature()
+  Line 95) getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 98) getParam(getNumberOfParams() - 1) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 98) getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 106) getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 109) getParam(getNumberOfParams() - 1).isVariadic() ==> com.github.javaparser.symbolsolver.model.declarations.ParameterDeclaration.isVariadic()
+  Line 109) getParam(getNumberOfParams() - 1) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 109) getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 115) this.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 116) tp.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 116) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 117) Optional.of(tp) ==> java.util.Optional.of(T)
+  Line 120) declaringType().findTypeParameter(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.findTypeParameter(java.lang.String)
+  Line 120) declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ParameterDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ParameterDeclaration.txt
new file mode 100644
index 0000000..753e4a8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ParameterDeclaration.txt
@@ -0,0 +1,7 @@
+  Line 46) isVariadic() ==> com.github.javaparser.symbolsolver.model.declarations.ParameterDeclaration.isVariadic()
+  Line 47) getType().asArrayType().getComponentType().describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 47) getType().asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 47) getType().asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 47) getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 49) getType().describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 49) getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ReferenceTypeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ReferenceTypeDeclaration.txt
new file mode 100644
index 0000000..85c3611
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ReferenceTypeDeclaration.txt
@@ -0,0 +1,85 @@
+  Line 45) Object.class.getCanonicalName().equals(getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 45) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 45) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 46) getAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAncestors()
+  Line 47) ancestors.add(ancestor) ==> java.util.List.add(E)
+  Line 48) ancestor.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 49) ancestors.contains(inheritedAncestor) ==> java.util.List.contains(java.lang.Object)
+  Line 50) ancestors.add(inheritedAncestor) ==> java.util.List.add(E)
+  Line 74) this.getAllFields().stream().filter(f -> f.getName().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 74) this.getAllFields().stream().filter(f -> f.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 74) this.getAllFields().stream() ==> java.util.Collection.stream()
+  Line 74) this.getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 74) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 74) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 75) field.isPresent() ==> java.util.Optional.isPresent()
+  Line 76) field.get() ==> java.util.Optional.get()
+  Line 86) getVisibleFields().stream().filter(f -> f.getName().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 86) getVisibleFields().stream().filter(f -> f.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 86) getVisibleFields().stream() ==> java.util.Collection.stream()
+  Line 86) getVisibleFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getVisibleFields()
+  Line 86) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 86) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 87) field.isPresent() ==> java.util.Optional.isPresent()
+  Line 88) field.get() ==> java.util.Optional.get()
+  Line 98) this.getAllFields().stream().filter(f -> f.getName().equals(name)).findFirst().isPresent() ==> java.util.Optional.isPresent()
+  Line 98) this.getAllFields().stream().filter(f -> f.getName().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 98) this.getAllFields().stream().filter(f -> f.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 98) this.getAllFields().stream() ==> java.util.Collection.stream()
+  Line 98) this.getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 98) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 98) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 105) getVisibleFields().stream().filter(f -> f.getName().equals(name)).findFirst().isPresent() ==> java.util.Optional.isPresent()
+  Line 105) getVisibleFields().stream().filter(f -> f.getName().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 105) getVisibleFields().stream().filter(f -> f.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 105) getVisibleFields().stream() ==> java.util.Collection.stream()
+  Line 105) getVisibleFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getVisibleFields()
+  Line 105) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 105) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 119) getAllFields().stream().filter(f -> f.declaringType().equals(this) || f.accessLevel() != AccessLevel.PRIVATE).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 119) getAllFields().stream().filter(f -> f.declaringType().equals(this) || f.accessLevel() != AccessLevel.PRIVATE) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 119) getAllFields().stream() ==> java.util.Collection.stream()
+  Line 119) getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 120) f.declaringType().equals(this) ==> java.lang.Object.equals(java.lang.Object)
+  Line 120) f.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration.declaringType()
+  Line 120) f.accessLevel() ==> com.github.javaparser.symbolsolver.model.declarations.HasAccessLevel.accessLevel()
+  Line 121) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 128) getAllFields().stream().filter(it -> !it.isStatic()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 128) getAllFields().stream().filter(it -> !it.isStatic()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 128) getAllFields().stream() ==> java.util.Collection.stream()
+  Line 128) getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 128) it.isStatic() ==> com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration.isStatic()
+  Line 128) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 135) getAllFields().stream().filter(it -> it.isStatic()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 135) getAllFields().stream().filter(it -> it.isStatic()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 135) getAllFields().stream() ==> java.util.Collection.stream()
+  Line 135) getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 135) it.isStatic() ==> com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration.isStatic()
+  Line 135) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 142) getAllFields().stream().filter(it -> it.declaringType().getQualifiedName().equals(getQualifiedName())).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 142) getAllFields().stream().filter(it -> it.declaringType().getQualifiedName().equals(getQualifiedName())) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 142) getAllFields().stream() ==> java.util.Collection.stream()
+  Line 142) getAllFields() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllFields()
+  Line 142) it.declaringType().getQualifiedName().equals(getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 142) it.declaringType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 142) it.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.FieldDeclaration.declaringType()
+  Line 142) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 142) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 175) other.isAssignableBy(this) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.isAssignableBy(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 197) hasDirectlyAnnotation(qualifiedName) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasDirectlyAnnotation(java.lang.String)
+  Line 200) getAllAncestors().stream().anyMatch(it -> it.asReferenceType().getTypeDeclaration().hasDirectlyAnnotation(qualifiedName)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 200) getAllAncestors().stream() ==> java.util.Collection.stream()
+  Line 200) getAllAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllAncestors()
+  Line 200) it.asReferenceType().getTypeDeclaration().hasDirectlyAnnotation(qualifiedName) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasDirectlyAnnotation(java.lang.String)
+  Line 200) it.asReferenceType().getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 200) it.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.asReferenceType()
+  Line 215) this.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 216) tp.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 216) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 217) Optional.of(tp) ==> java.util.Optional.of(T)
+  Line 220) this.containerType().isPresent() ==> java.util.Optional.isPresent()
+  Line 220) this.containerType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.containerType()
+  Line 221) this.containerType().get().findTypeParameter(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.findTypeParameter(java.lang.String)
+  Line 221) this.containerType().get() ==> java.util.Optional.get()
+  Line 221) this.containerType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.containerType()
+  Line 223) Optional.empty() ==> java.util.Optional.empty()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeDeclaration.txt
new file mode 100644
index 0000000..2524942
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeDeclaration.txt
@@ -0,0 +1,22 @@
+  Line 40) this.getClass().getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 40) this.getClass() ==> java.lang.Object.getClass()
+  Line 49) this.internalTypes().stream().filter(f -> f.getName().equals(name)).findFirst() ==> java.util.stream.Stream.findFirst()
+  Line 49) this.internalTypes().stream().filter(f -> f.getName().equals(name)) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 49) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 49) this.internalTypes() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.internalTypes()
+  Line 49) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 49) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 50) type.orElseThrow(() -> new UnsolvedSymbolException("Internal type not found: " + name)) ==> java.util.Optional.orElseThrow(java.util.function.Supplier<? extends X>)
+  Line 59) this.internalTypes().stream().anyMatch(f -> f.getName().equals(name)) ==> java.util.stream.Stream.anyMatch(java.util.function.Predicate<? super T>)
+  Line 59) this.internalTypes().stream() ==> java.util.Collection.stream()
+  Line 59) this.internalTypes() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.internalTypes()
+  Line 59) f.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 59) f.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 116) String.format("%s is not a class", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 123) String.format("%s is not an interface", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 130) String.format("%s is not an enum", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 137) String.format("%s is not a type parameter", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 141) String.format("%s is not a reference type", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 164) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 166) String.format("<localClass>:%s", getName()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 166) getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeParameterDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeParameterDeclaration.txt
new file mode 100644
index 0000000..13ee41c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeParameterDeclaration.txt
@@ -0,0 +1,7 @@
+  Line 104) getContainer() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getContainer()
+  Line 111) getContainer() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getContainer()
+  Line 118) getContainer() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getContainer()
+  Line 143) String.format("%s.%s", getContainerId(), getName()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 143) getContainerId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getContainerId()
+  Line 143) getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 218) isExtends() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.isExtends()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeParametrizable.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeParametrizable.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_TypeParametrizable.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ValueDeclaration.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ValueDeclaration.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_declarations_ValueDeclaration.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_methods_MethodUsage.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_methods_MethodUsage.txt
new file mode 100644
index 0000000..f63d08c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_methods_MethodUsage.txt
@@ -0,0 +1,24 @@
+  Line 41) TypeParametersMap.empty() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.empty()
+  Line 43) declaration.getNumberOfParams() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getNumberOfParams()
+  Line 44) paramTypes.add(declaration.getParam(i).getType()) ==> java.util.List.add(E)
+  Line 44) declaration.getParam(i).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 44) declaration.getParam(i) ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getParam(int)
+  Line 46) declaration.getReturnType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodDeclaration.getReturnType()
+  Line 50) TypeParametersMap.empty() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.empty()
+  Line 73) declaration.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
+  Line 77) declaration.declaringType() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.declaringType()
+  Line 89) paramTypes.get(i) ==> java.util.List.get(int)
+  Line 93) newParams.set(i, replaced) ==> java.util.List.set(int, E)
+  Line 109) paramTypes.size() ==> java.util.List.size()
+  Line 116) paramTypes.get(i) ==> java.util.List.get(int)
+  Line 125) typeParametersMap.toBuilder().setValue(typeParameter, type).build() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.Builder.build()
+  Line 125) typeParametersMap.toBuilder().setValue(typeParameter, type) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.Builder.setValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 125) typeParametersMap.toBuilder() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.toBuilder()
+  Line 128) paramTypes.size() ==> java.util.List.size()
+  Line 129) paramTypes.get(i) ==> java.util.List.get(int)
+  Line 130) originalParamType.replaceTypeVariables(typeParameter, type, inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 131) res.replaceParamType(i, newParamType) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceParamType(int, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 134) oldReturnType.replaceTypeVariables(typeParameter, type, inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 135) res.replaceReturnType(newReturnType) ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.replaceReturnType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 146) this.getDeclaration().getQualifiedSignature() ==> com.github.javaparser.symbolsolver.model.declarations.MethodLikeDeclaration.getQualifiedSignature()
+  Line 146) this.getDeclaration() ==> com.github.javaparser.symbolsolver.model.methods.MethodUsage.getDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_SymbolReference.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_SymbolReference.txt
new file mode 100644
index 0000000..02d4e19
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_SymbolReference.txt
@@ -0,0 +1,9 @@
+  Line 41) Optional.of(symbolDeclaration) ==> java.util.Optional.of(T)
+  Line 48) Optional.<S>empty() ==> java.util.Optional.empty()
+  Line 60) isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 63) correspondingDeclaration.get() ==> java.util.Optional.get()
+  Line 70) correspondingDeclaration.isPresent() ==> java.util.Optional.isPresent()
+  Line 74) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 75) SymbolReference.solved(ref.getCorrespondingDeclaration()) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.solved(S2)
+  Line 75) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
+  Line 77) SymbolReference.unsolved(clazz) ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.unsolved(java.lang.Class<S2>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_TypeSolver.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_TypeSolver.txt
new file mode 100644
index 0000000..e513843
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_TypeSolver.txt
@@ -0,0 +1,6 @@
+  Line 33) getParent() ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.getParent()
+  Line 36) getParent().getRoot() ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.getRoot()
+  Line 36) getParent() ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.getParent()
+  Line 60) tryToSolveType(name) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.tryToSolveType(java.lang.String)
+  Line 61) ref.isSolved() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.isSolved()
+  Line 62) ref.getCorrespondingDeclaration() ==> com.github.javaparser.symbolsolver.model.resolution.SymbolReference.getCorrespondingDeclaration()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_UnsolvedSymbolException.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_UnsolvedSymbolException.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_UnsolvedSymbolException.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_Value.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_Value.txt
new file mode 100644
index 0000000..22635bd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_resolution_Value.txt
@@ -0,0 +1,2 @@
+  Line 40) decl.getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 41) decl.getName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.getName()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_ArrayType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_ArrayType.txt
new file mode 100644
index 0000000..55d4971
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_ArrayType.txt
@@ -0,0 +1,18 @@
+  Line 43) getClass() ==> java.lang.Object.getClass()
+  Line 43) o.getClass() ==> java.lang.Object.getClass()
+  Line 47) baseType.equals(that.baseType) ==> java.lang.Object.equals(java.lang.Object)
+  Line 54) baseType.hashCode() ==> java.lang.Object.hashCode()
+  Line 78) baseType.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 87) other.isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 88) baseType.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 88) other.asArrayType().getComponentType().isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 88) other.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 88) other.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 89) baseType.equals(other.asArrayType().getComponentType()) ==> java.lang.Object.equals(java.lang.Object)
+  Line 89) other.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 89) other.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 91) baseType.isAssignableBy(other.asArrayType().getComponentType()) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 91) other.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 91) other.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 92) other.isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 100) baseType.replaceTypeVariables(tpToReplace, replaced, inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_LambdaConstraintType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_LambdaConstraintType.txt
new file mode 100644
index 0000000..e6dd2a3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_LambdaConstraintType.txt
@@ -0,0 +1,2 @@
+  Line 12) bound.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 35) bound.isAssignableBy(other) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_NullType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_NullType.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_NullType.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_PrimitiveType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_PrimitiveType.txt
new file mode 100644
index 0000000..723b5f5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_PrimitiveType.txt
@@ -0,0 +1,33 @@
+  Line 32) Byte.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 32) ImmutableList.of() ==> com.google.common.collect.ImmutableList.of()
+  Line 33) Short.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 33) ImmutableList.of(BYTE) ==> com.google.common.collect.ImmutableList.of(E)
+  Line 34) Character.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 34) ImmutableList.of() ==> com.google.common.collect.ImmutableList.of()
+  Line 35) Integer.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 35) ImmutableList.of(BYTE, SHORT, CHAR) ==> com.google.common.collect.ImmutableList.of(E, E, E)
+  Line 36) Long.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 36) ImmutableList.of(BYTE, SHORT, INT, CHAR) ==> com.google.common.collect.ImmutableList.of(E, E, E, E)
+  Line 37) Boolean.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 37) ImmutableList.of() ==> com.google.common.collect.ImmutableList.of()
+  Line 38) Float.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 38) ImmutableList.of(LONG, INT, SHORT, BYTE, CHAR) ==> com.google.common.collect.ImmutableList.of(E, E, E, E, E)
+  Line 39) Double.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 39) ImmutableList.of(FLOAT, LONG, INT, SHORT, BYTE, CHAR) ==> com.google.common.collect.ImmutableList.of(E, E, E, E, E, E)
+  Line 40) ImmutableList.of(INT, BOOLEAN, LONG, CHAR, FLOAT, DOUBLE, SHORT, BYTE) ==> com.google.common.collect.ImmutableList.of(E, E, E, E, E, E, E, E)
+  Line 57) name.toLowerCase() ==> java.lang.String.toLowerCase()
+  Line 59) ptu.describe().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 59) ptu.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.describe()
+  Line 104) other.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 105) promotionTypes.contains(other) ==> java.util.List.contains(java.lang.Object)
+  Line 106) other.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 107) other.asReferenceType().getQualifiedName().equals(boxTypeQName) ==> java.lang.String.equals(java.lang.Object)
+  Line 107) other.asReferenceType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 107) other.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 111) other.asReferenceType().getQualifiedName().equals(promotion.boxTypeQName) ==> java.lang.String.equals(java.lang.Object)
+  Line 111) other.asReferenceType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 111) other.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 116) other.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 117) this.isAssignableBy(other.asConstraintType().getBound()) ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 117) other.asConstraintType().getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 117) other.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_PrimitiveType_J9.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_PrimitiveType_J9.txt
new file mode 100644
index 0000000..57a7c2a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_PrimitiveType_J9.txt
@@ -0,0 +1,33 @@
+  Line 32) Byte.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 32) ImmutableList.of() ==> com.google.common.collect.ImmutableList.of()
+  Line 33) Short.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 33) ImmutableList.of(BYTE) ==> java.util.List.of(E...)
+  Line 34) Character.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 34) ImmutableList.of() ==> com.google.common.collect.ImmutableList.of()
+  Line 35) Integer.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 35) ImmutableList.of(BYTE, SHORT, CHAR) ==> java.util.List.of(E...)
+  Line 36) Long.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 36) ImmutableList.of(BYTE, SHORT, INT, CHAR) ==> java.util.List.of(E...)
+  Line 37) Boolean.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 37) ImmutableList.of() ==> com.google.common.collect.ImmutableList.of()
+  Line 38) Float.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 38) ImmutableList.of(LONG, INT, SHORT, BYTE, CHAR) ==> java.util.List.of(E...)
+  Line 39) Double.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 39) ImmutableList.of(FLOAT, LONG, INT, SHORT, BYTE, CHAR) ==> java.util.List.of(E...)
+  Line 40) ImmutableList.of(INT, BOOLEAN, LONG, CHAR, FLOAT, DOUBLE, SHORT, BYTE) ==> java.util.List.of(E...)
+  Line 57) name.toLowerCase() ==> java.lang.String.toLowerCase()
+  Line 59) ptu.describe().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 59) ptu.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.describe()
+  Line 104) other.isPrimitive() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isPrimitive()
+  Line 105) promotionTypes.contains(other) ==> java.util.List.contains(java.lang.Object)
+  Line 106) other.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 107) other.asReferenceType().getQualifiedName().equals(boxTypeQName) ==> java.lang.String.equals(java.lang.Object)
+  Line 107) other.asReferenceType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 107) other.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 111) other.asReferenceType().getQualifiedName().equals(promotion.boxTypeQName) ==> java.lang.String.equals(java.lang.Object)
+  Line 111) other.asReferenceType().getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 111) other.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 116) other.isConstraint() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isConstraint()
+  Line 117) this.isAssignableBy(other.asConstraintType().getBound()) ==> com.github.javaparser.symbolsolver.model.typesystem.PrimitiveType.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 117) other.asConstraintType().getBound() ==> com.github.javaparser.symbolsolver.model.typesystem.LambdaConstraintType.getBound()
+  Line 117) other.asConstraintType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asConstraintType()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_ReferenceType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_ReferenceType.txt
new file mode 100644
index 0000000..6a1895d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_ReferenceType.txt
@@ -0,0 +1,240 @@
+  Line 53) deriveParams(typeDeclaration) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.deriveParams(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration)
+  Line 60) typeDeclaration.isTypeParameter() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isTypeParameter()
+  Line 63) typeParameters.size() ==> java.util.List.size()
+  Line 63) typeParameters.size() ==> java.util.List.size()
+  Line 63) typeDeclaration.getTypeParameters().size() ==> java.util.List.size()
+  Line 63) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 64) String.format("expected either zero type parameters or has many as defined in the declaration (%d). Found %d", typeDeclaration.getTypeParameters().size(), typeParameters.size()) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 65) typeDeclaration.getTypeParameters().size() ==> java.util.List.size()
+  Line 65) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 65) typeParameters.size() ==> java.util.List.size()
+  Line 68) typeParameters.size() ==> java.util.List.size()
+  Line 69) typeParametersMapBuilder.setValue(typeDeclaration.getTypeParameters().get(i), typeParameters.get(i)) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.Builder.setValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 69) typeDeclaration.getTypeParameters().get(i) ==> java.util.List.get(int)
+  Line 69) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 69) typeParameters.get(i) ==> java.util.List.get(int)
+  Line 71) typeParametersMapBuilder.build() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.Builder.build()
+  Line 83) getClass() ==> java.lang.Object.getClass()
+  Line 83) o.getClass() ==> java.lang.Object.getClass()
+  Line 87) typeDeclaration.equals(that.typeDeclaration) ==> java.lang.Object.equals(java.lang.Object)
+  Line 88) typeParametersMap.equals(that.typeParametersMap) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.equals(java.lang.Object)
+  Line 95) typeDeclaration.hashCode() ==> java.lang.Object.hashCode()
+  Line 96) typeParametersMap.hashCode() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.hashCode()
+  Line 102) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 132) hasName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.hasName()
+  Line 133) sb.append(typeDeclaration.getQualifiedName()) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 133) typeDeclaration.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 135) sb.append("<anonymous class>") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 137) typeParametersMap().isEmpty() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.isEmpty()
+  Line 137) typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 138) sb.append("<") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 139) sb.append(String.join(", ", typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap().getValue(tp).describe()).collect(Collectors.toList()))) ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 139) String.join(", ", typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap().getValue(tp).describe()).collect(Collectors.toList())) ==> java.lang.String.join(java.lang.CharSequence, java.lang.Iterable<? extends java.lang.CharSequence>)
+  Line 139) typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap().getValue(tp).describe()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 139) typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap().getValue(tp).describe()) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 139) typeDeclaration.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 139) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 140) typeParametersMap().getValue(tp).describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 140) typeParametersMap().getValue(tp) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 140) typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 141) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 142) sb.append(">") ==> java.lang.StringBuilder.append(java.lang.String)
+  Line 144) sb.toString() ==> java.lang.StringBuilder.toString()
+  Line 157) this.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 158) transformer.transform(tp) ==> com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer.transform(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 161) result.asReferenceType().typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 161) result.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 162) typeParametersCorrected.set(i, transformedTp) ==> java.util.List.set(int, E)
+  Line 163) create(typeDeclaration, typeParametersCorrected, typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.create(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 178) this.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 179) tp.replaceTypeVariables(tpToReplace, replaced, inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 181) tp.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 181) tp.asTypeVariable().describe().equals(tpToReplace.getName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 181) tp.asTypeVariable().describe() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.describe()
+  Line 181) tp.asTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeVariable()
+  Line 181) tpToReplace.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 182) inferredTypes.put(tp.asTypeParameter(), replaced) ==> java.util.Map.put(K, V)
+  Line 182) tp.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 185) result.asReferenceType().typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 185) result.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.asReferenceType()
+  Line 186) typeParametersCorrected.set(i, transformedTp) ==> java.util.List.set(int, E)
+  Line 187) create(typeDeclaration, typeParametersCorrected, typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.create(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 192) result.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 193) values.contains(tpToReplace) ==> java.util.List.contains(java.lang.Object)
+  Line 194) values.indexOf(tpToReplace) ==> java.util.List.indexOf(java.lang.Object)
+  Line 195) values.set(index, replaced) ==> java.util.List.set(int, E)
+  Line 196) create(result.getTypeDeclaration(), values, typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.create(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 196) result.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 233) typeDeclaration.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getAllAncestors()
+  Line 235) ancestors.stream().map(a -> typeParametersMap().replaceAll(a).asReferenceType()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 235) ancestors.stream().map(a -> typeParametersMap().replaceAll(a).asReferenceType()) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 235) ancestors.stream() ==> java.util.Collection.stream()
+  Line 236) typeParametersMap().replaceAll(a).asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 236) typeParametersMap().replaceAll(a) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.replaceAll(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 236) typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 237) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 240) ancestors.removeIf(a -> a.getQualifiedName().equals(Object.class.getCanonicalName())) ==> java.util.Collection.removeIf(java.util.function.Predicate<? super E>)
+  Line 240) a.getQualifiedName().equals(Object.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 240) a.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 240) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 241) typeSolver.solveType(Object.class.getCanonicalName()) ==> com.github.javaparser.symbolsolver.model.resolution.TypeSolver.solveType(java.lang.String)
+  Line 241) Object.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 242) create(objectType, typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.create(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 243) ancestors.add(objectRef) ==> java.util.List.add(E)
+  Line 248) getAllAncestors().stream().filter(it -> it.getTypeDeclaration().isInterface()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 248) getAllAncestors().stream().filter(it -> it.getTypeDeclaration().isInterface()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 248) getAllAncestors().stream() ==> java.util.Collection.stream()
+  Line 248) getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 249) it.getTypeDeclaration().isInterface() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isInterface()
+  Line 249) it.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 250) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 254) getAllAncestors().stream().filter(it -> it.getTypeDeclaration().isClass()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 254) getAllAncestors().stream().filter(it -> it.getTypeDeclaration().isClass()) ==> java.util.stream.Stream.filter(java.util.function.Predicate<? super T>)
+  Line 254) getAllAncestors().stream() ==> java.util.Collection.stream()
+  Line 254) getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 255) it.getTypeDeclaration().isClass() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.isClass()
+  Line 255) it.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 256) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 268) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 269) tp.getName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 269) tp.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 270) Optional.of(this.typeParametersMap().getValue(tp)) ==> java.util.Optional.of(T)
+  Line 270) this.typeParametersMap().getValue(tp) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 270) this.typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 273) Optional.empty() ==> java.util.Optional.empty()
+  Line 281) this.typeParametersMap.isEmpty() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.isEmpty()
+  Line 281) Collections.emptyList() ==> java.util.Collections.emptyList()
+  Line 281) typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap.getValue(tp)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 281) typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap.getValue(tp)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 281) typeDeclaration.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 281) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 281) typeParametersMap.getValue(tp) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 281) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 290) isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 291) typeDeclaration.getTypeParameters().size() ==> java.util.List.size()
+  Line 291) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 292) typeParametersMap.add(new Tuple2<>(typeDeclaration.getTypeParameters().get(0), typeParametersValues().get(i))) ==> java.util.List.add(E)
+  Line 292) typeDeclaration.getTypeParameters().get(0) ==> java.util.List.get(int)
+  Line 292) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 292) typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 292) typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 319) typeDeclaration.hasField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.hasField(java.lang.String)
+  Line 320) Optional.empty() ==> java.util.Optional.empty()
+  Line 322) typeDeclaration.getField(name).getType() ==> com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration.getType()
+  Line 322) typeDeclaration.getField(name) ==> com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration.getField(java.lang.String)
+  Line 323) useThisTypeParametersOnTheGivenType(type) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 324) Optional.of(type) ==> java.util.Optional.of(T)
+  Line 331) typeDeclaration.hasName() ==> com.github.javaparser.symbolsolver.model.declarations.Declaration.hasName()
+  Line 338) typeDeclaration.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getQualifiedName()
+  Line 345) typeDeclaration.getId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getId()
+  Line 354) typeDeclaration.getTypeParameters().isEmpty() ==> java.util.List.isEmpty()
+  Line 354) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 355) typeParametersMap().isEmpty() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.isEmpty()
+  Line 355) typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 358) typeParametersMap().getNames() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getNames()
+  Line 358) typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 359) typeParametersMap().getValueBySignature(name) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValueBySignature(java.lang.String)
+  Line 359) typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 360) value.isPresent() ==> java.util.Optional.isPresent()
+  Line 360) value.get().isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 360) value.get() ==> java.util.Optional.get()
+  Line 360) value.get().asTypeVariable().qualifiedName().equals(name) ==> java.lang.String.equals(java.lang.Object)
+  Line 360) value.get().asTypeVariable().qualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.qualifiedName()
+  Line 360) value.get().asTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeVariable()
+  Line 360) value.get() ==> java.util.Optional.get()
+  Line 372) typeParameterDeclaration.declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 375) this.getTypeDeclaration().getId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeDeclaration.getId()
+  Line 375) this.getTypeDeclaration() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getTypeDeclaration()
+  Line 376) typeId.equals(typeParameterDeclaration.getContainerId()) ==> java.lang.String.equals(java.lang.Object)
+  Line 376) typeParameterDeclaration.getContainerId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getContainerId()
+  Line 377) Optional.of(this.typeParametersMap().getValue(typeParameterDeclaration)) ==> java.util.Optional.of(T)
+  Line 377) this.typeParametersMap().getValue(typeParameterDeclaration) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 377) this.typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 379) this.getAllAncestors() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getAllAncestors()
+  Line 380) ancestor.getId().equals(typeParameterDeclaration.getContainerId()) ==> java.lang.String.equals(java.lang.Object)
+  Line 380) ancestor.getId() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getId()
+  Line 380) typeParameterDeclaration.getContainerId() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getContainerId()
+  Line 381) Optional.of(ancestor.typeParametersMap().getValue(typeParameterDeclaration)) ==> java.util.Optional.of(T)
+  Line 381) ancestor.typeParametersMap().getValue(typeParameterDeclaration) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 381) ancestor.typeParametersMap() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersMap()
+  Line 384) Optional.empty() ==> java.util.Optional.empty()
+  Line 394) create(typeDeclaration, typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap.getValue(tp)).collect(Collectors.toList()), typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.create(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, java.util.List<com.github.javaparser.symbolsolver.model.typesystem.Type>, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 394) typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap.getValue(tp)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 394) typeDeclaration.getTypeParameters().stream().map(tp -> typeParametersMap.getValue(tp)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 394) typeDeclaration.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 394) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 395) typeParametersMap.getValue(tp) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 396) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 404) getQualifiedName().equals(Boolean.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 404) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 404) Boolean.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 406) getQualifiedName().equals(Character.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 406) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 406) Character.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 408) getQualifiedName().equals(Byte.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 408) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 408) Byte.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 410) getQualifiedName().equals(Short.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 410) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 410) Short.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 412) getQualifiedName().equals(Integer.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 412) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 412) Integer.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 414) getQualifiedName().equals(Long.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 414) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 414) Long.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 416) getQualifiedName().equals(Float.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 416) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 416) Float.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 418) getQualifiedName().equals(Double.class.getCanonicalName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 418) getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 418) Double.class.getCanonicalName() ==> java.lang.Class.getCanonicalName()
+  Line 425) other.equals(this) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.equals(java.lang.Object)
+  Line 428) this.getQualifiedName().equals(other.getQualifiedName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 428) this.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 428) other.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.getQualifiedName()
+  Line 429) this.isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 429) other.isRawType() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.isRawType()
+  Line 432) this.typeParametersValues().size() ==> java.util.List.size()
+  Line 432) this.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 432) other.typeParametersValues().size() ==> java.util.List.size()
+  Line 432) other.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 435) typeParametersValues().size() ==> java.util.List.size()
+  Line 435) typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 436) typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 436) typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 437) other.typeParametersValues().get(i) ==> java.util.List.get(int)
+  Line 437) other.typeParametersValues() ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.typeParametersValues()
+  Line 438) thisParam.equals(otherParam) ==> java.lang.Object.equals(java.lang.Object)
+  Line 441) thisParamAsWildcard.isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 441) otherParam.isAssignableBy(thisParamAsWildcard.getBoundedType()) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 441) thisParamAsWildcard.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 443) thisParamAsWildcard.isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 443) thisParamAsWildcard.getBoundedType().isAssignableBy(otherParam) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 443) thisParamAsWildcard.getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 445) thisParamAsWildcard.isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 452) thisParam.asTypeVariable().asTypeParameter().getBounds(this.typeSolver).stream().map(bound -> bound.getType()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 452) thisParam.asTypeVariable().asTypeParameter().getBounds(this.typeSolver).stream().map(bound -> bound.getType()) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 452) thisParam.asTypeVariable().asTypeParameter().getBounds(this.typeSolver).stream() ==> java.util.Collection.stream()
+  Line 452) thisParam.asTypeVariable().asTypeParameter().getBounds(this.typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 452) thisParam.asTypeVariable().asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.asTypeParameter()
+  Line 452) thisParam.asTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeVariable()
+  Line 452) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 452) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 453) otherParam.asTypeVariable().asTypeParameter().getBounds(other.typeSolver).stream().map(bound -> bound.getType()).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 453) otherParam.asTypeVariable().asTypeParameter().getBounds(other.typeSolver).stream().map(bound -> bound.getType()) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 453) otherParam.asTypeVariable().asTypeParameter().getBounds(other.typeSolver).stream() ==> java.util.Collection.stream()
+  Line 453) otherParam.asTypeVariable().asTypeParameter().getBounds(other.typeSolver) ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getBounds(com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
+  Line 453) otherParam.asTypeVariable().asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.asTypeParameter()
+  Line 453) otherParam.asTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeVariable()
+  Line 453) bound.getType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.Bound.getType()
+  Line 453) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 454) thisBounds.size() ==> java.util.List.size()
+  Line 454) otherBounds.size() ==> java.util.List.size()
+  Line 454) otherBounds.containsAll(thisBounds) ==> java.util.List.containsAll(java.util.Collection<? extends java.lang.Object>)
+  Line 472) typeDeclaration.getTypeParameters().stream().map((tp) -> new TypeVariable(tp)).collect(Collectors.toList()) ==> java.util.stream.Stream.collect(java.util.stream.Collector<? super T, A, R>)
+  Line 472) typeDeclaration.getTypeParameters().stream().map((tp) -> new TypeVariable(tp)) ==> java.util.stream.Stream.map(java.util.function.Function<? super T, ? extends R>)
+  Line 472) typeDeclaration.getTypeParameters().stream() ==> java.util.Collection.stream()
+  Line 472) typeDeclaration.getTypeParameters() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParametrizable.getTypeParameters()
+  Line 472) Collectors.toList() ==> java.util.stream.Collectors.toList()
+  Line 476) create(typeDeclaration, typeParametersMap, typeSolver) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.create(com.github.javaparser.symbolsolver.model.declarations.ReferenceTypeDeclaration, com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap, com.github.javaparser.symbolsolver.model.resolution.TypeSolver)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_Type.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_Type.txt
new file mode 100644
index 0000000..afd7bd4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_Type.txt
@@ -0,0 +1,17 @@
+  Line 48) isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 49) this.asArrayType().getComponentType().arrayLevel() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.arrayLevel()
+  Line 49) this.asArrayType().getComponentType() ==> com.github.javaparser.symbolsolver.model.typesystem.ArrayType.getComponentType()
+  Line 49) this.asArrayType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asArrayType()
+  Line 73) isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 73) isArray() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isArray()
+  Line 73) isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 73) isNull() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isNull()
+  Line 73) isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 106) String.format("%s is not an Array", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 110) String.format("%s is not a Reference Type", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 114) String.format("%s is not a Type parameter", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 118) String.format("%s is not a Type variable", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 122) String.format("%s is not a Primitive type", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 126) String.format("%s is not a Wildcard", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 130) String.format("%s is not a constraint type", this) ==> java.lang.String.format(java.lang.String, java.lang.Object...)
+  Line 156) replaceTypeVariables(tp, replaced, new HashMap<>()) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_TypeTransformer.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_TypeTransformer.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_TypeTransformer.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_TypeVariable.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_TypeVariable.txt
new file mode 100644
index 0000000..56f72e8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_TypeVariable.txt
@@ -0,0 +1,22 @@
+  Line 39) typeParameter.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 43) this.typeParameter.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 49) getClass() ==> java.lang.Object.getClass()
+  Line 49) o.getClass() ==> java.lang.Object.getClass()
+  Line 53) typeParameter.getName().equals(that.typeParameter.getName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 53) typeParameter.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 53) that.typeParameter.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 54) typeParameter.declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 54) that.typeParameter.declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 55) typeParameter.declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 55) that.typeParameter.declaredOnMethod() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnMethod()
+  Line 62) typeParameter.hashCode() ==> java.lang.Object.hashCode()
+  Line 77) tpToBeReplaced.getName().equals(this.typeParameter.getName()) ==> java.lang.String.equals(java.lang.Object)
+  Line 77) tpToBeReplaced.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 77) this.typeParameter.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 78) inferredTypes.put(this.asTypeParameter(), replaced) ==> java.util.Map.put(K, V)
+  Line 78) this.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.asTypeParameter()
+  Line 92) typeParameter.getName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getName()
+  Line 112) other.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 113) describe().equals(other.describe()) ==> java.lang.String.equals(java.lang.Object)
+  Line 113) describe() ==> com.github.javaparser.symbolsolver.model.typesystem.TypeVariable.describe()
+  Line 113) other.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_VoidType.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_VoidType.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_VoidType.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_Wildcard.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_Wildcard.txt
new file mode 100644
index 0000000..4695dca
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_Wildcard.txt
@@ -0,0 +1,9 @@
+  Line 81) boundedType.equals(that.boundedType) ==> java.lang.Object.equals(java.lang.Object)
+  Line 89) type.hashCode() ==> java.lang.Enum.hashCode()
+  Line 90) boundedType.hashCode() ==> java.lang.Object.hashCode()
+  Line 99) boundedType.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 101) boundedType.describe() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.describe()
+  Line 116) isSuper() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isSuper()
+  Line 116) isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 132) boundedType.isAssignableBy(other) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isAssignableBy(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 148) boundedType.replaceTypeVariables(tpToReplace, replaced, inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParameterValueProvider.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParameterValueProvider.txt
new file mode 100644
index 0000000..bead9ac
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParameterValueProvider.txt
@@ -0,0 +1,23 @@
+  Line 25) type.isTypeVariable() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isTypeVariable()
+  Line 26) type.asTypeParameter() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asTypeParameter()
+  Line 27) typeParameter.declaredOnType() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.declaredOnType()
+  Line 28) typeParamValue(typeParameter) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.typeParamValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
+  Line 29) typeParam.isPresent() ==> java.util.Optional.isPresent()
+  Line 30) typeParam.get() ==> java.util.Optional.get()
+  Line 35) type.isWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isWildcard()
+  Line 35) type.asWildcard().isBounded() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isBounded()
+  Line 35) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 36) type.asWildcard().isExtends() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.isExtends()
+  Line 36) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 37) Wildcard.extendsBound(useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.extendsBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 37) useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 37) type.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 37) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 39) Wildcard.superBound(useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType())) ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.superBound(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 39) useThisTypeParametersOnTheGivenType(type.asWildcard().getBoundedType()) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
+  Line 39) type.asWildcard().getBoundedType() ==> com.github.javaparser.symbolsolver.model.typesystem.Wildcard.getBoundedType()
+  Line 39) type.asWildcard() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asWildcard()
+  Line 43) type.isReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.isReferenceType()
+  Line 44) type.asReferenceType().transformTypeParameters(tp -> useThisTypeParametersOnTheGivenType(tp)) ==> com.github.javaparser.symbolsolver.model.typesystem.ReferenceType.transformTypeParameters(com.github.javaparser.symbolsolver.model.typesystem.TypeTransformer)
+  Line 44) type.asReferenceType() ==> com.github.javaparser.symbolsolver.model.typesystem.Type.asReferenceType()
+  Line 44) useThisTypeParametersOnTheGivenType(tp) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParameterValueProvider.useThisTypeParametersOnTheGivenType(com.github.javaparser.symbolsolver.model.typesystem.Type)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParametersMap.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParametersMap.txt
new file mode 100644
index 0000000..28d9985
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParametersMap.txt
@@ -0,0 +1,24 @@
+  Line 43) this.nameToValue.putAll(nameToValue) ==> java.util.Map.putAll(java.util.Map<? extends K, ? extends V>)
+  Line 45) this.nameToDeclaration.putAll(nameToDeclaration) ==> java.util.Map.putAll(java.util.Map<? extends K, ? extends V>)
+  Line 54) typeParameter.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 55) nameToValue.put(qualifiedName, value) ==> java.util.Map.put(K, V)
+  Line 56) nameToDeclaration.put(qualifiedName, typeParameter) ==> java.util.Map.put(K, V)
+  Line 68) nameToValue.equals(that.nameToValue) ==> java.util.Map.equals(java.lang.Object)
+  Line 68) nameToDeclaration.equals(that.nameToDeclaration) ==> java.util.Map.equals(java.lang.Object)
+  Line 74) nameToValue.hashCode() ==> java.util.Map.hashCode()
+  Line 88) new Builder().build() ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.Builder.build()
+  Line 93) this.nameToValue.putAll(nameToValue) ==> java.util.Map.putAll(java.util.Map<? extends K, ? extends V>)
+  Line 95) this.nameToDeclaration.putAll(nameToDeclaration) ==> java.util.Map.putAll(java.util.Map<? extends K, ? extends V>)
+  Line 99) typeParameter.getQualifiedName() ==> com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration.getQualifiedName()
+  Line 100) nameToValue.containsKey(qualifiedName) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 101) nameToValue.get(qualifiedName) ==> java.util.Map.get(java.lang.Object)
+  Line 108) nameToValue.containsKey(signature) ==> java.util.Map.containsKey(java.lang.Object)
+  Line 109) Optional.of(nameToValue.get(signature)) ==> java.util.Optional.of(T)
+  Line 109) nameToValue.get(signature) ==> java.util.Map.get(java.lang.Object)
+  Line 111) Optional.empty() ==> java.util.Optional.empty()
+  Line 116) nameToValue.keySet() ==> java.util.Map.keySet()
+  Line 120) nameToValue.values() ==> java.util.Map.values()
+  Line 128) nameToValue.isEmpty() ==> java.util.Map.isEmpty()
+  Line 133) this.nameToDeclaration.values() ==> java.util.Map.values()
+  Line 134) type.replaceTypeVariables(typeParameterDeclaration, getValue(typeParameterDeclaration), inferredTypes) ==> com.github.javaparser.symbolsolver.model.typesystem.Type.replaceTypeVariables(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type, java.util.Map<com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration, com.github.javaparser.symbolsolver.model.typesystem.Type>)
+  Line 134) getValue(typeParameterDeclaration) ==> com.github.javaparser.symbolsolver.model.typesystem.parametrization.TypeParametersMap.getValue(com.github.javaparser.symbolsolver.model.declarations.TypeParameterDeclaration)
diff --git a/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParametrized.txt b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParametrized.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/javasymbolsolver_0_6_0/expected_output/java-symbol-solver-model/com_github_javaparser_symbolsolver_model_typesystem_parametrization_TypeParametrized.txt
diff --git a/javaparser-symbol-solver-testing/src/test/resources/junit-4.8.1.jar b/javaparser-symbol-solver-testing/src/test/resources/junit-4.8.1.jar
new file mode 100644
index 0000000..524cd65
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/junit-4.8.1.jar
Binary files differ
diff --git a/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Base.java b/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Base.java
new file mode 100644
index 0000000..1deebf2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Base.java
@@ -0,0 +1,5 @@
+
+
+public interface Base<T, S extends Base<T, S>>{
+
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Extends.java b/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Extends.java
new file mode 100644
index 0000000..5f69935
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Extends.java
@@ -0,0 +1,8 @@
+import java.util.stream.BaseStream;
+
+public interface Extends extends Base<Integer, Extends> {
+
+    public static void foo() {
+
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Usage.java b/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Usage.java
new file mode 100644
index 0000000..fb8fb2e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/recursion-issue/Usage.java
@@ -0,0 +1,6 @@
+class Usage{
+
+    void bar(){
+        Extends.foo();
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/a/src/a.java b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/a/src/a.java
new file mode 100644
index 0000000..909044a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/a/src/a.java
@@ -0,0 +1,2 @@
+public class a {
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/a/src/package_a/a.java b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/a/src/package_a/a.java
new file mode 100644
index 0000000..198c2e4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/a/src/package_a/a.java
@@ -0,0 +1,4 @@
+package package_a;
+
+public class a {
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/b/src/b.java b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/b/src/b.java
new file mode 100644
index 0000000..9d113aa
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/b/src/b.java
@@ -0,0 +1,2 @@
+public class b {
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/b/src/package_b/b.java b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/b/src/package_b/b.java
new file mode 100644
index 0000000..6b0c607
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/b/src/package_b/b.java
@@ -0,0 +1,4 @@
+package package_b;
+
+public class b {
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/c/src/c.java b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/c/src/c.java
new file mode 100644
index 0000000..c8745a1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/c/src/c.java
@@ -0,0 +1,2 @@
+public class c {
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/c/src/package_c/c.java b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/c/src/package_c/c.java
new file mode 100644
index 0000000..4eb5849
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/c/src/package_c/c.java
@@ -0,0 +1,4 @@
+package package_c;
+
+public class c {
+}
diff --git a/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/src/Main.java b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/src/Main.java
new file mode 100644
index 0000000..a0428da
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/resources/symbolsolver_quicksetup/src/Main.java
@@ -0,0 +1,6 @@
+public class Main {
+
+    public static void main(String[] args) {
+        System.out.println("Hello World!");
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/CommentsInserter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/CommentsInserter.java
new file mode 100644
index 0000000..eee450d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/CommentsInserter.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.utils.PositionUtils;
+
+import java.util.*;
+
+import static com.github.javaparser.ast.Node.NODE_BY_BEGIN_POSITION;
+
+/**
+ * Assigns comments to nodes of the AST.
+ * 
+ * @author Sebastian Kuerten
+ * @author Júlio Vilmar Gesser
+ */
+class CommentsInserter {
+    private final ParserConfiguration configuration;
+
+    CommentsInserter(ParserConfiguration configuration) {
+        this.configuration = configuration;
+    }
+    
+    /**
+     * Comments are attributed to the thing they comment and are removed from
+     * the comments.
+     */
+    private void insertComments(CompilationUnit cu, TreeSet<Comment> comments) {
+        if (comments.isEmpty())
+            return;
+
+        /* I should sort all the direct children and the comments, if a comment
+         is the first thing then it
+         a comment to the CompilationUnit */
+
+        // FIXME if there is no package it could be also a comment to the following class...
+        // so I could use some heuristics in these cases to distinguish the two
+        // cases
+
+        List<Node> children = cu.getChildrenNodes();
+        PositionUtils.sortByBeginPosition(children);
+
+        Comment firstComment = comments.iterator().next();
+        if (cu.getPackage() != null
+                && (children.isEmpty() || PositionUtils.areInOrder(
+                firstComment, children.get(0)))) {
+            cu.setComment(firstComment);
+            comments.remove(firstComment);
+        }
+    }
+
+    /**
+     * This method try to attributes the nodes received to child of the node. It
+     * returns the node that were not attributed.
+     */
+    void insertComments(Node node, TreeSet<Comment> commentsToAttribute) {
+        if (commentsToAttribute.isEmpty())
+            return;
+        
+        if(node instanceof CompilationUnit){
+            insertComments((CompilationUnit)node, commentsToAttribute);
+        }
+
+        // the comments can:
+        // 1) Inside one of the child, then it is the child that have to
+        // associate them
+        // 2) If they are not inside a child they could be preceeding nothing, a
+        // comment or a child
+        // if they preceed a child they are assigned to it, otherweise they
+        // remain "orphans"
+
+        List<Node> children = node.getChildrenNodes();
+        PositionUtils.sortByBeginPosition(children);
+
+        for (Node child : children) {
+            TreeSet<Comment> commentsInsideChild = new TreeSet<>(NODE_BY_BEGIN_POSITION);
+            for (Comment c : commentsToAttribute) {
+                if (PositionUtils.nodeContains(child, c,
+                        configuration.doNotConsiderAnnotationsAsNodeStartForCodeAttribution)) {
+                    commentsInsideChild.add(c);
+                }
+            }
+            commentsToAttribute.removeAll(commentsInsideChild);
+            insertComments(child, commentsInsideChild);
+        }
+
+        /* I can attribute in line comments to elements preceeding them, if
+         there is something contained in their line */
+        List<Comment> attributedComments = new LinkedList<>();
+        for (Comment comment : commentsToAttribute) {
+            if (comment.isLineComment()) {
+                for (Node child : children) {
+                    if (child.getEnd().line == comment.getBegin().line
+                        && attributeLineCommentToNodeOrChild(child,
+                                comment.asLineComment())) {
+                            attributedComments.add(comment);
+                    }
+                }
+            }
+        }
+
+        /* at this point I create an ordered list of all remaining comments and
+         children */
+        Comment previousComment = null;
+        attributedComments = new LinkedList<>();
+        List<Node> childrenAndComments = new LinkedList<>();
+        childrenAndComments.addAll(children);
+        childrenAndComments.addAll(commentsToAttribute);
+        PositionUtils.sortByBeginPosition(childrenAndComments,
+                configuration.doNotConsiderAnnotationsAsNodeStartForCodeAttribution);
+
+        for (Node thing : childrenAndComments) {
+            if (thing instanceof Comment) {
+                previousComment = (Comment) thing;
+                if (!previousComment.isOrphan()) {
+                    previousComment = null;
+                }
+            } else {
+                if (previousComment != null && !thing.hasComment()) {
+                    if (!configuration.doNotAssignCommentsPrecedingEmptyLines
+                            || !thereAreLinesBetween(previousComment, thing)) {
+                        thing.setComment(previousComment);
+                        attributedComments.add(previousComment);
+                        previousComment = null;
+                    }
+                }
+            }
+        }
+
+        commentsToAttribute.removeAll(attributedComments);
+
+        // all the remaining are orphan nodes
+        for (Comment c : commentsToAttribute) {
+            if (c.isOrphan()) {
+                node.addOrphanComment(c);
+            }
+        }
+    }
+
+    private boolean attributeLineCommentToNodeOrChild(Node node, LineComment lineComment) {
+        // The node start and end at the same line as the comment,
+        // let's give to it the comment
+        if (node.getBegin().line == lineComment.getBegin().line
+                && !node.hasComment()) {
+            if(!(node instanceof Comment)) {
+                node.setComment(lineComment);
+            }
+            return true;
+        } else {
+            // try with all the children, sorted by reverse position (so the
+            // first one is the nearest to the comment
+            List<Node> children = new LinkedList<Node>();
+            children.addAll(node.getChildrenNodes());
+            PositionUtils.sortByBeginPosition(children);
+            Collections.reverse(children);
+
+            for (Node child : children) {
+                if (attributeLineCommentToNodeOrChild(child, lineComment)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+    private boolean thereAreLinesBetween(Node a, Node b) {
+        if (!PositionUtils.areInOrder(a, b)) {
+            return thereAreLinesBetween(b, a);
+        }
+        int endOfA = a.getEnd().line;
+        return b.getBegin().line > (endOfA + 1);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/JavaParser.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/JavaParser.java
new file mode 100644
index 0000000..7fdc77f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/JavaParser.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.comments.CommentsCollection;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import static com.github.javaparser.ParseStart.*;
+import static com.github.javaparser.Providers.UTF8;
+import static com.github.javaparser.Providers.provider;
+
+/**
+ * Parse Java source code and creates Abstract Syntax Trees.
+ *
+ * @author Júlio Vilmar Gesser
+ */
+public final class JavaParser {
+	private final CommentsInserter commentsInserter;
+
+	private ASTParser astParser = null;
+
+	/**
+	 * Instantiate the parser with default configuration. Note that parsing can also be done with the static methods on this class.
+	 * Creating an instance will reduce setup time between parsing files.
+	 */
+	public JavaParser() {
+		this(new ParserConfiguration());
+	}
+
+	/**
+	 * Instantiate the parser. Note that parsing can also be done with the static methods on this class.
+	 * Creating an instance will reduce setup time between parsing files.
+	 */
+	public JavaParser(ParserConfiguration configuration) {
+		commentsInserter = new CommentsInserter(configuration);
+	}
+
+	private ASTParser getParserForProvider(Provider provider) {
+		if (astParser == null) {
+			astParser = new ASTParser(provider);
+		} else {
+			astParser.ReInit(provider);
+		}
+		return astParser;
+	}
+
+	/**
+	 * Parses source code.
+	 * It takes the source code from a Provider.
+	 * The start indicates what can be found in the source code (compilation unit, block, import...)
+	 *
+     * @param start    refer to the constants in ParseStart to see what can be parsed.
+     * @param provider refer to Providers to see how you can read source.
+     * @param <N>      the subclass of Node that is the result of parsing in the start.
+     * @return the parse result, a collection of encountered problems, and some extra data.
+     */
+	public <N extends Node> ParseResult<N> parse(ParseStart<N> start, Provider provider) {
+		try {
+            final ASTParser parser = getParserForProvider(provider);
+			N resultNode = start.parse(parser);
+            final CommentsCollection comments = astParser.getCommentsCollection();
+            commentsInserter.insertComments(resultNode, comments.copy().getComments());
+            
+			return new ParseResult<>(Optional.of(resultNode), parser.problems, Optional.of(astParser.getTokens()), Optional.of(astParser.getCommentsCollection()));
+		} catch (ParseException e) {
+			return new ParseResult<>(e);
+        } catch (TokenMgrException e) {
+            return new ParseResult<>(e);
+		} finally {
+			try {
+				provider.close();
+			} catch (IOException e) {
+				// Since we're done parsing and have our result, we don't care about any errors.
+			}
+		}
+	}
+
+	/**
+	 * Parses the Java code contained in the {@link InputStream} and returns a
+	 * {@link CompilationUnit} that represents it.
+	 *
+	 * @param in       {@link InputStream} containing Java source code
+	 * @param encoding encoding of the source code
+	 * @return CompilationUnit representing the Java source code
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static CompilationUnit parse(final InputStream in, Charset encoding) {
+		return simplifiedParse(COMPILATION_UNIT, provider(in, encoding));
+	}
+
+	/**
+	 * Parses the Java code contained in the {@link InputStream} and returns a
+	 * {@link CompilationUnit} that represents it.<br>
+	 * Note: Uses UTF-8 encoding
+	 *
+	 * @param in {@link InputStream} containing Java source code
+	 * @return CompilationUnit representing the Java source code
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static CompilationUnit parse(final InputStream in) {
+		return parse(in, UTF8);
+	}
+
+	/**
+	 * Parses the Java code contained in a {@link File} and returns a
+	 * {@link CompilationUnit} that represents it.
+	 *
+	 * @param file     {@link File} containing Java source code
+	 * @param encoding encoding of the source code
+	 * @return CompilationUnit representing the Java source code
+	 * @throws ParseProblemException if the source code has parser errors
+     * @throws FileNotFoundException the file was not found
+	 */
+	public static CompilationUnit parse(final File file, final Charset encoding) throws FileNotFoundException {
+		return simplifiedParse(COMPILATION_UNIT, provider(file, encoding));
+	}
+
+	/**
+	 * Parses the Java code contained in a {@link File} and returns a
+	 * {@link CompilationUnit} that represents it.<br>
+	 * Note: Uses UTF-8 encoding
+	 *
+	 * @param file {@link File} containing Java source code
+	 * @return CompilationUnit representing the Java source code
+	 * @throws ParseProblemException if the source code has parser errors
+	 * @throws FileNotFoundException the file was not found
+	 */
+	public static CompilationUnit parse(final File file) throws FileNotFoundException {
+		return simplifiedParse(COMPILATION_UNIT, provider(file));
+	}
+
+	/**
+	 * Parses the Java code contained in a file and returns a
+	 * {@link CompilationUnit} that represents it.
+	 *
+	 * @param path     path to a file containing Java source code
+	 * @param encoding encoding of the source code
+	 * @return CompilationUnit representing the Java source code
+	 * @throws IOException the path could not be accessed
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static CompilationUnit parse(final Path path, final Charset encoding) throws IOException {
+		return simplifiedParse(COMPILATION_UNIT, provider(path, encoding));
+	}
+
+	/**
+	 * Parses the Java code contained in a file and returns a
+	 * {@link CompilationUnit} that represents it.<br>
+	 * Note: Uses UTF-8 encoding
+	 *
+	 * @param path     path to a file containing Java source code
+	 * @return CompilationUnit representing the Java source code
+	 * @throws ParseProblemException if the source code has parser errors
+	 * @throws IOException the path could not be accessed
+	 */
+	public static CompilationUnit parse(final Path path) throws IOException {
+		return simplifiedParse(COMPILATION_UNIT, provider(path));
+	}
+
+    /**
+     * Parses Java code from a Reader and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     *
+     * @param reader the reader containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+	public static CompilationUnit parse(final Reader reader) {
+		return simplifiedParse(COMPILATION_UNIT, provider(reader));
+	}
+
+	/**
+	 * Parses the Java code contained in code and returns a
+	 * {@link CompilationUnit} that represents it.
+	 *
+	 * @param code             Java source code
+	 * @return CompilationUnit representing the Java source code
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static CompilationUnit parse(String code) {
+		return simplifiedParse(COMPILATION_UNIT, provider(code));
+	}
+
+	/**
+	 * Parses the Java block contained in a {@link String} and returns a
+	 * {@link BlockStmt} that represents it.
+	 *
+	 * @param blockStatement {@link String} containing Java block code
+	 * @return BlockStmt representing the Java block
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static BlockStmt parseBlock(final String blockStatement) {
+		return simplifiedParse(BLOCK, provider(blockStatement));
+	}
+
+	/**
+	 * Parses the Java statement contained in a {@link String} and returns a
+	 * {@link Statement} that represents it.
+	 *
+	 * @param statement {@link String} containing Java statement code
+	 * @return Statement representing the Java statement
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static Statement parseStatement(final String statement) {
+		return simplifiedParse(STATEMENT, provider(statement));
+	}
+
+	private static <T extends Node> T simplifiedParse(ParseStart<T> context, Provider provider) {
+		ParseResult<T> result = new JavaParser(new ParserConfiguration()).parse(context, provider);
+		if (result.isSuccessful()) {
+			return result.getResult().get();
+		}
+		throw new ParseProblemException(result.getProblems());
+	}
+
+	/**
+	 * Parses the Java import contained in a {@link String} and returns a
+	 * {@link ImportDeclaration} that represents it.
+	 *
+	 * @param importDeclaration {@link String} containing Java import code
+	 * @return ImportDeclaration representing the Java import declaration
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static ImportDeclaration parseImport(final String importDeclaration) {
+		return simplifiedParse(IMPORT_DECLARATION, provider(importDeclaration));
+	}
+
+	/**
+	 * Parses the Java expression contained in a {@link String} and returns a
+	 * {@link Expression} that represents it.
+	 *
+	 * @param expression {@link String} containing Java expression
+	 * @return Expression representing the Java expression
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static Expression parseExpression(final String expression) {
+		return simplifiedParse(EXPRESSION, provider(expression));
+	}
+
+	/**
+	 * Parses the Java annotation contained in a {@link String} and returns a
+	 * {@link AnnotationExpr} that represents it.
+	 *
+	 * @param annotation {@link String} containing Java annotation
+	 * @return AnnotationExpr representing the Java annotation
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static AnnotationExpr parseAnnotation(final String annotation) {
+		return simplifiedParse(ANNOTATION, provider(annotation));
+	}
+
+	/**
+	 * Parses the Java annotation body declaration(e.g fields or methods) contained in a
+	 * {@link String} and returns a {@link BodyDeclaration} that represents it.
+	 *
+	 * @param body {@link String} containing Java body declaration
+	 * @return BodyDeclaration representing the Java annotation
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static BodyDeclaration<?> parseAnnotationBodyDeclaration(final String body) {
+		return simplifiedParse(ANNOTATION_BODY, provider(body));
+	}
+
+	/**
+	 * Parses a Java class body declaration(e.g fields or methods) and returns a
+	 * {@link BodyDeclaration} that represents it.
+	 *
+	 * @param body the body of a class
+	 * @return BodyDeclaration representing the Java class body
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static BodyDeclaration<?> parseClassBodyDeclaration(String body) {
+		return simplifiedParse(CLASS_BODY, provider(body));
+	}
+
+	/**
+	 * Parses a Java interface body declaration(e.g fields or methods) and returns a
+	 * {@link BodyDeclaration} that represents it.
+	 *
+	 * @param body the body of an interface
+	 * @return BodyDeclaration representing the Java interface body
+	 * @throws ParseProblemException if the source code has parser errors
+	 */
+	public static BodyDeclaration parseInterfaceBodyDeclaration(String body) {
+		return simplifiedParse(INTERFACE_BODY, provider(body));
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/PackageLocalClasses.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/PackageLocalClasses.java
new file mode 100644
index 0000000..90a33f5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/PackageLocalClasses.java
@@ -0,0 +1,4 @@
+package com.github.javaparser;
+
+class FooClass {}
+class BarClass {}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseProblemException.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseProblemException.java
new file mode 100644
index 0000000..f6a0298
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseProblemException.java
@@ -0,0 +1,40 @@
+package com.github.javaparser;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.Collections.singletonList;
+
+import static com.github.javaparser.utils.Utils.EOL;
+
+/**
+ * Thrown when parsing problems occur during parsing with the static methods on JavaParser.
+ */
+public class ParseProblemException extends RuntimeException {
+    /**
+     * The problems that were encountered during parsing
+     */
+    private final List<Problem> problems;
+
+    ParseProblemException(List<Problem> problems) {
+        super(createMessage(assertNotNull(problems)));
+        this.problems = problems;
+    }
+
+    ParseProblemException(Throwable throwable) {
+        this(singletonList(new Problem(throwable.getMessage(), Optional.empty(), Optional.of(throwable))));
+    }
+
+    private static String createMessage(List<Problem> problems) {
+        StringBuilder message = new StringBuilder();
+        for(Problem problem: problems){
+            message.append(problem.toString()).append(EOL);
+        }
+        return message.toString();
+    }
+
+    public List<Problem> getProblems() {
+        return problems;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseResult.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseResult.java
new file mode 100644
index 0000000..88e4005
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseResult.java
@@ -0,0 +1,88 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.comments.CommentsCollection;
+
+import java.util.List;
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+import static java.util.Collections.singletonList;
+
+import static com.github.javaparser.utils.Utils.EOL;
+
+/**
+ * The results given when parsing with an instance of JavaParser.
+ */
+public class ParseResult<T> {
+    private final Optional<T> result;
+    private final List<Problem> problems;
+    private final Optional<List<Token>> tokens;
+    private final Optional<CommentsCollection> commentsCollection;
+
+    /**
+     * General constructor.
+     * @param result the AST, or empty if it wasn't created.
+     * @param problems a list of encountered parsing problems.
+     * @param tokens the complete list of tokens that were parsed, or empty if parsing failed completely.
+     */
+    ParseResult(Optional<T> result, List<Problem> problems, Optional<List<Token>> tokens, Optional<CommentsCollection> commentsCollection) {
+        this.commentsCollection = assertNotNull(commentsCollection);
+        this.result = assertNotNull(result);
+        this.problems = assertNotNull(problems);
+        this.tokens = assertNotNull(tokens);
+    }
+
+    /**
+     * Used when parsing failed completely with an exception.
+     */
+    ParseResult(Throwable throwable) {
+        this(Optional.empty(), singletonList(new Problem(throwable.getMessage(), Optional.empty(), Optional.of(throwable))), Optional.empty(), Optional.empty());
+    }
+
+    /**
+     * @return if parsing was successful, meaning no errors of any kind were encountered.
+     */
+    public boolean isSuccessful() {
+        return problems.isEmpty() && result.isPresent();
+    }
+
+    /**
+     * @return the list of encountered parsing problems. Empty when no problems were encountered.
+     */
+    public List<Problem> getProblems() {
+        return problems;
+    }
+
+    /**
+     * @return the complete list of tokens that were parsed, or empty if parsing failed completely.
+     */
+    public Optional<List<Token>> getTokens() {
+        return tokens;
+    }
+
+    /**
+     * @return the complete collection of comments encountered while parsing.
+     */
+    public Optional<CommentsCollection> getCommentsCollection() {
+        return commentsCollection;
+    }
+
+    /**
+     * @return the AST of the parsed source code, or empty if parsing failed completely.
+     */
+    public Optional<T> getResult() {
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        if (isSuccessful()) {
+            return "Parsing successful";
+        }
+        StringBuilder message = new StringBuilder("Parsing failed:").append(EOL);
+        for (Problem problem : problems) {
+            message.append(problem.toString()).append(EOL);
+        }
+        return message.toString();
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseStart.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseStart.java
new file mode 100644
index 0000000..f94a662
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParseStart.java
@@ -0,0 +1,32 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+
+/**
+ * The start production for JavaParser.
+ * Tells JavaParser what piece of Java code it can expect.
+ * For example,
+ * COMPILATION_UNIT indicates a complete Java file,
+ * and CLASS_BODY would indicate the part of a class that is within { and }.
+ * @see JavaParser#parse(ParseStart, Provider)
+ */
+@FunctionalInterface
+public interface ParseStart<R> {
+	ParseStart<CompilationUnit> COMPILATION_UNIT = ASTParser::CompilationUnit;
+	ParseStart<BlockStmt> BLOCK = ASTParser::Block;
+	ParseStart<Statement> STATEMENT = ASTParser::BlockStatement;
+	ParseStart<ImportDeclaration> IMPORT_DECLARATION= ASTParser::ImportDeclaration;
+	ParseStart<Expression> EXPRESSION = ASTParser::Expression;
+	ParseStart<AnnotationExpr> ANNOTATION = ASTParser::Annotation;
+	ParseStart<BodyDeclaration<?>> ANNOTATION_BODY = ASTParser::AnnotationBodyDeclaration;
+	ParseStart<BodyDeclaration<?>> CLASS_BODY = p -> p.ClassOrInterfaceBodyDeclaration(false);
+	ParseStart<BodyDeclaration<?>> INTERFACE_BODY = p -> p.ClassOrInterfaceBodyDeclaration(true);
+
+	R parse(ASTParser parser) throws ParseException;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParserConfiguration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParserConfiguration.java
new file mode 100644
index 0000000..0b165b6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ParserConfiguration.java
@@ -0,0 +1,6 @@
+package com.github.javaparser;
+
+public class ParserConfiguration {
+    public boolean doNotAssignCommentsPrecedingEmptyLines = true;
+    public boolean doNotConsiderAnnotationsAsNodeStartForCodeAttribution = false;
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Position.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Position.java
new file mode 100644
index 0000000..3128244
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Position.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Node;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * A position in a source file. Lines and columns start counting at 1.
+ */
+public class Position implements Comparable<Position> {
+	public final int line;
+	public final int column;
+
+	public static final Position ABSOLUTE_START = new Position(Node.ABSOLUTE_BEGIN_LINE, -1);
+	public static final Position ABSOLUTE_END = new Position(Node.ABSOLUTE_END_LINE, -1);
+
+	/**
+	 * The first position in the file
+	 */
+	public static final Position HOME = new Position(1, 1);
+	public static final Position UNKNOWN = new Position(0, 0);
+
+	public Position(int line, int column) {
+		if (line < Node.ABSOLUTE_END_LINE) {
+			throw new IllegalArgumentException("Can't position at line " + line);
+		}
+		if (column < -1) {
+			throw new IllegalArgumentException("Can't position at column " + column);
+		}
+		this.line = line;
+		this.column = column;
+	}
+
+	/**
+	 * Convenient factory method.
+	 */
+	public static Position pos(int line, int column) {
+		return new Position(line, column);
+	}
+
+	public Position withColumn(int column) {
+		return new Position(this.line, column);
+	}
+
+	public Position withLine(int line) {
+		return new Position(line, this.column);
+	}
+
+	/**
+	 * Check if the position is usable. Does not know what it is pointing at, so it can't check if the position is after the end of the source.
+	 */
+	public boolean valid() {
+		return line > 0 && column > 0;
+	}
+
+	public boolean invalid() {
+		return !valid();
+	}
+
+	public Position orIfInvalid(Position anotherPosition) {
+		if (valid()) {
+			return this;
+		}
+		return anotherPosition;
+	}
+	
+	public boolean isAfter(Position position) {
+		assertNotNull(position);
+		if (position.line == Node.ABSOLUTE_BEGIN_LINE) return true;
+		if (line > position.line) {
+			return true;
+		} else if (line == position.line) {
+			return column > position.column;
+		}
+		return false;
+
+	}
+
+	public boolean isBefore(Position position) {
+		assertNotNull(position);
+		if (position.line == Node.ABSOLUTE_END_LINE) return true;
+		if (line < position.line) {
+			return true;
+		} else if (line == position.line) {
+			return column < position.column;
+		}
+		return false;
+	}
+
+	@Override
+	public int compareTo(Position o) {
+		assertNotNull(o);
+		if (isBefore(o)) {
+			return -1;
+		}
+		if (isAfter(o)) {
+			return 1;
+		}
+		return 0;
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (o == null || getClass() != o.getClass()) return false;
+
+		Position position = (Position) o;
+
+		return line == position.line && column == position.column;
+	}
+
+	@Override
+	public int hashCode() {
+		return 31 * line + column;
+	}
+
+	@Override
+	public String toString() {
+		return "(line " + line + ",col " + column + ")";
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Problem.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Problem.java
new file mode 100644
index 0000000..7e45cc9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Problem.java
@@ -0,0 +1,39 @@
+package com.github.javaparser;
+
+import java.util.Optional;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * A problem that was encountered during parsing.
+ */
+public class Problem {
+    private final String message;
+    private final Optional<Range> range;
+    private final Optional<Throwable> cause;
+
+    Problem(String message, Optional<Range> range, Optional<Throwable> cause) {
+        this.message = assertNotNull(message);
+        this.range = assertNotNull(range);
+        this.cause = assertNotNull(cause);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder(message);
+        range.ifPresent(r -> str.append(" ").append(r));
+        return str.toString();
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public Optional<Range> getRange() {
+        return range;
+    }
+
+    public Optional<Throwable> getCause() {
+        return cause;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Providers.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Providers.java
new file mode 100644
index 0000000..b5e731c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Providers.java
@@ -0,0 +1,61 @@
+package com.github.javaparser;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Factory for providers of source code for JavaParser.
+ * Providers that have no parameter for encoding but need it will use UTF-8.
+ */
+public final class Providers {
+	public static final Charset UTF8 = Charset.forName("utf-8");
+
+	private Providers() {
+	}
+
+	public static Provider provider(Reader reader) {
+		return new StreamProvider(assertNotNull(reader));
+	}
+
+	public static Provider provider(InputStream input, Charset encoding) {
+		assertNotNull(input);
+		assertNotNull(encoding);
+		try {
+			return new StreamProvider(input, encoding.name());
+		} catch (IOException e) {
+			// The only one that is thrown is UnsupportedCharacterEncodingException,
+			// and that's a fundamental problem, so runtime exception.
+			throw new RuntimeException(e);
+		}
+	}
+
+	public static Provider provider(InputStream input) {
+		return provider(input, UTF8);
+	}
+
+	public static Provider provider(File file, Charset encoding) throws FileNotFoundException {
+		return provider(new FileInputStream(assertNotNull(file)), assertNotNull(encoding));
+	}
+
+	public static Provider provider(File file) throws FileNotFoundException {
+		return provider(assertNotNull(file), UTF8);
+	}
+
+	public static Provider provider(Path path, Charset encoding) throws IOException {
+		return provider(Files.newInputStream(assertNotNull(path)), assertNotNull(encoding));
+	}
+
+	public static Provider provider(Path path) throws IOException {
+		return provider(assertNotNull(path), UTF8);
+	}
+
+	public static Provider provider(String source) {
+		return new StringProvider(assertNotNull(source));
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Range.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Range.java
new file mode 100644
index 0000000..68e364a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/Range.java
@@ -0,0 +1,89 @@
+package com.github.javaparser;
+
+import static com.github.javaparser.Position.pos;
+
+/**
+ * A range of characters in a source file, from "begin" to "end", including the characters at "begin" and "end".
+ */
+public class Range {
+    public static final Range UNKNOWN = range(Position.UNKNOWN, Position.UNKNOWN);
+
+    public final Position begin;
+    public final Position end;
+
+    public Range(Position begin, Position end) {
+        if (begin == null) {
+            throw new IllegalArgumentException("begin can't be null");
+        }
+        if (end == null) {
+            throw new IllegalArgumentException("end can't be null");
+        }
+        this.begin = begin;
+        this.end = end;
+    }
+
+    public static Range range(Position begin, Position end) {
+        return new Range(begin, end);
+    }
+
+    public static Range range(int beginLine, int beginColumn, int endLine, int endColumn) {
+        return new Range(pos(beginLine, beginColumn), pos(endLine, endColumn));
+    }
+
+    public Range withBeginColumn(int column) {
+        return range(begin.withColumn(column), end);
+    }
+
+    public Range withBeginLine(int line) {
+        return range(begin.withLine(line), end);
+    }
+
+    public Range withEndColumn(int column) {
+        return range(begin, end.withColumn(column));
+    }
+
+    public Range withEndLine(int line) {
+        return range(begin, end.withLine(line));
+    }
+
+    public Range withBegin(Position begin) {
+        return range(begin, this.end);
+    }
+
+    public Range withEnd(Position end) {
+        return range(this.begin, end);
+    }
+
+    public boolean contains(Range other) {
+        return begin.isBefore(other.begin) && end.isAfter(other.end);
+    }
+
+    public boolean isBefore(Position position) {
+        return end.isBefore(position);
+    }
+
+    public boolean isAfter(Position position) {
+        return begin.isAfter(position);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Range range = (Range) o;
+
+        return begin.equals(range.begin) && end.equals(range.end);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * begin.hashCode() + end.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return begin+"-"+end;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/AccessSpecifier.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/AccessSpecifier.java
new file mode 100644
index 0000000..f23f863
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/AccessSpecifier.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+/**
+ * Access specifier. Represents one of the possible levels of
+ * access permitted by the language.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public enum AccessSpecifier {
+
+    PUBLIC("public"),
+    PRIVATE("private"),
+    PROTECTED("protected"),
+    DEFAULT("");
+
+    private String codeRepresenation;
+
+    AccessSpecifier(String codeRepresentation) {
+        this.codeRepresenation = codeRepresentation;
+    }
+
+    public String getCodeRepresenation(){
+        return this.codeRepresenation;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ArrayBracketPair.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ArrayBracketPair.java
new file mode 100644
index 0000000..cca0b87
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ArrayBracketPair.java
@@ -0,0 +1,44 @@
+package com.github.javaparser.ast;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * In, for example, <code>int[] a[];</code> there are two ArrayBracketPair objects,
+ * one for the [] after int, one for the [] after a.
+ */
+public class ArrayBracketPair extends Node implements NodeWithAnnotations<ArrayBracketPair> {
+    private List<AnnotationExpr> annotations;
+
+    public ArrayBracketPair(Range range, List<AnnotationExpr> annotations) {
+        super(range);
+        setAnnotations(annotations);
+    }
+
+    @Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+    }
+
+    public List<AnnotationExpr> getAnnotations() {
+        annotations = ensureNotNull(annotations);
+        return annotations;
+    }
+
+    public ArrayBracketPair setAnnotations(List<AnnotationExpr> annotations) {
+        setAsParentNodeOf(annotations);
+        this.annotations = annotations;
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ArrayCreationLevel.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ArrayCreationLevel.java
new file mode 100644
index 0000000..2edc68c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ArrayCreationLevel.java
@@ -0,0 +1,56 @@
+package com.github.javaparser.ast;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * In <code>new int[1][2];</code> there are two ArrayCreationLevel objects,
+ * the first one contains the expression "1",
+ * the second the expression "2".
+ */
+public class ArrayCreationLevel extends Node implements NodeWithAnnotations<ArrayCreationLevel> {
+    private Expression dimension;
+    private List<AnnotationExpr> annotations;
+
+    public ArrayCreationLevel(Range range, Expression dimension, List<AnnotationExpr> annotations) {
+        super(range);
+        setDimension(dimension);
+        setAnnotations(annotations);
+    }
+
+    @Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    public void setDimension(Expression dimension) {
+        this.dimension = dimension;
+        setAsParentNodeOf(dimension);
+    }
+
+    public Expression getDimension() {
+        return dimension;
+    }
+
+    public List<AnnotationExpr> getAnnotations() {
+        annotations = ensureNotNull(annotations);
+        return annotations;
+    }
+
+    public ArrayCreationLevel setAnnotations(List<AnnotationExpr> annotations) {
+        setAsParentNodeOf(annotations);
+        this.annotations = annotations;
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java
new file mode 100644
index 0000000..2f30777
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/CompilationUnit.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import static com.github.javaparser.ast.expr.NameExpr.*;
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.utils.ClassUtils;
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.utils.ClassUtils;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * <p>
+ * This class represents the entire compilation unit. Each java file denotes a
+ * compilation unit.
+ * </p>
+ * The CompilationUnit is constructed following the syntax:<br>
+ * 
+ * <pre>
+ * {@code
+ * CompilationUnit ::=  ( }{@link PackageDeclaration}{@code )?
+ *                      ( }{@link ImportDeclaration}{@code )*
+ *                      ( }{@link TypeDeclaration}{@code )*
+ * }
+ * </pre>
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public final class CompilationUnit extends Node {
+
+    private PackageDeclaration pakage;
+
+    private List<ImportDeclaration> imports;
+
+    private List<TypeDeclaration<?>> types;
+
+    public CompilationUnit() {
+    }
+
+    public CompilationUnit(PackageDeclaration pakage, List<ImportDeclaration> imports, List<TypeDeclaration<?>> types) {
+        setPackage(pakage);
+        setImports(imports);
+        setTypes(types);
+    }
+
+    public CompilationUnit(Range range, PackageDeclaration pakage, List<ImportDeclaration> imports,
+                           List<TypeDeclaration<?>> types) {
+        super(range);
+        setPackage(pakage);
+        setImports(imports);
+        setTypes(types);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return a list containing all comments declared in this compilation unit.
+     * Including javadocs, line comments and block comments of all types,
+     * inner-classes and other members.<br>
+     * If there is no comment, <code>null</code> is returned.
+     * 
+     * @return list with all comments of this compilation unit or
+     *         <code>null</code>
+     * @see JavadocComment
+     * @see com.github.javaparser.ast.comments.LineComment
+     * @see com.github.javaparser.ast.comments.BlockComment
+     */
+    public List<Comment> getComments() {
+        return this.getAllContainedComments();
+    }
+
+    /**
+     * Retrieves the list of imports declared in this compilation unit or
+     * <code>null</code> if there is no import.
+     * 
+     * @return the list of imports or <code>null</code> if there is no import
+     */
+    public List<ImportDeclaration> getImports() {
+        imports = ensureNotNull(imports);
+        return imports;
+    }
+
+    /**
+     * Retrieves the package declaration of this compilation unit.<br>
+     * If this compilation unit has no package declaration (default package),
+     * <code>null</code> is returned.
+     * 
+     * @return the package declaration or <code>null</code>
+     */
+    public PackageDeclaration getPackage() {
+        return pakage;
+    }
+
+    /**
+     * Return the list of types declared in this compilation unit.<br>
+     * If there is no types declared, <code>null</code> is returned.
+     * 
+     * @return the list of types or <code>null</code> null if there is no type
+     * @see AnnotationDeclaration
+     * @see ClassOrInterfaceDeclaration
+     * @see EmptyTypeDeclaration
+     * @see EnumDeclaration
+     */
+    public List<TypeDeclaration<?>> getTypes() {
+        types = ensureNotNull(types);
+        return types;
+    }
+
+    /**
+     * Sets the list of comments of this compilation unit.
+     * 
+     * @param comments
+     *            the list of comments
+     */
+    public CompilationUnit setComments(List<Comment> comments) {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Sets the list of imports of this compilation unit. The list is initially
+     * <code>null</code>.
+     * 
+     * @param imports
+     *            the list of imports
+     */
+    public CompilationUnit setImports(List<ImportDeclaration> imports) {
+        this.imports = imports;
+        setAsParentNodeOf(this.imports);
+        return this;
+    }
+
+    /**
+     * Sets or clear the package declarations of this compilation unit.
+     * 
+     * @param pakage
+     *            the pakage declaration to set or <code>null</code> to default
+     *            package
+     */
+    public CompilationUnit setPackage(PackageDeclaration pakage) {
+        this.pakage = pakage;
+        setAsParentNodeOf(this.pakage);
+        return this;
+    }
+
+    /**
+     * Sets the list of types declared in this compilation unit.
+     * 
+     * @param types
+     *            the lis of types
+     */
+    public CompilationUnit setTypes(List<TypeDeclaration<?>> types) {
+        this.types = types;
+        setAsParentNodeOf(this.types);
+        return this;
+    }
+
+    /**
+     * sets the package declaration of this compilation unit
+     * 
+     * @param name the name of the package
+     * @return this, the {@link CompilationUnit}
+     */
+    public CompilationUnit setPackageName(String name) {
+        setPackage(new PackageDeclaration(name(name)));
+        return this;
+    }
+
+    /**
+     * Add an import to the list of {@link ImportDeclaration} of this compilation unit<br>
+     * shorthand for {@link #addImport(String, boolean, boolean)} with name,false,false
+     * 
+     * @param name the import name
+     * @return this, the {@link CompilationUnit}
+     */
+    public CompilationUnit addImport(String name) {
+        return addImport(name, false, false);
+    }
+
+    /**
+     * Add an import to the list of {@link ImportDeclaration} of this compilation unit<br>
+     * shorthand for {@link #addImport(String)} with clazz.getName()
+     * 
+     * @param clazz the class to import
+     * @return this, the {@link CompilationUnit}
+     */
+    public CompilationUnit addImport(Class<?> clazz) {
+        if (ClassUtils.isPrimitiveOrWrapper(clazz) || clazz.getName().startsWith("java.lang"))
+            return this;
+        else if (clazz.isArray() && !ClassUtils.isPrimitiveOrWrapper(clazz.getComponentType())
+                && !clazz.getComponentType().getName().startsWith("java.lang"))
+            return addImport(clazz.getComponentType().getName());
+        return addImport(clazz.getName());
+    }
+
+    /**
+     * Add an import to the list of {@link ImportDeclaration} of this compilation unit<br>
+     * <b>This method check if no import with the same name is already in the list</b>
+     * 
+     * @param name the import name
+     * @param isStatic      is it an "import static"
+     * @param isAsterisk does the import end with ".*"
+     * @return this, the {@link CompilationUnit}
+     */
+    public CompilationUnit addImport(String name, boolean isStatic, boolean isAsterisk) {
+        if (getImports().stream().anyMatch(i -> i.getName().toString().equals(name)))
+            return this;
+        else {
+            ImportDeclaration importDeclaration = new ImportDeclaration(name(name), isStatic,
+                    isAsterisk);
+            getImports().add(importDeclaration);
+            importDeclaration.setParentNode(this);
+            return this;
+        }
+    }
+
+    /**
+     * Add a public class to the types of this compilation unit
+     * 
+     * @param name the class name
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addClass(String name) {
+        return addClass(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add a class to the types of this compilation unit
+     * 
+     * @param name the class name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addClass(String name, Modifier... modifiers) {
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = new ClassOrInterfaceDeclaration(
+                Arrays.stream(modifiers)
+                        .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))),
+                false, name);
+        getTypes().add(classOrInterfaceDeclaration);
+        classOrInterfaceDeclaration.setParentNode(this);
+        return classOrInterfaceDeclaration;
+    }
+
+    /**
+     * Add a public interface class to the types of this compilation unit
+     * 
+     * @param name the interface name
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addInterface(String name) {
+        return addInterface(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add an interface to the types of this compilation unit
+     * 
+     * @param name the interface name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public ClassOrInterfaceDeclaration addInterface(String name, Modifier... modifiers) {
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = new ClassOrInterfaceDeclaration(
+                Arrays.stream(modifiers)
+                        .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))),
+                true, name);
+        getTypes().add(classOrInterfaceDeclaration);
+        classOrInterfaceDeclaration.setParentNode(this);
+        return classOrInterfaceDeclaration;
+    }
+
+    /**
+     * Add a public enum to the types of this compilation unit
+     * 
+     * @param name the enum name
+     * @return the newly created class
+     */
+    public EnumDeclaration addEnum(String name) {
+        return addEnum(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add an enum to the types of this compilation unit
+     * 
+     * @param name the enum name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public EnumDeclaration addEnum(String name, Modifier... modifiers) {
+        EnumDeclaration enumDeclaration = new EnumDeclaration(Arrays.stream(modifiers)
+                .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), name);
+        getTypes().add(enumDeclaration);
+        enumDeclaration.setParentNode(this);
+        return enumDeclaration;
+    }
+
+    /**
+     * Add a public annotation declaration to the types of this compilation unit
+     * 
+     * @param name the annotation name
+     * @return the newly created class
+     */
+    public AnnotationDeclaration addAnnotationDeclaration(String name) {
+        return addAnnotationDeclaration(name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add an annotation declaration to the types of this compilation unit
+     * 
+     * @param name the annotation name
+     * @param modifiers the modifiers (like Modifier.PUBLIC)
+     * @return the newly created class
+     */
+    public AnnotationDeclaration addAnnotationDeclaration(String name, Modifier... modifiers) {
+        AnnotationDeclaration annotationDeclaration = new AnnotationDeclaration(Arrays.stream(modifiers)
+                .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))), name);
+        getTypes().add(annotationDeclaration);
+        annotationDeclaration.setParentNode(this);
+        return annotationDeclaration;
+    }
+
+    /**
+     * Try to get a class by its name
+     * 
+     * @param className the class name (case-sensitive)
+     * @return null if not found, the class otherwise
+     */
+    public ClassOrInterfaceDeclaration getClassByName(String className) {
+        return (ClassOrInterfaceDeclaration) getTypes().stream().filter(type -> type.getName().equals(className)
+                && type instanceof ClassOrInterfaceDeclaration && !((ClassOrInterfaceDeclaration) type).isInterface())
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Try to get an interface by its name
+     * 
+     * @param interfaceName the interface name (case-sensitive)
+     * @return null if not found, the interface otherwise
+     */
+    public ClassOrInterfaceDeclaration getInterfaceByName(String interfaceName) {
+        return (ClassOrInterfaceDeclaration) getTypes().stream().filter(type -> type.getName().equals(interfaceName)
+                && type instanceof ClassOrInterfaceDeclaration && ((ClassOrInterfaceDeclaration) type).isInterface())
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Try to get an enum by its name
+     * 
+     * @param enumName the enum name (case-sensitive)
+     * @return null if not found, the enum otherwise
+     */
+    public EnumDeclaration getEnumByName(String enumName) {
+        return (EnumDeclaration) getTypes().stream().filter(type -> type.getName().equals(enumName)
+                && type instanceof EnumDeclaration)
+                .findFirst().orElse(null);
+    }
+
+    /**
+     * Try to get an annotation by its name
+     * 
+     * @param annotationName the annotation name (case-sensitive)
+     * @return null if not found, the annotation otherwise
+     */
+    public AnnotationDeclaration getAnnotationDeclarationByName(String annotationName) {
+        return (AnnotationDeclaration) getTypes().stream().filter(type -> type.getName().equals(annotationName)
+                && type instanceof AnnotationDeclaration)
+                .findFirst().orElse(null);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Example.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Example.java
new file mode 100644
index 0000000..70cf2cd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Example.java
@@ -0,0 +1,31 @@
+package com.github.javaparser.ast;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Created by federico on 07/01/16.
+ */
+public class Example {
+
+    public static void main(String[] args) throws UnsupportedEncodingException, ParseException {
+        String code = "interface A {\n" +
+                "    default Comparator<T> thenComparing(Comparator<? super T> other) {\n" +
+                "        Objects.requireNonNull(other);\n" +
+                "        return (Comparator<T> & Serializable) (c1, c2) -> { // this is the defaulting line\n" +
+                "            int res = compare(c1, c2);\n" +
+                "            return (res != 0) ? res : other.compare(c1, c2);\n" +
+                "        };\n" +
+                "    }\n" +
+                "}";
+        InputStream stream = new ByteArrayInputStream(code.getBytes("UTF-8"));
+        CompilationUnit cu = JavaParser.parse(stream);
+
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ImportDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ImportDeclaration.java
new file mode 100644
index 0000000..863c8d3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/ImportDeclaration.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * <p>
+ * This class represents a import declaration or an empty import declaration. Imports are optional for the
+ * {@link CompilationUnit}.
+ * </p>
+ * The ImportDeclaration is constructed following the syntax:<br>
+ * <pre>
+ * {@code
+ * ImportDeclaration ::= "import" ( "static" )? }{@link NameExpr}{@code ( "." "*" )? ";"
+ * }
+ * </pre>
+ * An enmpty import declaration is simply a semicolon among the import declarations.
+ * @author Julio Vilmar Gesser
+ */
+public final class ImportDeclaration extends Node {
+
+    private NameExpr name;
+    private boolean static_;
+    private boolean asterisk;
+    private boolean isEmptyImportDeclaration;
+
+    private ImportDeclaration() {
+        this.isEmptyImportDeclaration = true;
+        static_ = false;
+        asterisk = false;
+    }
+
+    private ImportDeclaration(Range range) {
+        super(range);
+        this.isEmptyImportDeclaration = true;
+        static_ = false;
+        asterisk = false;
+    }
+
+    /**
+     * Create an empty import declaration without specifying its position.
+     */
+    public static ImportDeclaration createEmptyDeclaration(){
+        return new ImportDeclaration();
+    }
+
+    /**
+     * Create an empty import declaration specifying its position.
+     */
+    public static ImportDeclaration createEmptyDeclaration(Range range){
+        return new ImportDeclaration(range);
+    }
+
+    public ImportDeclaration(NameExpr name, boolean isStatic, boolean isAsterisk) {
+        setAsterisk(isAsterisk);
+        setName(name);
+        setStatic(isStatic);
+        this.isEmptyImportDeclaration = false;
+    }
+
+    public ImportDeclaration(Range range, NameExpr name, boolean isStatic, boolean isAsterisk) {
+        super(range);
+        setAsterisk(isAsterisk);
+        setName(name);
+        setStatic(isStatic);
+        this.isEmptyImportDeclaration = false;
+    }
+
+    /**
+     * Is this an empty import declaration or a normal import declaration?
+     */
+    public boolean isEmptyImportDeclaration(){
+        return this.isEmptyImportDeclaration;
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Retrieves the name of the import.
+     * 
+     * @return the name of the import
+     * @throws UnsupportedOperationException when invoked on an empty import declaration
+     */
+    public NameExpr getName() {
+        if (isEmptyImportDeclaration) {
+            throw new UnsupportedOperationException("Empty import declarations have no name");
+        }
+        return name;
+    }
+
+    /**
+     * Return if the import ends with "*".
+     * 
+     * @return <code>true</code> if the import ends with "*", <code>false</code>
+     *         otherwise
+     */
+    public boolean isAsterisk() {
+        return asterisk;
+    }
+
+    /**
+     * Return if the import is static.
+     * 
+     * @return <code>true</code> if the import is static, <code>false</code>
+     *         otherwise
+     */
+    public boolean isStatic() {
+        return static_;
+    }
+
+    /**
+     * Sets if this import is asterisk.
+     * 
+     * @param asterisk
+     *            <code>true</code> if this import is asterisk
+     * @throws UnsupportedOperationException when setting true on an empty import declaration
+     */
+    public ImportDeclaration setAsterisk(boolean asterisk) {
+        if (isEmptyImportDeclaration && asterisk) {
+            throw new UnsupportedOperationException("Empty import cannot have asterisk");
+        }
+        this.asterisk = asterisk;
+        return this;
+    }
+
+    /**
+     * Sets the name this import.
+     * 
+     * @param name
+     *            the name to set
+     * @throws UnsupportedOperationException when invoked on an empty import declaration
+     */
+    public ImportDeclaration setName(NameExpr name) {
+        if (isEmptyImportDeclaration) {
+            throw new UnsupportedOperationException("Empty import cannot have name");
+        }
+        this.name = name;
+        setAsParentNodeOf(this.name);
+        return this;
+    }
+
+    /**
+     * Sets if this import is static.
+     * 
+     * @param static_
+     *            <code>true</code> if this import is static
+     * @throws UnsupportedOperationException when setting true on an empty import declaration
+     */
+    public ImportDeclaration setStatic(boolean static_) {
+        if (isEmptyImportDeclaration && static_) {
+            throw new UnsupportedOperationException("Empty import cannot be static");
+        }
+        this.static_ = static_;
+        return this;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Modifier.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Modifier.java
new file mode 100644
index 0000000..3f5a50b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Modifier.java
@@ -0,0 +1,46 @@
+package com.github.javaparser.ast;
+
+import java.util.EnumSet;
+
+public enum Modifier {
+	PUBLIC("public"),
+    PROTECTED("protected"),
+	PRIVATE("private"),
+    ABSTRACT("abstract"),
+	STATIC("static"),
+	FINAL("final"),
+    TRANSIENT("transient"), 
+    VOLATILE("volatile"),
+	SYNCHRONIZED("synchronized"),
+	NATIVE("native"),
+	STRICTFP("strictfp");
+
+    String lib;
+
+    private Modifier(String lib) {
+        this.lib = lib;
+    }
+
+    /**
+     * @return the lib
+     */
+    public String getLib() {
+        return lib;
+    }
+
+    public EnumSet<Modifier> toEnumSet() {
+        return EnumSet.of(this);
+    }
+
+    public static AccessSpecifier getAccessSpecifier(EnumSet<Modifier> modifiers) {
+        if (modifiers.contains(Modifier.PUBLIC)) {
+            return AccessSpecifier.PUBLIC;
+        } else if (modifiers.contains(Modifier.PROTECTED)) {
+            return AccessSpecifier.PROTECTED;
+        } else if (modifiers.contains(Modifier.PRIVATE)) {
+            return AccessSpecifier.PRIVATE;
+        } else {
+            return AccessSpecifier.DEFAULT;
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Node.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Node.java
new file mode 100644
index 0000000..f2bae43
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/Node.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.Position;
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.visitor.*;
+
+import java.util.*;
+
+/**
+ * Abstract class for all nodes of the AST.
+ *
+ * Each Node can have one associated comment which describe it and
+ * a number of "orphan comments" which it contains but are not specifically
+ * associated to any element.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Node implements Cloneable {
+    /**
+     * This can be used to sort nodes on position.
+     */
+    public static Comparator<Node> NODE_BY_BEGIN_POSITION = (a, b) -> a.getBegin().compareTo(b.getBegin());
+
+    private Range range;
+
+    private Node parentNode;
+
+    private List<Node> childrenNodes = new LinkedList<>();
+    private List<Comment> orphanComments = new LinkedList<>();
+
+    private IdentityHashMap<UserDataKey<?>, Object> userData = null;
+
+    private Comment comment;
+
+    public Node() {
+        this(Range.UNKNOWN);
+    }
+
+    public Node(Range range) {
+        this.range = range;
+    }
+
+    /**
+     * Accept method for visitor support.
+     * 
+     * @param <R>
+     *            the type the return value of the visitor
+     * @param <A>
+     *            the type the argument passed to the visitor
+     * @param v
+     *            the visitor implementation
+     * @param arg
+     *            the argument passed to the visitor
+     * @return the result of the visit
+     */
+    public abstract <R, A> R accept(GenericVisitor<R, A> v, A arg);
+
+    /**
+     * Accept method for visitor support.
+     * 
+     * @param <A>
+     *            the type the argument passed for the visitor
+     * @param v
+     *            the visitor implementation
+     * @param arg
+     *            any value relevant for the visitor
+     */
+    public abstract <A> void accept(VoidVisitor<A> v, A arg);
+
+    /**
+     * This is a comment associated with this node.
+     *
+     * @return comment property
+     */
+    public final Comment getComment() {
+        return comment;
+    }
+
+    /**
+     * The begin position of this node in the source file.
+     */
+    public Position getBegin() {
+        return range.begin;
+    }
+
+    /**
+     * The end position of this node in the source file.
+     */
+    public Position getEnd() {
+        return range.end;
+    }
+
+    /**
+     * Sets the begin position of this node in the source file.
+     */
+    public Node setBegin(Position begin) {
+        range = range.withBegin(begin);
+        return this;
+    }
+
+    /**
+     * Sets the end position of this node in the source file.
+     */
+    public Node setEnd(Position end) {
+        range = range.withEnd(end);
+        return this;
+    }
+
+    /**
+     * @return the range of characters in the source code that this node covers.
+     */
+    public Range getRange() {
+        return range;
+    }
+
+    /**
+     * @param range the range of characters in the source code that this node covers.
+     */
+    public Node setRange(Range range) {
+        this.range = range;
+        return this;
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    public final Node setComment(final Comment comment) {
+        if (comment != null && (this instanceof Comment)) {
+            throw new RuntimeException("A comment can not be commented");
+        }
+        if (this.comment != null) {
+            this.comment.setCommentedNode(null);
+        }
+        this.comment = comment;
+        if (comment != null) {
+            this.comment.setCommentedNode(this);
+        }
+        return this;
+    }
+
+
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    public final Node setLineComment(String comment) {
+        return setComment(new LineComment(comment));
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    public final Node setBlockComment(String comment) {
+        return setComment(new BlockComment(comment));
+    }
+
+    /**
+     * Return the String representation of this node.
+     * 
+     * @return the String representation of this node
+     */
+    @Override
+    public final String toString() {
+        final DumpVisitor visitor = new DumpVisitor();
+        accept(visitor, null);
+        return visitor.getSource();
+    }
+
+    public final String toStringWithoutComments() {
+        final DumpVisitor visitor = new DumpVisitor(false);
+        accept(visitor, null);
+        return visitor.getSource();
+    }
+
+    @Override
+    public final int hashCode() {
+        return toString().hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null || !(obj instanceof Node)) {
+            return false;
+        }
+        return EqualsVisitor.equals(this, (Node) obj);
+    }
+
+    @Override
+    public Node clone() {
+        return this.accept(new CloneVisitor(), null);
+    }
+
+    public Node getParentNode() {
+        return parentNode;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getParentNodeOfType(Class<T> classType) {
+        Node parent = parentNode;
+        while (parent != null) {
+            if (classType.isAssignableFrom(parent.getClass()))
+                return (T) parent;
+            parent = parent.parentNode;
+        }
+        return null;
+    }
+
+    public List<Node> getChildrenNodes() {
+        return childrenNodes;
+    }
+
+    public boolean contains(Node other) {
+        return range.contains(other.range);
+    }
+
+    public void addOrphanComment(Comment comment) {
+        orphanComments.add(comment);
+        comment.setParentNode(this);
+    }
+
+    /**
+     * This is a list of Comment which are inside the node and are not associated
+     * with any meaningful AST Node.
+     *
+     * For example, comments at the end of methods (immediately before the parenthesis)
+     * or at the end of CompilationUnit are orphan comments.
+     *
+     * When more than one comment preceeds a statement, the one immediately preceding it
+     * it is associated with the statements, while the others are orphans.
+     * 
+     * @return all comments that cannot be attributed to a concept
+     */
+    public List<Comment> getOrphanComments() {
+        return orphanComments;
+    }
+
+    /**
+     * This is the list of Comment which are contained in the Node either because
+     * they are properly associated to one of its children or because they are floating
+     * around inside the Node
+     * 
+     * @return all Comments within the node as a list
+     */
+    public List<Comment> getAllContainedComments() {
+        List<Comment> comments = new LinkedList<>();
+        comments.addAll(getOrphanComments());
+
+        for (Node child : getChildrenNodes()) {
+            if (child.getComment() != null) {
+                comments.add(child.getComment());
+            }
+            comments.addAll(child.getAllContainedComments());
+        }
+
+        return comments;
+    }
+
+    /**
+     * Assign a new parent to this node, removing it
+     * from the list of children of the previous parent, if any.
+     *
+     * @param parentNode node to be set as parent
+     */
+    public void setParentNode(Node parentNode) {
+        // remove from old parent, if any
+        if (this.parentNode != null) {
+            this.parentNode.childrenNodes.remove(this);
+        }
+        this.parentNode = parentNode;
+        // add to new parent, if any
+        if (this.parentNode != null) {
+            this.parentNode.childrenNodes.add(this);
+        }
+    }
+
+    protected void setAsParentNodeOf(List<? extends Node> childNodes) {
+        if (childNodes != null) {
+            for (Node current : childNodes) {
+                current.setParentNode(this);
+            }
+        }
+    }
+
+    protected void setAsParentNodeOf(Node childNode) {
+        if (childNode != null) {
+            childNode.setParentNode(this);
+        }
+    }
+
+    public static final int ABSOLUTE_BEGIN_LINE = -1;
+    public static final int ABSOLUTE_END_LINE = -2;
+
+    public boolean isPositionedAfter(Position position) {
+        return range.isAfter(position);
+    }
+
+    public boolean isPositionedBefore(Position position) {
+        return range.isBefore(position);
+    }
+
+    public boolean hasComment() {
+        return comment != null;
+    }
+
+    public void tryAddImportToParentCompilationUnit(Class<?> clazz) {
+        CompilationUnit parentNode = getParentNodeOfType(CompilationUnit.class);
+        if (parentNode != null) {
+            parentNode.addImport(clazz);
+        }
+    }
+
+    /**
+     * Recursively finds all nodes of a certain type.
+     *
+     * @param clazz the type of node to find.
+     */
+    public <N extends Node> List<N> getNodesByType(Class<N> clazz) {
+        List<N> nodes = new ArrayList<>();
+        for (Node child : getChildrenNodes()) {
+            if (clazz.isInstance(child)) {
+                nodes.add(clazz.cast(child));
+            }
+            nodes.addAll(child.getNodesByType(clazz));
+        }
+        return nodes;
+    }
+
+    /**
+     * Gets user data for this component using the given key.
+     *
+     * @param <M>
+     *            The type of the user data.
+     *
+     * @param key
+     *            The key for the data
+     * @return The user data or null of no user data was found for the given key
+     * @see UserDataKey
+     */
+    public <M> M getUserData(final UserDataKey<M> key) {
+        if (userData == null) {
+            return null;
+        }
+        return (M) userData.get(key);
+    }
+
+    /**
+     * Sets user data for this component using the given key.
+     * For information on creating UserDataKey, see {@link UserDataKey}.
+     *
+     * @param <M>
+     *            The type of user data
+     *
+     * @param key
+     *            The singleton key for the user data
+     * @param object
+     *            The user data object
+     * @throws IllegalArgumentException
+     * @see UserDataKey
+     */
+    public <M> void setUserData(UserDataKey<M> key, M object) {
+        if (userData == null) {
+            userData = new IdentityHashMap<>();
+        }
+        userData.put(key, object);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/PackageDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/PackageDeclaration.java
new file mode 100644
index 0000000..4252ad4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/PackageDeclaration.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.utils.Utils;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * <p>
+ * This class represents the package declaration. The package declaration is
+ * optional for the {@link CompilationUnit}.
+ * </p>
+ * The PackageDeclaration is constructed following the syntax:<br>
+ * <pre>
+ * {@code
+ * PackageDeclaration ::= ( }{@link AnnotationExpr}{@code )* "package" }{@link NameExpr}{@code ) ";"
+ * }
+ * </pre>
+ * @author Julio Vilmar Gesser
+ */
+public final class PackageDeclaration extends Node implements NodeWithAnnotations<PackageDeclaration> {
+
+    private List<AnnotationExpr> annotations;
+
+    private NameExpr name;
+
+    public PackageDeclaration() {
+    }
+
+    public PackageDeclaration(NameExpr name) {
+        setName(name);
+    }
+
+    public PackageDeclaration(List<AnnotationExpr> annotations, NameExpr name) {
+        setAnnotations(annotations);
+        setName(name);
+    }
+
+    public PackageDeclaration(Range range, List<AnnotationExpr> annotations, NameExpr name) {
+        super(range);
+        setAnnotations(annotations);
+        setName(name);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Retrieves the list of annotations declared before the package
+     * declaration. Return <code>null</code> if there are no annotations.
+     * 
+     * @return list of annotations or <code>null</code>
+     */
+    public List<AnnotationExpr> getAnnotations() {
+        annotations = Utils.ensureNotNull(annotations);
+        return annotations;
+    }
+
+    /**
+     * Return the name expression of the package.
+     *
+     * @return the name of the package
+     */
+    public NameExpr getName() {
+        return name;
+    }
+
+    /**
+     * Get full package name.
+     */
+    public String getPackageName() {
+        return name.toString();
+    }
+
+    /**
+     * @param annotations
+     *            the annotations to set
+     */
+    public PackageDeclaration setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+        setAsParentNodeOf(this.annotations);
+        return this;
+    }
+
+    /**
+     * Sets the name of this package declaration.
+     * 
+     * @param name
+     *            the name to set
+     */
+    public PackageDeclaration setName(NameExpr name) {
+        this.name = name;
+        setAsParentNodeOf(this.name);
+        return this;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/UserDataKey.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/UserDataKey.java
new file mode 100644
index 0000000..4d7caa2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/UserDataKey.java
@@ -0,0 +1,39 @@
+package com.github.javaparser.ast;
+
+/**
+ * A key to a piece of user data associated with a {@link Node} at runtime.
+ * The key contains type information that can be used to check the
+ * type of any user data value for the key when the value is set. UserDataKey is abstract in order to
+ * force the creation of a subtype. That subtype is used to test for identity when looking for the
+ * user data because actual object identity would suffer from problems under serialization.
+ * So, the correct way to declare a UserDataKey is like this:
+ *
+ * <pre>
+ * <code>
+ * public static final UserDataKey&lt;Role&gt; ROLE = new UserDataKey&lt;Role&gt;() { };
+ * </code>
+ * </pre>
+ *
+ * This code was taken from the <a href="http://wicket.apache.org/">Wicket project</a>.
+ *
+ * @param <T>
+ *            The type of the object which is stored
+ *
+ * @see Node#getUserData(UserDataKey)
+ */
+public abstract class UserDataKey<T> {
+    @Override
+    public int hashCode()
+    {
+        return getClass().hashCode();
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj)
+    {
+        return obj != null && getClass().equals(obj.getClass());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/AnnotationDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/AnnotationDeclaration.java
new file mode 100644
index 0000000..74d84e8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/AnnotationDeclaration.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import java.util.List;
+
+import java.util.EnumSet;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AnnotationDeclaration extends TypeDeclaration<AnnotationDeclaration> {
+
+    public AnnotationDeclaration() {
+    }
+
+    public AnnotationDeclaration(EnumSet<Modifier> modifiers, String name) {
+        super(modifiers, name);
+    }
+
+    public AnnotationDeclaration(EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, String name,
+                                 List<BodyDeclaration<?>> members) {
+        super(annotations, modifiers, name, members);
+    }
+
+    public AnnotationDeclaration(Range range, EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, String name,
+                                 List<BodyDeclaration<?>> members) {
+        super(range, annotations, modifiers, name, members);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java
new file mode 100644
index 0000000..66b9dc3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.EnumSet;
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AnnotationMemberDeclaration extends BodyDeclaration<AnnotationMemberDeclaration>
+        implements NodeWithJavaDoc<AnnotationMemberDeclaration>, NodeWithName<AnnotationMemberDeclaration>,
+        NodeWithType<AnnotationMemberDeclaration>, NodeWithModifiers<AnnotationMemberDeclaration> {
+
+    private EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+
+    private Type type;
+
+    private String name;
+
+    private Expression defaultValue;
+
+    public AnnotationMemberDeclaration() {
+    }
+
+    public AnnotationMemberDeclaration(EnumSet<Modifier> modifiers, Type type, String name, Expression defaultValue) {
+        setModifiers(modifiers);
+        setType(type);
+        setName(name);
+        setDefaultValue(defaultValue);
+    }
+
+    public AnnotationMemberDeclaration(EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, Type type, String name,
+                                       Expression defaultValue) {
+        super(annotations);
+        setModifiers(modifiers);
+        setType(type);
+        setName(name);
+        setDefaultValue(defaultValue);
+    }
+
+    public AnnotationMemberDeclaration(Range range, EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, Type type,
+                                       String name, Expression defaultValue) {
+        super(range, annotations);
+        setModifiers(modifiers);
+        setType(type);
+        setName(name);
+        setDefaultValue(defaultValue);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getDefaultValue() {
+        return defaultValue;
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     * 
+     * @see Modifier
+     * @return modifiers
+     */
+    @Override
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public Type getType() {
+        return type;
+    }
+
+    public AnnotationMemberDeclaration setDefaultValue(Expression defaultValue) {
+        this.defaultValue = defaultValue;
+        setAsParentNodeOf(defaultValue);
+        return this;
+    }
+
+    @Override
+    public AnnotationMemberDeclaration setModifiers(EnumSet<Modifier> modifiers) {
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Override
+    public AnnotationMemberDeclaration setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    @Override
+    public AnnotationMemberDeclaration setType(Type type) {
+        this.type = type;
+        setAsParentNodeOf(type);
+        return this;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        if (getComment() instanceof JavadocComment) {
+            return (JavadocComment) getComment();
+        }
+        return null;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/BodyDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/BodyDeclaration.java
new file mode 100644
index 0000000..9055d96
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/BodyDeclaration.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.utils.Utils;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class BodyDeclaration<T> extends Node implements NodeWithAnnotations<T> {
+
+    private List<AnnotationExpr> annotations;
+
+    public BodyDeclaration() {
+    }
+
+    public BodyDeclaration(List<AnnotationExpr> annotations) {
+    	setAnnotations(annotations);
+    }
+
+    public BodyDeclaration(Range range, List<AnnotationExpr> annotations) {
+        super(range);
+    	setAnnotations(annotations);
+    }
+
+    @Override
+    public final List<AnnotationExpr> getAnnotations() {
+        annotations = Utils.ensureNotNull(annotations);
+        return annotations;
+    }
+
+    /**
+     *
+     * @param annotations a null value is currently treated as an empty list. This behavior could change
+     *                    in the future, so please avoid passing null
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public final T setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+		setAsParentNodeOf(this.annotations);
+        return (T) this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java
new file mode 100644
index 0000000..4120d4a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithExtends;
+import com.github.javaparser.ast.nodeTypes.NodeWithImplements;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassOrInterfaceDeclaration extends TypeDeclaration<ClassOrInterfaceDeclaration>
+        implements NodeWithImplements<ClassOrInterfaceDeclaration>, NodeWithExtends<ClassOrInterfaceDeclaration> {
+
+    private boolean interface_;
+
+    private List<TypeParameter> typeParameters;
+
+    // Can contain more than one item if this is an interface
+    private List<ClassOrInterfaceType> extendsList;
+
+    private List<ClassOrInterfaceType> implementsList;
+
+    public ClassOrInterfaceDeclaration() {
+    }
+
+    public ClassOrInterfaceDeclaration(final EnumSet<Modifier> modifiers, final boolean isInterface,
+                                       final String name) {
+        super(modifiers, name);
+        setInterface(isInterface);
+    }
+
+    public ClassOrInterfaceDeclaration(final EnumSet<Modifier> modifiers,
+                                       final List<AnnotationExpr> annotations, final boolean isInterface,
+                                       final String name,
+                                       final List<TypeParameter> typeParameters,
+                                       final List<ClassOrInterfaceType> extendsList,
+                                       final List<ClassOrInterfaceType> implementsList,
+                                       final List<BodyDeclaration<?>> members) {
+        super(annotations, modifiers, name, members);
+        setInterface(isInterface);
+        setTypeParameters(typeParameters);
+        setExtends(extendsList);
+        setImplements(implementsList);
+    }
+
+    public ClassOrInterfaceDeclaration(Range range, final EnumSet<Modifier> modifiers,
+                                       final List<AnnotationExpr> annotations, final boolean isInterface,
+                                       final String name,
+                                       final List<TypeParameter> typeParameters,
+                                       final List<ClassOrInterfaceType> extendsList,
+                                       final List<ClassOrInterfaceType> implementsList,
+                                       final List<BodyDeclaration<?>> members) {
+        super(range, annotations, modifiers, name, members);
+        setInterface(isInterface);
+        setTypeParameters(typeParameters);
+        setExtends(extendsList);
+        setImplements(implementsList);
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<ClassOrInterfaceType> getExtends() {
+        extendsList = ensureNotNull(extendsList);
+        return extendsList;
+    }
+
+    @Override
+    public List<ClassOrInterfaceType> getImplements() {
+        implementsList = ensureNotNull(implementsList);
+        return implementsList;
+    }
+
+    public List<TypeParameter> getTypeParameters() {
+        typeParameters = ensureNotNull(typeParameters);
+        return typeParameters;
+    }
+
+    public boolean isInterface() {
+        return interface_;
+    }
+
+    /**
+     * 
+     * @param extendsList a null value is currently treated as an empty list. This behavior could change
+     *            in the future, so please avoid passing null
+     * @return
+     */
+    @Override
+    public ClassOrInterfaceDeclaration setExtends(final List<ClassOrInterfaceType> extendsList) {
+        this.extendsList = extendsList;
+        setAsParentNodeOf(this.extendsList);
+        return this;
+    }
+
+    /**
+     * 
+     * @param implementsList a null value is currently treated as an empty list. This behavior could change
+     *            in the future, so please avoid passing null
+     */
+    @Override
+    public ClassOrInterfaceDeclaration setImplements(final List<ClassOrInterfaceType> implementsList) {
+        this.implementsList = implementsList;
+        setAsParentNodeOf(this.implementsList);
+        return this;
+    }
+
+    public ClassOrInterfaceDeclaration setInterface(final boolean interface_) {
+        this.interface_ = interface_;
+        return this;
+    }
+
+    /**
+     *
+     * @param typeParameters a null value is currently treated as an empty list. This behavior could change
+     *            in the future, so please avoid passing null
+     */
+    public ClassOrInterfaceDeclaration setTypeParameters(final List<TypeParameter> typeParameters) {
+        this.typeParameters = typeParameters;
+        setAsParentNodeOf(this.typeParameters);
+        return this;
+    }
+
+   
+
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/ConstructorDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/ConstructorDeclaration.java
new file mode 100644
index 0000000..4a9cd2a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/ConstructorDeclaration.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ConstructorDeclaration extends BodyDeclaration<ConstructorDeclaration>
+        implements NodeWithJavaDoc<ConstructorDeclaration>, NodeWithDeclaration,
+        NodeWithName<ConstructorDeclaration>, NodeWithModifiers<ConstructorDeclaration>,
+        NodeWithParameters<ConstructorDeclaration>, NodeWithThrowable<ConstructorDeclaration>,
+        NodeWithBlockStmt<ConstructorDeclaration> {
+
+    private EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+
+    private List<TypeParameter> typeParameters;
+
+    private NameExpr name;
+
+    private List<Parameter> parameters;
+
+    private List<ReferenceType> throws_;
+
+    private BlockStmt body;
+
+    public ConstructorDeclaration() {
+    }
+
+    public ConstructorDeclaration(EnumSet<Modifier> modifiers, String name) {
+        setModifiers(modifiers);
+        setName(name);
+    }
+
+    public ConstructorDeclaration(EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations,
+                                  List<TypeParameter> typeParameters,
+                                  String name, List<Parameter> parameters, List<ReferenceType> throws_,
+                                  BlockStmt block) {
+        super(annotations);
+        setModifiers(modifiers);
+        setTypeParameters(typeParameters);
+        setName(name);
+        setParameters(parameters);
+        setThrows(throws_);
+        setBody(block);
+    }
+
+    public ConstructorDeclaration(Range range, EnumSet<Modifier> modifiers,
+                                  List<AnnotationExpr> annotations, List<TypeParameter> typeParameters, String name,
+                                  List<Parameter> parameters, List<ReferenceType> throws_, BlockStmt block) {
+        super(range, annotations);
+        setModifiers(modifiers);
+        setTypeParameters(typeParameters);
+        setName(name);
+        setParameters(parameters);
+        setThrows(throws_);
+        setBody(block);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     * 
+     * @see Modifier
+     * @return modifiers
+     */
+    @Override
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Override
+    public String getName() {
+        return name == null ? null : name.getName();
+    }
+
+    public NameExpr getNameExpr() {
+        return name;
+    }
+
+    @Override
+    public List<Parameter> getParameters() {
+        parameters = ensureNotNull(parameters);
+        return parameters;
+    }
+
+    @Override
+    public List<ReferenceType> getThrows() {
+        throws_ = ensureNotNull(throws_);
+        return throws_;
+    }
+
+    public List<TypeParameter> getTypeParameters() {
+        typeParameters = ensureNotNull(typeParameters);
+        return typeParameters;
+    }
+
+    @Override
+    public ConstructorDeclaration setModifiers(EnumSet<Modifier> modifiers) {
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Override
+    public ConstructorDeclaration setName(String name) {
+        setNameExpr(new NameExpr(name));
+        return this;
+    }
+
+    public ConstructorDeclaration setNameExpr(NameExpr name) {
+        this.name = name;
+        setAsParentNodeOf(this.name);
+        return this;
+    }
+
+    @Override
+    public ConstructorDeclaration setParameters(List<Parameter> parameters) {
+        this.parameters = parameters;
+        setAsParentNodeOf(this.parameters);
+        return this;
+    }
+
+    @Override
+    public ConstructorDeclaration setThrows(List<ReferenceType> throws_) {
+        this.throws_ = throws_;
+        setAsParentNodeOf(this.throws_);
+        return this;
+    }
+
+    public ConstructorDeclaration setTypeParameters(List<TypeParameter> typeParameters) {
+        this.typeParameters = typeParameters;
+        setAsParentNodeOf(this.typeParameters);
+        return this;
+    }
+
+    /**
+     * The declaration returned has this schema:
+     *
+     * [accessSpecifier] className ([paramType [paramName]])
+     * [throws exceptionsList]
+     */
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows,
+                                         boolean includingParameterName) {
+        StringBuilder sb = new StringBuilder();
+        if (includingModifiers) {
+            AccessSpecifier accessSpecifier = Modifier.getAccessSpecifier(getModifiers());
+            sb.append(accessSpecifier.getCodeRepresenation());
+            sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ");
+        }
+        sb.append(getName());
+        sb.append("(");
+        boolean firstParam = true;
+        for (Parameter param : getParameters()) {
+            if (firstParam) {
+                firstParam = false;
+            } else {
+                sb.append(", ");
+            }
+            if (includingParameterName) {
+                sb.append(param.toStringWithoutComments());
+            } else {
+                sb.append(param.getElementType().toStringWithoutComments());
+            }
+        }
+        sb.append(")");
+        if (includingThrows) {
+            boolean firstThrow = true;
+            for (ReferenceType thr : getThrows()) {
+                if (firstThrow) {
+                    firstThrow = false;
+                    sb.append(" throws ");
+                } else {
+                    sb.append(", ");
+                }
+                sb.append(thr.toStringWithoutComments());
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows) {
+        return getDeclarationAsString(includingModifiers, includingThrows, true);
+    }
+
+    @Override
+    public String getDeclarationAsString() {
+        return getDeclarationAsString(true, true, true);
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        if (getComment() instanceof JavadocComment) {
+            return (JavadocComment) getComment();
+        }
+        return null;
+    }
+
+    @Override
+    public BlockStmt getBody() {
+        return body;
+    }
+
+    @Override
+    public ConstructorDeclaration setBody(BlockStmt body) {
+        this.body = body;
+        setAsParentNodeOf(body);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EmptyMemberDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EmptyMemberDeclaration.java
new file mode 100644
index 0000000..102eb7a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EmptyMemberDeclaration.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EmptyMemberDeclaration extends BodyDeclaration<EmptyMemberDeclaration>
+        implements NodeWithJavaDoc<EmptyMemberDeclaration> {
+
+    public EmptyMemberDeclaration() {
+        super(null);
+    }
+
+    public EmptyMemberDeclaration(Range range) {
+        super(range, null);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        if(getComment() instanceof JavadocComment){
+            return (JavadocComment) getComment();
+        }
+        return null;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EmptyTypeDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EmptyTypeDeclaration.java
new file mode 100644
index 0000000..3a774de
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EmptyTypeDeclaration.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import java.util.EnumSet;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EmptyTypeDeclaration extends TypeDeclaration<EmptyTypeDeclaration> {
+
+    public EmptyTypeDeclaration() {
+        super(null, EnumSet.noneOf(Modifier.class), null, null);
+    }
+
+    public EmptyTypeDeclaration(Range range) {
+        super(range, null, EnumSet.noneOf(Modifier.class), null, null);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EnumConstantDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EnumConstantDeclaration.java
new file mode 100644
index 0000000..646f6c2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EnumConstantDeclaration.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import static com.github.javaparser.ast.expr.NameExpr.*;
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EnumConstantDeclaration extends BodyDeclaration<EnumConstantDeclaration>
+        implements NodeWithJavaDoc<EnumConstantDeclaration>, NodeWithName<EnumConstantDeclaration> {
+
+    private String name;
+
+    private List<Expression> args;
+
+    private List<BodyDeclaration<?>> classBody;
+
+    public EnumConstantDeclaration() {
+    }
+
+    public EnumConstantDeclaration(String name) {
+        setName(name);
+    }
+
+    public EnumConstantDeclaration(List<AnnotationExpr> annotations, String name, List<Expression> args,
+                                   List<BodyDeclaration<?>> classBody) {
+        super(annotations);
+        setName(name);
+        setArgs(args);
+        setClassBody(classBody);
+    }
+
+    public EnumConstantDeclaration(Range range, List<AnnotationExpr> annotations, String name, List<Expression> args,
+                                   List<BodyDeclaration<?>> classBody) {
+        super(range, annotations);
+        setName(name);
+        setArgs(args);
+        setClassBody(classBody);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<Expression> getArgs() {
+        args = ensureNotNull(args);
+        return args;
+    }
+
+    public List<BodyDeclaration<?>> getClassBody() {
+        classBody = ensureNotNull(classBody);
+        return classBody;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public EnumConstantDeclaration setArgs(List<Expression> args) {
+        this.args = args;
+		setAsParentNodeOf(this.args);
+        return this;
+    }
+
+    public EnumConstantDeclaration setClassBody(List<BodyDeclaration<?>> classBody) {
+        this.classBody = classBody;
+		setAsParentNodeOf(this.classBody);
+        return this;
+    }
+
+    @Override
+    public EnumConstantDeclaration setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        if(getComment() instanceof JavadocComment){
+            return (JavadocComment) getComment();
+        }
+        return null;
+    }
+
+    public EnumConstantDeclaration addArgument(String valueExpr) {
+        getArgs().add(name(valueExpr));
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EnumDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EnumDeclaration.java
new file mode 100644
index 0000000..0ad3089
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/EnumDeclaration.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithImplements;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EnumDeclaration extends TypeDeclaration<EnumDeclaration>
+        implements NodeWithImplements<EnumDeclaration> {
+
+    private List<ClassOrInterfaceType> implementsList;
+
+    private List<EnumConstantDeclaration> entries;
+
+    public EnumDeclaration() {
+    }
+
+    public EnumDeclaration(EnumSet<Modifier> modifiers, String name) {
+        super(modifiers, name);
+    }
+
+    public EnumDeclaration(EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, String name,
+                           List<ClassOrInterfaceType> implementsList, List<EnumConstantDeclaration> entries,
+                           List<BodyDeclaration<?>> members) {
+        super(annotations, modifiers, name, members);
+        setImplements(implementsList);
+        setEntries(entries);
+    }
+
+    public EnumDeclaration(Range range, EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, String name,
+                           List<ClassOrInterfaceType> implementsList, List<EnumConstantDeclaration> entries,
+                           List<BodyDeclaration<?>> members) {
+        super(range, annotations, modifiers, name, members);
+        setImplements(implementsList);
+        setEntries(entries);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<EnumConstantDeclaration> getEntries() {
+        entries = ensureNotNull(entries);
+        return entries;
+    }
+
+    @Override
+    public List<ClassOrInterfaceType> getImplements() {
+        implementsList = ensureNotNull(implementsList);
+        return implementsList;
+    }
+
+    public EnumDeclaration setEntries(List<EnumConstantDeclaration> entries) {
+        this.entries = entries;
+		setAsParentNodeOf(this.entries);
+        return this;
+    }
+
+    @Override
+    public EnumDeclaration setImplements(List<ClassOrInterfaceType> implementsList) {
+        this.implementsList = implementsList;
+		setAsParentNodeOf(this.implementsList);
+        return this;
+    }
+
+
+
+    public EnumConstantDeclaration addEnumConstant(String name) {
+        EnumConstantDeclaration enumConstant = new EnumConstantDeclaration(name);
+        getEntries().add(enumConstant);
+        enumConstant.setParentNode(this);
+        return enumConstant;
+    }
+
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/FieldDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/FieldDeclaration.java
new file mode 100644
index 0000000..aa04a52
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/FieldDeclaration.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import static com.github.javaparser.ast.expr.NameExpr.*;
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.AssignExpr.Operator;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import static com.github.javaparser.ast.Modifier.PUBLIC;
+import static com.github.javaparser.ast.type.VoidType.VOID_TYPE;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class FieldDeclaration extends BodyDeclaration<FieldDeclaration> implements
+        NodeWithJavaDoc<FieldDeclaration>,
+        NodeWithElementType<FieldDeclaration>,
+        NodeWithModifiers<FieldDeclaration>,
+        NodeWithVariables<FieldDeclaration> {
+
+    private EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+
+    private Type elementType;
+
+    private List<VariableDeclarator> variables;
+
+    private List<ArrayBracketPair> arrayBracketPairsAfterElementType;
+
+    public FieldDeclaration() {
+    }
+
+    public FieldDeclaration(EnumSet<Modifier> modifiers, Type elementType, VariableDeclarator variable) {
+        setModifiers(modifiers);
+        setElementType(elementType);
+        List<VariableDeclarator> aux = new ArrayList<>();
+        aux.add(variable);
+        setVariables(aux);
+    }
+
+    public FieldDeclaration(EnumSet<Modifier> modifiers, Type elementType, List<VariableDeclarator> variables) {
+        setModifiers(modifiers);
+        setElementType(elementType);
+        setVariables(variables);
+    }
+
+    public FieldDeclaration(EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, Type elementType, List<ArrayBracketPair> arrayBracketPairsAfterElementType,
+                            List<VariableDeclarator> variables) {
+        super(annotations);
+        setModifiers(modifiers);
+        setElementType(elementType);
+        setVariables(variables);
+        setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType);
+    }
+
+    public FieldDeclaration(Range range, EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations, Type elementType,
+                            List<VariableDeclarator> variables, List<ArrayBracketPair> arrayBracketPairsAfterElementType) {
+        super(range, annotations);
+        setModifiers(modifiers);
+        setElementType(elementType);
+        setVariables(variables);
+        setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType);
+    }
+
+    /**
+     * Creates a {@link FieldDeclaration}.
+     *
+     * @param modifiers
+     *            modifiers
+     * @param type
+     *            type
+     * @param variable
+     *            variable declarator
+     * @return instance of {@link FieldDeclaration}
+     */
+    public static FieldDeclaration create(EnumSet<Modifier> modifiers, Type type,
+                                                          VariableDeclarator variable) {
+        List<VariableDeclarator> variables = new ArrayList<>();
+        variables.add(variable);
+        return new FieldDeclaration(modifiers, type, variables);
+    }
+
+    /**
+     * Creates a {@link FieldDeclaration}.
+     *
+     * @param modifiers
+     *            modifiers
+     * @param type
+     *            type
+     * @param name
+     *            field name
+     * @return instance of {@link FieldDeclaration}
+     */
+    public static FieldDeclaration create(EnumSet<Modifier> modifiers, Type type, String name) {
+        VariableDeclaratorId id = new VariableDeclaratorId(name);
+        VariableDeclarator variable = new VariableDeclarator(id);
+        return create(modifiers, type, variable);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     * 
+     * @see Modifier
+     * @return modifiers
+     */
+    @Override
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Override
+    public List<VariableDeclarator> getVariables() {
+        variables = ensureNotNull(variables);
+        return variables;
+    }
+
+    @Override
+    public FieldDeclaration setModifiers(EnumSet<Modifier> modifiers) {
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Override
+    public FieldDeclaration setVariables(List<VariableDeclarator> variables) {
+        this.variables = variables;
+        setAsParentNodeOf(this.variables);
+        return this;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        if (getComment() instanceof JavadocComment) {
+            return (JavadocComment) getComment();
+        }
+        return null;
+    }
+
+    /**
+     * Create a getter for this field, <b>will only work if this field declares only 1 identifier and if this field is
+     * already added to a ClassOrInterfaceDeclaration</b>
+     * 
+     * @return the {@link MethodDeclaration} created
+     * @throws IllegalStateException if there is more than 1 variable identifier or if this field isn't attached to a
+     *             class or enum
+     */
+    public MethodDeclaration createGetter() {
+        if (getVariables().size() != 1)
+            throw new IllegalStateException("You can use this only when the field declares only 1 variable name");
+        ClassOrInterfaceDeclaration parentClass = getParentNodeOfType(ClassOrInterfaceDeclaration.class);
+        EnumDeclaration parentEnum = getParentNodeOfType(EnumDeclaration.class);
+        if ((parentClass == null && parentEnum == null) || (parentClass != null && parentClass.isInterface()))
+            throw new IllegalStateException(
+                    "You can use this only when the field is attached to a class or an enum");
+
+        VariableDeclarator variable = getVariables().get(0);
+        String fieldName = variable.getId().getName();
+        String fieldNameUpper = fieldName.toUpperCase().substring(0, 1) + fieldName.substring(1, fieldName.length());
+        final MethodDeclaration getter;
+        if (parentClass != null)
+            getter = parentClass.addMethod("get" + fieldNameUpper, PUBLIC);
+        else
+            getter = parentEnum.addMethod("get" + fieldNameUpper, PUBLIC);
+        getter.setType(variable.getType());
+        BlockStmt blockStmt = new BlockStmt();
+        getter.setBody(blockStmt);
+        blockStmt.addStatement(new ReturnStmt(name(fieldName)));
+        return getter;
+    }
+
+    /**
+     * Create a setter for this field, <b>will only work if this field declares only 1 identifier and if this field is
+     * already added to a ClassOrInterfaceDeclaration</b>
+     * 
+     * @return the {@link MethodDeclaration} created
+     * @throws IllegalStateException if there is more than 1 variable identifier or if this field isn't attached to a
+     *             class or enum
+     */
+    public MethodDeclaration createSetter() {
+        if (getVariables().size() != 1)
+            throw new IllegalStateException("You can use this only when the field declares only 1 variable name");
+        ClassOrInterfaceDeclaration parentClass = getParentNodeOfType(ClassOrInterfaceDeclaration.class);
+        EnumDeclaration parentEnum = getParentNodeOfType(EnumDeclaration.class);
+        if ((parentClass == null && parentEnum == null) || (parentClass != null && parentClass.isInterface()))
+            throw new IllegalStateException(
+                    "You can use this only when the field is attached to a class or an enum");
+
+        VariableDeclarator variable = getVariables().get(0);
+        String fieldName = variable.getId().getName();
+        String fieldNameUpper = fieldName.toUpperCase().substring(0, 1) + fieldName.substring(1, fieldName.length());
+
+        final MethodDeclaration setter;
+        if (parentClass != null)
+            setter = parentClass.addMethod("set" + fieldNameUpper, PUBLIC);
+        else
+            setter = parentEnum.addMethod("set" + fieldNameUpper, PUBLIC);
+        setter.setType(VOID_TYPE);
+        setter.getParameters().add(new Parameter(variable.getType(), new VariableDeclaratorId(fieldName)));
+        BlockStmt blockStmt2 = new BlockStmt();
+        setter.setBody(blockStmt2);
+        blockStmt2.addStatement(new AssignExpr(new NameExpr("this." + fieldName), new NameExpr(fieldName), Operator.assign));
+        return setter;
+    }
+
+
+    @Override
+    public Type getElementType() {
+        return elementType;
+    }
+
+    @Override
+    public FieldDeclaration setElementType(final Type elementType) {
+        this.elementType = elementType;
+        setAsParentNodeOf(this.elementType);
+        return this;
+    }
+
+    /**
+     * @return the array brackets in this position: <code>class C { int[] abc; }</code>
+     */
+    public List<ArrayBracketPair> getArrayBracketPairsAfterElementType() {
+        arrayBracketPairsAfterElementType = ensureNotNull(arrayBracketPairsAfterElementType);
+        return arrayBracketPairsAfterElementType;
+    }
+
+    @Override
+    public FieldDeclaration setArrayBracketPairsAfterElementType(List<ArrayBracketPair> arrayBracketPairsAfterType) {
+        this.arrayBracketPairsAfterElementType = arrayBracketPairsAfterType;
+        setAsParentNodeOf(arrayBracketPairsAfterType);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/InitializerDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/InitializerDeclaration.java
new file mode 100644
index 0000000..adb893f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/InitializerDeclaration.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class InitializerDeclaration extends BodyDeclaration<InitializerDeclaration>
+        implements NodeWithJavaDoc<InitializerDeclaration> {
+
+    private boolean isStatic;
+
+    private BlockStmt block;
+
+    public InitializerDeclaration() {
+    }
+
+    public InitializerDeclaration(boolean isStatic, BlockStmt block) {
+        super(null);
+        setStatic(isStatic);
+        setBlock(block);
+    }
+
+    public InitializerDeclaration(Range range, boolean isStatic, BlockStmt block) {
+        super(range, null);
+        setStatic(isStatic);
+        setBlock(block);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public BlockStmt getBlock() {
+        return block;
+    }
+
+    public boolean isStatic() {
+        return isStatic;
+    }
+
+    public InitializerDeclaration setBlock(BlockStmt block) {
+        this.block = block;
+		setAsParentNodeOf(this.block);
+        return this;
+    }
+
+    public InitializerDeclaration setStatic(boolean isStatic) {
+        this.isStatic = isStatic;
+        return this;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        if(getComment() instanceof JavadocComment){
+            return (JavadocComment) getComment();
+        }
+        return null;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/MethodDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/MethodDeclaration.java
new file mode 100644
index 0000000..a89103a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/MethodDeclaration.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import static com.github.javaparser.ast.type.ArrayType.*;
+import static com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes;
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.utils.Pair;
+
+import java.util.EnumSet;
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MethodDeclaration extends BodyDeclaration<MethodDeclaration> implements 
+        NodeWithJavaDoc<MethodDeclaration>, 
+        NodeWithDeclaration, 
+        NodeWithName<MethodDeclaration>,
+        NodeWithType<MethodDeclaration>,
+        NodeWithElementType<MethodDeclaration>,
+        NodeWithModifiers<MethodDeclaration>, 
+        NodeWithParameters<MethodDeclaration>,
+        NodeWithThrowable<MethodDeclaration>, 
+        NodeWithBlockStmt<MethodDeclaration> {
+
+    private EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+
+    private List<TypeParameter> typeParameters;
+
+    private Type elementType;
+
+    private NameExpr name;
+
+    private List<Parameter> parameters;
+
+    private List<ReferenceType> throws_;
+
+    private BlockStmt body;
+
+    private boolean isDefault = false;
+
+    private List<ArrayBracketPair> arrayBracketPairsAfterType;
+
+    private List<ArrayBracketPair> arrayBracketPairsAfterParameterList;
+
+    public MethodDeclaration() {
+    }
+
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, final Type elementType, final String name) {
+        setModifiers(modifiers);
+        setElementType(elementType);
+        setName(name);
+    }
+
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, final Type elementType, final String name,
+                             final List<Parameter> parameters) {
+        setModifiers(modifiers);
+        setElementType(elementType);
+        setName(name);
+        setParameters(parameters);
+    }
+
+    public MethodDeclaration(final EnumSet<Modifier> modifiers, 
+                             final List<AnnotationExpr> annotations,
+                             final List<TypeParameter> typeParameters, 
+                             final Type elementType,
+                             final List<ArrayBracketPair> arrayBracketPairsAfterElementType,
+                             final String name,
+                             final List<Parameter> parameters, 
+                             final List<ArrayBracketPair> arrayBracketPairsAfterParameterList,
+                             final List<ReferenceType> throws_, 
+                             final BlockStmt body) {
+        super(annotations);
+        setModifiers(modifiers);
+        setTypeParameters(typeParameters);
+        setElementType(elementType);
+        setName(name);
+        setParameters(parameters);
+        setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType);
+        setArrayBracketPairsAfterParameterList(arrayBracketPairsAfterParameterList);
+        setThrows(throws_);
+        setBody(body);
+    }
+
+    public MethodDeclaration(Range range,
+                             final EnumSet<Modifier> modifiers, 
+                             final List<AnnotationExpr> annotations,
+                             final List<TypeParameter> typeParameters, 
+                             final Type elementType,
+                             final List<ArrayBracketPair> arrayBracketPairsAfterElementType,
+                             final NameExpr nameExpr,
+                             final List<Parameter> parameters, 
+                             final List<ArrayBracketPair> arrayBracketPairsAfterParameterList,
+                             final List<ReferenceType> throws_, 
+                             final BlockStmt body) {
+        super(range, annotations);
+        setModifiers(modifiers);
+        setTypeParameters(typeParameters);
+        setElementType(elementType);
+        setNameExpr(nameExpr);
+        setParameters(parameters);
+        setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType);
+        setArrayBracketPairsAfterParameterList(arrayBracketPairsAfterParameterList);
+        setThrows(throws_);
+        setBody(body);
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public BlockStmt getBody() {
+        return body;
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     * 
+     * @see Modifier
+     * @return modifiers
+     */
+    @Override
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Override
+    public String getName() {
+        return name.getName();
+    }
+
+    public NameExpr getNameExpr() {
+        return name;
+    }
+
+    @Override
+    public List<Parameter> getParameters() {
+        parameters = ensureNotNull(parameters);
+        return parameters;
+    }
+
+    @Override
+    public List<ReferenceType> getThrows() {
+        throws_ = ensureNotNull(throws_);
+        return throws_;
+    }
+
+    @Override
+    public Type getType() {
+        return wrapInArrayTypes(getElementType(),
+                getArrayBracketPairsAfterElementType(),
+                getArrayBracketPairsAfterParameterList());
+    }
+
+    @Override
+    public Type getElementType() {
+        return elementType;
+    }
+
+    public List<TypeParameter> getTypeParameters() {
+        typeParameters = ensureNotNull(typeParameters);
+        return typeParameters;
+    }
+
+    @Override
+    public MethodDeclaration setBody(final BlockStmt body) {
+        this.body = body;
+        setAsParentNodeOf(this.body);
+        return this;
+    }
+
+    @Override
+    public MethodDeclaration setModifiers(final EnumSet<Modifier> modifiers) {
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Override
+    public MethodDeclaration setName(final String name) {
+        setNameExpr(new NameExpr(name));
+        return this;
+    }
+
+    public MethodDeclaration setNameExpr(final NameExpr name) {
+        this.name = name;
+        setAsParentNodeOf(this.name);
+        return this;
+    }
+
+    @Override
+    public MethodDeclaration setParameters(final List<Parameter> parameters) {
+        this.parameters = parameters;
+        setAsParentNodeOf(this.parameters);
+        return this;
+    }
+
+    @Override
+    public MethodDeclaration setThrows(final List<ReferenceType> throws_) {
+        this.throws_ = throws_;
+        setAsParentNodeOf(this.throws_);
+        return this;
+    }
+
+    @Override
+    public MethodDeclaration setType(final Type type) {
+        Pair<Type, List<ArrayBracketPair>> typeListPair = unwrapArrayTypes(type);
+        setElementType(typeListPair.a);
+        setArrayBracketPairsAfterElementType(typeListPair.b);
+        setArrayBracketPairsAfterParameterList(null);
+        return this;
+    }
+
+    @Override
+    public MethodDeclaration setElementType(final Type elementType) {
+        this.elementType = elementType;
+        setAsParentNodeOf(this.elementType);
+        return this;
+    }
+
+    public MethodDeclaration setTypeParameters(final List<TypeParameter> typeParameters) {
+        this.typeParameters = typeParameters;
+        setAsParentNodeOf(typeParameters);
+        return this;
+    }
+
+    public boolean isDefault() {
+        return isDefault;
+    }
+
+    public MethodDeclaration setDefault(boolean isDefault) {
+        this.isDefault = isDefault;
+        return this;
+    }
+
+    @Override
+    public String getDeclarationAsString() {
+        return getDeclarationAsString(true, true, true);
+    }
+
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows) {
+        return getDeclarationAsString(includingModifiers, includingThrows, true);
+    }
+
+    /**
+     * The declaration returned has this schema:
+     *
+     * [accessSpecifier] [static] [abstract] [final] [native]
+     * [synchronized] returnType methodName ([paramType [paramName]])
+     * [throws exceptionsList]
+     * 
+     * @return method declaration as String
+     */
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows,
+                                         boolean includingParameterName) {
+        StringBuilder sb = new StringBuilder();
+        if (includingModifiers) {
+            AccessSpecifier accessSpecifier = Modifier.getAccessSpecifier(getModifiers());
+            sb.append(accessSpecifier.getCodeRepresenation());
+            sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ");
+            if (getModifiers().contains(Modifier.STATIC)) {
+                sb.append("static ");
+            }
+            if (getModifiers().contains(Modifier.ABSTRACT)) {
+                sb.append("abstract ");
+            }
+            if (getModifiers().contains(Modifier.FINAL)) {
+                sb.append("final ");
+            }
+            if (getModifiers().contains(Modifier.NATIVE)) {
+                sb.append("native ");
+            }
+            if (getModifiers().contains(Modifier.SYNCHRONIZED)) {
+                sb.append("synchronized ");
+            }
+        }
+        // TODO verify it does not print comments connected to the type
+        sb.append(getElementType().toStringWithoutComments());
+        sb.append(" ");
+        sb.append(getName());
+        sb.append("(");
+        boolean firstParam = true;
+        for (Parameter param : getParameters()) {
+            if (firstParam) {
+                firstParam = false;
+            } else {
+                sb.append(", ");
+            }
+            if (includingParameterName) {
+                sb.append(param.toStringWithoutComments());
+            } else {
+                sb.append(param.getElementType().toStringWithoutComments());
+                if (param.isVarArgs()) {
+                    sb.append("...");
+                }
+            }
+        }
+        sb.append(")");
+        if (includingThrows) {
+            boolean firstThrow = true;
+            for (ReferenceType thr : getThrows()) {
+                if (firstThrow) {
+                    firstThrow = false;
+                    sb.append(" throws ");
+                } else {
+                    sb.append(", ");
+                }
+                sb.append(thr.toStringWithoutComments());
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        if (getComment() instanceof JavadocComment) {
+            return (JavadocComment) getComment();
+        }
+        return null;
+    }
+
+    /**
+     * @return the array brackets in this position: <code>class C { int[] abc; }</code>
+     */
+    public List<ArrayBracketPair> getArrayBracketPairsAfterElementType() {
+        arrayBracketPairsAfterType = ensureNotNull(arrayBracketPairsAfterType);
+        return arrayBracketPairsAfterType;
+    }
+
+    @Override
+    public MethodDeclaration setArrayBracketPairsAfterElementType(List<ArrayBracketPair> arrayBracketPairsAfterType) {
+        this.arrayBracketPairsAfterType = arrayBracketPairsAfterType;
+        setAsParentNodeOf(arrayBracketPairsAfterType);
+        return this;
+    }
+
+	/**
+     * @return the array brackets in this position: <code>int abc()[] {...}</code>
+     */
+    public List<ArrayBracketPair> getArrayBracketPairsAfterParameterList() {
+        arrayBracketPairsAfterParameterList = ensureNotNull(arrayBracketPairsAfterParameterList);
+        return arrayBracketPairsAfterParameterList;
+    }
+
+    public MethodDeclaration setArrayBracketPairsAfterParameterList(List<ArrayBracketPair> arrayBracketPairsAfterParameterList) {
+        this.arrayBracketPairsAfterParameterList = arrayBracketPairsAfterParameterList;
+        setAsParentNodeOf(arrayBracketPairsAfterParameterList);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/Parameter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/Parameter.java
new file mode 100644
index 0000000..d66b39a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/Parameter.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.*;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.utils.Pair;
+
+import static com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes;
+import java.util.EnumSet;
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class Parameter extends Node implements
+        NodeWithType<Parameter>,
+        NodeWithElementType<Parameter>,
+        NodeWithAnnotations<Parameter>,
+        NodeWithName<Parameter>,
+        NodeWithModifiers<Parameter> {
+
+    private Type elementType;
+
+    private boolean isVarArgs;
+
+    private EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+
+    private List<AnnotationExpr> annotations;
+
+    private VariableDeclaratorId id;
+
+    private List<ArrayBracketPair> arrayBracketPairsAfterType;
+
+    public Parameter() {
+    }
+
+    public Parameter(Type elementType, VariableDeclaratorId id) {
+        setId(id);
+        setElementType(elementType);
+    }
+
+    /**
+     * Creates a new {@link Parameter}.
+     *
+     * @param elementType
+     *            type of the parameter
+     * @param name
+     *            name of the parameter
+     * @return instance of {@link Parameter}
+     */
+    public static Parameter create(Type elementType, String name) {
+        return new Parameter(elementType, new VariableDeclaratorId(name));
+    }
+
+    public Parameter(EnumSet<Modifier> modifiers, Type elementType, VariableDeclaratorId id) {
+        setModifiers(modifiers);
+        setId(id);
+        setElementType(elementType);
+    }
+
+    public Parameter(final Range range, 
+                     EnumSet<Modifier> modifiers, 
+                     List<AnnotationExpr> annotations, 
+                     Type elementType,
+                     List<ArrayBracketPair> arrayBracketPairsAfterElementType,
+                     boolean isVarArgs, 
+                     VariableDeclaratorId id) {
+        super(range);
+        setModifiers(modifiers);
+        setAnnotations(annotations);
+        setId(id);
+        setElementType(elementType);
+        setVarArgs(isVarArgs);
+        setArrayBracketPairsAfterElementType(arrayBracketPairsAfterElementType);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public Type getType() {
+        return wrapInArrayTypes(elementType,
+                getArrayBracketPairsAfterElementType(),
+                getId().getArrayBracketPairsAfterId());
+    }
+
+    public boolean isVarArgs() {
+        return isVarArgs;
+    }
+
+    @Override
+    public Parameter setType(Type type) {
+        Pair<Type, List<ArrayBracketPair>> unwrapped = ArrayType.unwrapArrayTypes(type);
+        setElementType(unwrapped.a);
+        setArrayBracketPairsAfterElementType(unwrapped.b);
+        getId().setArrayBracketPairsAfterId(null);
+        return this;
+    }
+
+    public Parameter setVarArgs(boolean isVarArgs) {
+        this.isVarArgs = isVarArgs;
+        return this;
+    }
+    /**
+     * @return the list returned could be immutable (in that case it will be empty)
+     */
+    @Override
+    public List<AnnotationExpr> getAnnotations() {
+        annotations = ensureNotNull(annotations);
+        return annotations;
+    }
+
+    public VariableDeclaratorId getId() {
+        return id;
+    }
+
+    @Override
+    public String getName() {
+        return getId().getName();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Parameter setName(String name) {
+        if (id != null)
+            id.setName(name);
+        else
+            id = new VariableDeclaratorId(name);
+        return this;
+    }
+
+    /**
+     * Return the modifiers of this parameter declaration.
+     *
+     * @see Modifier
+     * @return modifiers
+     */
+    @Override
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    /**
+     * @param annotations a null value is currently treated as an empty list. This behavior could change
+     *            in the future, so please avoid passing null
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    public Parameter setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+        setAsParentNodeOf(this.annotations);
+        return this;
+    }
+
+    public void setId(VariableDeclaratorId id) {
+        this.id = id;
+        setAsParentNodeOf(this.id);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Parameter setModifiers(EnumSet<Modifier> modifiers) {
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Override
+    public Type getElementType() {
+        return elementType;
+    }
+
+    @Override
+    public Parameter setElementType(final Type elementType) {
+        this.elementType = elementType;
+        setAsParentNodeOf(this.elementType);
+        return this;
+    }
+
+    public List<ArrayBracketPair> getArrayBracketPairsAfterElementType() {
+        arrayBracketPairsAfterType = ensureNotNull(arrayBracketPairsAfterType);
+        return arrayBracketPairsAfterType;
+    }
+
+    @Override
+    public Parameter setArrayBracketPairsAfterElementType(List<ArrayBracketPair> arrayBracketPairsAfterType) {
+        this.arrayBracketPairsAfterType = arrayBracketPairsAfterType;
+        setAsParentNodeOf(arrayBracketPairsAfterType);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/TypeDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/TypeDeclaration.java
new file mode 100644
index 0000000..829d37c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/TypeDeclaration.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+import static com.github.javaparser.utils.Utils.isNullOrEmpty;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithJavaDoc;
+import com.github.javaparser.ast.nodeTypes.NodeWithMembers;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class TypeDeclaration<T> extends BodyDeclaration<T>
+        implements NodeWithName<T>, NodeWithJavaDoc<T>, NodeWithModifiers<T>, NodeWithMembers<T> {
+
+	private NameExpr name;
+
+    private EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+
+    private List<BodyDeclaration<?>> members;
+
+	public TypeDeclaration() {
+	}
+
+    public TypeDeclaration(EnumSet<Modifier> modifiers, String name) {
+		setName(name);
+		setModifiers(modifiers);
+	}
+
+	public TypeDeclaration(List<AnnotationExpr> annotations,
+                           EnumSet<Modifier> modifiers, String name,
+                           List<BodyDeclaration<?>> members) {
+		super(annotations);
+		setName(name);
+		setModifiers(modifiers);
+		setMembers(members);
+	}
+
+	public TypeDeclaration(Range range, List<AnnotationExpr> annotations,
+                           EnumSet<Modifier> modifiers, String name,
+                           List<BodyDeclaration<?>> members) {
+		super(range, annotations);
+		setName(name);
+		setModifiers(modifiers);
+		setMembers(members);
+	}
+
+	/**
+	 * Adds the given declaration to the specified type. The list of members
+	 * will be initialized if it is <code>null</code>.
+	 *
+	 * @param decl
+	 *            member declaration
+	 */
+	public TypeDeclaration<T> addMember(BodyDeclaration<?> decl) {
+		List<BodyDeclaration<?>> members = getMembers();
+		if (isNullOrEmpty(members)) {
+			members = new ArrayList<>();
+			setMembers(members);
+		}
+		members.add(decl);
+		decl.setParentNode(this);
+		return this;
+	}
+
+    @Override
+    public List<BodyDeclaration<?>> getMembers() {
+        	members = ensureNotNull(members);
+        	return members;
+	}
+
+	/**
+     * Return the modifiers of this type declaration.
+     * 
+     * @see Modifier
+     * @return modifiers
+     */
+	@Override
+    public final EnumSet<Modifier> getModifiers() {
+		return modifiers;
+	}
+
+	@Override
+	public final String getName() {
+		return name.getName();
+	}
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public T setMembers(List<BodyDeclaration<?>> members) {
+		this.members = members;
+		setAsParentNodeOf(this.members);
+        return (T) this;
+	}
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public T setModifiers(EnumSet<Modifier> modifiers) {
+		this.modifiers = modifiers;
+        return (T) this;
+	}
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public T setName(String name) {
+		setNameExpr(new NameExpr(name));
+        return (T) this;
+	}
+
+    @SuppressWarnings("unchecked")
+    public T setNameExpr(NameExpr nameExpr) {
+		this.name = nameExpr;
+		setAsParentNodeOf(this.name);
+        return (T) this;
+	}
+
+	public final NameExpr getNameExpr() {
+		return name;
+	}
+
+	@Override
+	public JavadocComment getJavaDoc() {
+		if(getComment() instanceof JavadocComment){
+			return (JavadocComment) getComment();
+		}
+		return null;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/VariableDeclarator.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/VariableDeclarator.java
new file mode 100644
index 0000000..ff78d6e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/VariableDeclarator.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithElementType;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.utils.Pair;
+
+import java.util.List;
+
+import static com.github.javaparser.ast.type.ArrayType.wrapInArrayTypes;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclarator extends Node implements
+        NodeWithType<VariableDeclarator> {
+
+    private VariableDeclaratorId id;
+
+    private Expression init;
+
+    public VariableDeclarator() {
+    }
+
+    public VariableDeclarator(VariableDeclaratorId id) {
+        setId(id);
+    }
+
+    public VariableDeclarator(String variableName) {
+        setId(new VariableDeclaratorId(variableName));
+    }
+
+    /**
+     * Defines the declaration of a variable.
+     * 
+     * @param id The identifier for this variable. IE. The variables name.
+     * @param init What this variable should be initialized to.
+     *            An {@link com.github.javaparser.ast.expr.AssignExpr} is unnecessary as the <code>=</code> operator is
+     *            already added.
+     */
+    public VariableDeclarator(VariableDeclaratorId id, Expression init) {
+        setId(id);
+        setInit(init);
+    }
+
+    public VariableDeclarator(String variableName, Expression init) {
+        setId(new VariableDeclaratorId(variableName));
+        setInit(init);
+    }
+
+    public VariableDeclarator(Range range, VariableDeclaratorId id, Expression init) {
+        super(range);
+        setId(id);
+        setInit(init);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public VariableDeclaratorId getId() {
+        return id;
+    }
+
+    public Expression getInit() {
+        return init;
+    }
+
+    public VariableDeclarator setId(VariableDeclaratorId id) {
+        this.id = id;
+        setAsParentNodeOf(this.id);
+        return this;
+    }
+
+    public VariableDeclarator setInit(Expression init) {
+        this.init = init;
+        setAsParentNodeOf(this.init);
+        return this;
+    }
+
+    /**
+     * Will create a {@link NameExpr} with the init param
+     */
+    public VariableDeclarator setInit(String init) {
+        this.init = new NameExpr(init);
+        setAsParentNodeOf(this.init);
+        return this;
+    }
+
+
+    @Override
+    public Type getType() {
+        NodeWithElementType<?> elementType = getParentNodeOfType(NodeWithElementType.class);
+
+        return wrapInArrayTypes(elementType.getElementType(),
+                elementType.getArrayBracketPairsAfterElementType(),
+                getId().getArrayBracketPairsAfterId());
+    }
+
+    @Override
+    public VariableDeclarator setType(Type type) {
+        Pair<Type, List<ArrayBracketPair>> unwrapped = ArrayType.unwrapArrayTypes(type);
+        NodeWithElementType<?> nodeWithElementType = getParentNodeOfType(NodeWithElementType.class);
+        if (nodeWithElementType == null) {
+            throw new IllegalStateException("Cannot set type without a parent");
+        }
+        nodeWithElementType.setElementType(unwrapped.a);
+        nodeWithElementType.setArrayBracketPairsAfterElementType(null);
+        getId().setArrayBracketPairsAfterId(unwrapped.b);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/VariableDeclaratorId.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/VariableDeclaratorId.java
new file mode 100644
index 0000000..b6dccc2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/body/VariableDeclaratorId.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclaratorId extends Node implements NodeWithName<VariableDeclaratorId> {
+
+    private String name;
+
+    private List<ArrayBracketPair> arrayBracketPairsAfterId;
+
+    public VariableDeclaratorId() {
+    }
+
+    public VariableDeclaratorId(String name) {
+       setName(name);
+    }
+
+    public VariableDeclaratorId(Range range, String name, List<ArrayBracketPair> arrayBracketPairsAfterId) {
+        super(range);
+        setName(name);
+        setArrayBracketPairsAfterId(arrayBracketPairsAfterId);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public VariableDeclaratorId setName(String name) {
+        this.name = name;
+        return this;
+    }
+
+    public List<ArrayBracketPair> getArrayBracketPairsAfterId() {
+        arrayBracketPairsAfterId = ensureNotNull(arrayBracketPairsAfterId);
+        return arrayBracketPairsAfterId;
+    }
+
+    public VariableDeclaratorId setArrayBracketPairsAfterId(List<ArrayBracketPair> arrayBracketPairsAfterId) {
+        this.arrayBracketPairsAfterId = arrayBracketPairsAfterId;
+        setAsParentNodeOf(arrayBracketPairsAfterId);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/BlockComment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/BlockComment.java
new file mode 100644
index 0000000..77157d5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/BlockComment.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * <p>
+ * AST node that represent block comments.
+ * </p>
+ * Block comments can has multi lines and are delimited by "/&#42;" and
+ * "&#42;/".
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public final class BlockComment extends Comment {
+
+    public BlockComment() {
+    }
+
+    public BlockComment(String content) {
+        super(content);
+    }
+
+    public BlockComment(Range range, String content) {
+        super(range, content);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/Comment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/Comment.java
new file mode 100644
index 0000000..9da994e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/Comment.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+
+/**
+ * Abstract class for all AST nodes that represent comments.
+ * 
+ * @see BlockComment
+ * @see LineComment
+ * @see JavadocComment
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Comment extends Node {
+
+    private String content;
+    private Node commentedNode;
+
+    public Comment() {
+    }
+
+    public Comment(String content) {
+        this.content = content;
+    }
+
+    public Comment(Range range, String content) {
+        super(range);
+        this.content = content;
+    }
+
+    /**
+     * Return the text of the comment.
+     * 
+     * @return text of the comment
+     */
+    public final String getContent() {
+        return content;
+    }
+
+    /**
+     * Sets the text of the comment.
+     * 
+     * @param content
+     *            the text of the comment to set
+     */
+    public Comment setContent(String content) {
+        this.content = content;
+        return this;
+    }
+
+    public boolean isLineComment()
+    {
+        return false;
+    }
+
+    public LineComment asLineComment() {
+        if (isLineComment()) {
+            return (LineComment) this;
+        } else {
+            throw new UnsupportedOperationException("Not a line comment");
+        }
+    }
+
+    public Node getCommentedNode()
+    {
+        return this.commentedNode;
+    }
+
+    public Comment setCommentedNode(Node commentedNode)
+    {
+        if (commentedNode==null) {
+            this.commentedNode = null;
+            return this;
+        }
+        if (commentedNode==this) {
+            throw new IllegalArgumentException();
+        }
+        if (commentedNode instanceof Comment) {
+            throw new IllegalArgumentException();
+        }
+        this.commentedNode = commentedNode;
+        return this;
+    }
+
+    public boolean isOrphan()
+    {
+        return this.commentedNode == null;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/CommentsCollection.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/CommentsCollection.java
new file mode 100644
index 0000000..d02c7a5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/CommentsCollection.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.comments;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.ast.Node.NODE_BY_BEGIN_POSITION;
+
+/**
+ * The comments contained in a certain parsed piece of source code.
+ */
+public class CommentsCollection {
+    private final TreeSet<Comment> comments = new TreeSet<>(NODE_BY_BEGIN_POSITION);
+
+    public CommentsCollection() {
+    }
+
+    public CommentsCollection(Collection<Comment> commentsToCopy) {
+        comments.addAll(commentsToCopy);
+    }
+
+    public Set<LineComment> getLineComments() {
+        return comments.stream()
+                .filter(comment -> comment instanceof LineComment)
+                .map(comment -> (LineComment) comment)
+                .collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)));
+    }
+
+    public Set<BlockComment> getBlockComments() {
+        return comments.stream()
+                .filter(comment -> comment instanceof BlockComment)
+                .map(comment -> (BlockComment) comment)
+                .collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)));
+    }
+
+    public Set<JavadocComment> getJavadocComments() {
+        return comments.stream()
+                .filter(comment -> comment instanceof JavadocComment)
+                .map(comment -> (JavadocComment) comment)
+                .collect(Collectors.toCollection(() -> new TreeSet<>(NODE_BY_BEGIN_POSITION)));
+    }
+
+    public void addComment(Comment comment) {
+        comments.add(comment);
+    }
+
+    public boolean contains(Comment comment) {
+        for (Comment c : getComments()) {
+            // we tolerate a difference of one element in the end column:
+            // it depends how \r and \n are calculated...
+            if (c.getBegin().line == comment.getBegin().line &&
+                    c.getBegin().column == comment.getBegin().column &&
+                    c.getEnd().line == comment.getEnd().line &&
+                    Math.abs(c.getEnd().column - comment.getEnd().column) < 2) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public TreeSet<Comment> getComments() {
+        return comments;
+    }
+
+    public int size() {
+        return comments.size();
+    }
+
+    public CommentsCollection minus(CommentsCollection other) {
+        CommentsCollection result = new CommentsCollection();
+        result.comments.addAll(
+                comments.stream()
+                        .filter(comment -> !other.contains(comment))
+                        .collect(Collectors.toList()));
+        return result;
+    }
+
+    public CommentsCollection copy() {
+        return new CommentsCollection(comments);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/JavadocComment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/JavadocComment.java
new file mode 100644
index 0000000..18b77af
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/JavadocComment.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class JavadocComment extends Comment {
+
+    public JavadocComment() {
+    }
+
+    public JavadocComment(String content) {
+        super(content);
+    }
+
+    public JavadocComment(Range range, String content) {
+        super(range, content);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/LineComment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/LineComment.java
new file mode 100644
index 0000000..56b8054
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/comments/LineComment.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * <p>
+ * AST node that represent line comments.
+ * </p>
+ * Line comments are started with "//" and finish at the end of the line ("\n").
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public final class LineComment extends Comment {
+
+    public LineComment() {
+    }
+
+    public LineComment(String content) {
+        super(content);
+    }
+
+    public LineComment(Range range, String content) {
+        super(range, content);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public boolean isLineComment()
+    {
+        return true;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/AnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/AnnotationExpr.java
new file mode 100644
index 0000000..a1cad1c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/AnnotationExpr.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class AnnotationExpr extends Expression {
+
+	protected NameExpr name;
+
+	public AnnotationExpr() {}
+
+	public AnnotationExpr(Range range) {
+		super(range);
+	}
+
+	public NameExpr getName() {
+		return name;
+	}
+
+	public AnnotationExpr setName(NameExpr name) {
+		this.name = name;
+		setAsParentNodeOf(name);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayAccessExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayAccessExpr.java
new file mode 100644
index 0000000..b461ea8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayAccessExpr.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayAccessExpr extends Expression {
+
+    private Expression name;
+
+    private Expression index;
+
+    public ArrayAccessExpr() {
+    }
+
+    public ArrayAccessExpr(Expression name, Expression index) {
+        setName(name);
+        setIndex(index);
+    }
+
+    public ArrayAccessExpr(Range range, Expression name, Expression index) {
+        super(range);
+        setName(name);
+        setIndex(index);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getIndex() {
+        return index;
+    }
+
+    public Expression getName() {
+        return name;
+    }
+
+    public ArrayAccessExpr setIndex(Expression index) {
+        this.index = index;
+		setAsParentNodeOf(this.index);
+        return this;
+    }
+
+    public ArrayAccessExpr setName(Expression name) {
+        this.name = name;
+		setAsParentNodeOf(this.name);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayCreationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayCreationExpr.java
new file mode 100644
index 0000000..79d55a5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayCreationExpr.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.ArrayCreationLevel;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayCreationExpr extends Expression implements NodeWithType<ArrayCreationExpr> {
+
+    private List<ArrayCreationLevel> levels;
+
+    private Type type;
+
+    private ArrayInitializerExpr initializer;
+
+    public ArrayCreationExpr() {
+    }
+
+    public ArrayCreationExpr(Type type, List<ArrayCreationLevel> levels, ArrayInitializerExpr initializer) {
+        setLevels(levels);
+        setType(type);
+        setInitializer(initializer);
+    }
+
+    public ArrayCreationExpr(Range range, Type type, List<ArrayCreationLevel> levels, ArrayInitializerExpr initializer) {
+        super(range);
+        setLevels(levels);
+        setType(type);
+        setInitializer(initializer);
+    }
+
+    public ArrayCreationExpr(Type type) {
+        setType(type);
+        setInitializer(null);
+    }
+
+    public ArrayCreationExpr(Range range, Type type) {
+        super(range);
+        setType(type);
+        setInitializer(null);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public ArrayInitializerExpr getInitializer() {
+        return initializer;
+    }
+
+    @Override
+    public Type getType() {
+        return type;
+    }
+
+    public ArrayCreationExpr setInitializer(ArrayInitializerExpr initializer) {
+        this.initializer = initializer;
+		setAsParentNodeOf(this.initializer);
+        return this;
+    }
+
+    @Override
+    public ArrayCreationExpr setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+        return this;
+    }
+
+    public List<ArrayCreationLevel> getLevels() {
+        levels = ensureNotNull(levels);
+        return levels;
+    }
+
+    public ArrayCreationExpr setLevels(List<ArrayCreationLevel> levels) {
+        this.levels = levels;
+        setAsParentNodeOf(levels);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayInitializerExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayInitializerExpr.java
new file mode 100644
index 0000000..67c1073
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ArrayInitializerExpr.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayInitializerExpr extends Expression {
+
+    private List<Expression> values;
+
+    public ArrayInitializerExpr() {
+    }
+
+    public ArrayInitializerExpr(List<Expression> values) {
+       setValues(values);
+    }
+
+    public ArrayInitializerExpr(Range range, List<Expression> values) {
+        super(range);
+        setValues(values);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<Expression> getValues() {
+        values = ensureNotNull(values);
+        return values;
+    }
+
+    public ArrayInitializerExpr setValues(List<Expression> values) {
+        this.values = values;
+		setAsParentNodeOf(this.values);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/AssignExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/AssignExpr.java
new file mode 100644
index 0000000..cf16c6f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/AssignExpr.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AssignExpr extends Expression {
+
+    public enum Operator {
+        assign, // =
+        plus, // +=
+        minus, // -=
+        star, // *=
+        slash, // /=
+        and, // &=
+        or, // |=
+        xor, // ^=
+        rem, // %=
+        lShift, // <<=
+        rSignedShift, // >>=
+        rUnsignedShift, // >>>=
+    }
+
+    private Expression target;
+
+    private Expression value;
+
+    private Operator op;
+
+    public AssignExpr() {
+    }
+
+    public AssignExpr(Expression target, Expression value, Operator op) {
+        setTarget(target);
+        setValue(value);
+        setOperator(op);
+    }
+
+    public AssignExpr(Range range, Expression target, Expression value, Operator op) {
+        super(range);
+        setTarget(target);
+        setValue(value);
+        setOperator(op);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Operator getOperator() {
+        return op;
+    }
+
+    public Expression getTarget() {
+        return target;
+    }
+
+    public Expression getValue() {
+        return value;
+    }
+
+    public AssignExpr setOperator(Operator op) {
+        this.op = op;
+        return this;
+    }
+
+    public AssignExpr setTarget(Expression target) {
+        this.target = target;
+		setAsParentNodeOf(this.target);
+        return this;
+    }
+
+    public AssignExpr setValue(Expression value) {
+        this.value = value;
+		setAsParentNodeOf(this.value);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/BinaryExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/BinaryExpr.java
new file mode 100644
index 0000000..83675c8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/BinaryExpr.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BinaryExpr extends Expression {
+
+    public enum Operator {
+        or, // ||
+        and, // &&
+        binOr, // |
+        binAnd, // &
+        xor, // ^
+        equals, // ==
+        notEquals, // !=
+        less, // <
+        greater, // >
+        lessEquals, // <=
+        greaterEquals, // >=
+        lShift, // <<
+        rSignedShift, // >>
+        rUnsignedShift, // >>>
+        plus, // +
+        minus, // -
+        times, // *
+        divide, // /
+        remainder, // %
+    }
+
+    private Expression left;
+
+    private Expression right;
+
+    private Operator op;
+
+    public BinaryExpr() {
+    }
+
+    public BinaryExpr(Expression left, Expression right, Operator op) {
+    	setLeft(left);
+    	setRight(right);
+    	setOperator(op);
+    }
+
+    public BinaryExpr(Range range, Expression left, Expression right, Operator op) {
+        super(range);
+    	setLeft(left);
+    	setRight(right);
+    	setOperator(op);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getLeft() {
+        return left;
+    }
+
+    public Operator getOperator() {
+        return op;
+    }
+
+    public Expression getRight() {
+        return right;
+    }
+
+    public BinaryExpr setLeft(Expression left) {
+        this.left = left;
+		setAsParentNodeOf(this.left);
+        return this;
+    }
+
+    public BinaryExpr setOperator(Operator op) {
+        this.op = op;
+        return this;
+    }
+
+    public BinaryExpr setRight(Expression right) {
+        this.right = right;
+		setAsParentNodeOf(this.right);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/BooleanLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/BooleanLiteralExpr.java
new file mode 100644
index 0000000..a42c8c7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/BooleanLiteralExpr.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BooleanLiteralExpr extends LiteralExpr {
+
+    private boolean value;
+
+    public BooleanLiteralExpr() {
+    }
+
+    public BooleanLiteralExpr(boolean value) {
+    	setValue(value);
+    }
+
+    public BooleanLiteralExpr(Range range, boolean value) {
+        super(range);
+        setValue(value);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public boolean getValue() {
+        return value;
+    }
+
+    public BooleanLiteralExpr setValue(boolean value) {
+        this.value = value;
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/CastExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/CastExpr.java
new file mode 100644
index 0000000..d2a54bc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/CastExpr.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class CastExpr extends Expression implements NodeWithType<CastExpr> {
+
+    private Type type;
+
+    private Expression expr;
+
+    public CastExpr() {
+    }
+
+    public CastExpr(Type type, Expression expr) {
+    	setType(type);
+    	setExpr(expr);
+    }
+
+    public CastExpr(Range range, Type type, Expression expr) {
+        super(range);
+        setType(type);
+    	setExpr(expr);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getExpr() {
+        return expr;
+    }
+
+    @Override
+    public Type getType() {
+        return type;
+    }
+
+    public CastExpr setExpr(Expression expr) {
+        this.expr = expr;
+		setAsParentNodeOf(this.expr);
+        return this;
+    }
+
+    @Override
+    public CastExpr setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/CharLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/CharLiteralExpr.java
new file mode 100644
index 0000000..e799e88
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/CharLiteralExpr.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.utils.Utils;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class CharLiteralExpr extends StringLiteralExpr {
+
+    public CharLiteralExpr() {
+    }
+
+    public CharLiteralExpr(String value) {
+        super(value);
+    }
+
+    public CharLiteralExpr(Range range, String value) {
+        super(range, value);
+    }
+
+    /**
+     * Utility method that creates a new StringLiteralExpr. Escapes EOL characters.
+     */
+    public static CharLiteralExpr escape(String string) {
+        return new CharLiteralExpr(Utils.escapeEndOfLines(string));
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ClassExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ClassExpr.java
new file mode 100644
index 0000000..a6dc905
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ClassExpr.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * Defines an expression that accesses the class of a type.
+ * Example:
+ * <code>
+ *     Object.class
+ * </code>
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassExpr extends Expression implements NodeWithType<ClassExpr> {
+
+    private Type type;
+
+    public ClassExpr() {
+    }
+
+    public ClassExpr(Type type) {
+       setType(type);
+    }
+
+    public ClassExpr(Range range, Type type) {
+        super(range);
+        setType(type);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public Type getType() {
+        return type;
+    }
+
+    @Override
+    public ClassExpr setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ConditionalExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ConditionalExpr.java
new file mode 100644
index 0000000..4dd4c4b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ConditionalExpr.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ConditionalExpr extends Expression {
+
+    private Expression condition;
+
+    private Expression thenExpr;
+
+    private Expression elseExpr;
+
+    public ConditionalExpr() {
+    }
+
+    public ConditionalExpr(Expression condition, Expression thenExpr, Expression elseExpr) {
+        setCondition(condition);
+        setThenExpr(thenExpr);
+        setElseExpr(elseExpr);
+    }
+
+    public ConditionalExpr(Range range, Expression condition, Expression thenExpr, Expression elseExpr) {
+        super(range);
+        setCondition(condition);
+        setThenExpr(thenExpr);
+        setElseExpr(elseExpr);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getCondition() {
+        return condition;
+    }
+
+    public Expression getElseExpr() {
+        return elseExpr;
+    }
+
+    public Expression getThenExpr() {
+        return thenExpr;
+    }
+
+    public ConditionalExpr setCondition(Expression condition) {
+        this.condition = condition;
+		setAsParentNodeOf(this.condition);
+        return this;
+    }
+
+    public ConditionalExpr setElseExpr(Expression elseExpr) {
+        this.elseExpr = elseExpr;
+		setAsParentNodeOf(this.elseExpr);
+        return this;
+    }
+
+    public ConditionalExpr setThenExpr(Expression thenExpr) {
+        this.thenExpr = thenExpr;
+		setAsParentNodeOf(this.thenExpr);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/DoubleLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/DoubleLiteralExpr.java
new file mode 100644
index 0000000..b789238
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/DoubleLiteralExpr.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class DoubleLiteralExpr extends StringLiteralExpr {
+
+	public DoubleLiteralExpr() {
+	}
+
+	public DoubleLiteralExpr(final String value) {
+		super(value);
+	}
+
+	public DoubleLiteralExpr(final Range range, final String value) {
+		super(range, value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/EnclosedExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/EnclosedExpr.java
new file mode 100644
index 0000000..a7c40fe
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/EnclosedExpr.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EnclosedExpr extends Expression {
+
+	private Expression inner;
+
+	public EnclosedExpr() {
+	}
+
+	public EnclosedExpr(final Expression inner) {
+		setInner(inner);
+	}
+
+	public EnclosedExpr(final Range range, final Expression inner) {
+		super(range);
+		setInner(inner);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getInner() {
+		return inner;
+	}
+
+	public EnclosedExpr setInner(final Expression inner) {
+		this.inner = inner;
+		setAsParentNodeOf(this.inner);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/Expression.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/Expression.java
new file mode 100644
index 0000000..f974564
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/Expression.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Expression extends Node {
+
+	public Expression() {
+	}
+
+	public Expression(Range range) {
+		super(range);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/FieldAccessExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/FieldAccessExpr.java
new file mode 100644
index 0000000..0a4badf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/FieldAccessExpr.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class FieldAccessExpr extends Expression implements NodeWithTypeArguments<FieldAccessExpr> {
+
+	private Expression scope;
+
+	private List<Type<?>> typeArguments;
+
+	private NameExpr field;
+
+	public FieldAccessExpr() {
+	}
+
+	public FieldAccessExpr(final Expression scope, final String field) {
+		setScope(scope);
+		setField(field);
+	}
+
+	public FieldAccessExpr(final Range range, final Expression scope, final List<Type<?>> typeArguments, final String field) {
+		super(range);
+		setScope(scope);
+		setTypeArguments(typeArguments);
+		setField(field);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getField() {
+		return field.getName();
+	}
+
+	public NameExpr getFieldExpr() {
+		return field;
+	}
+
+	public Expression getScope() {
+		return scope;
+	}
+
+	public FieldAccessExpr setField(final String field) {
+		setFieldExpr(new NameExpr(field));
+		return this;
+	}
+
+	public FieldAccessExpr setFieldExpr(NameExpr field) {
+		this.field = field;
+		setAsParentNodeOf(this.field);
+		return this;
+	}
+
+	public FieldAccessExpr setScope(final Expression scope) {
+		this.scope = scope;
+		setAsParentNodeOf(this.scope);
+		return this;
+	}
+
+
+	@Override
+	public List<Type<?>> getTypeArguments() {
+		return typeArguments;
+	}
+
+	@Override
+	public FieldAccessExpr setTypeArguments(final List<Type<?>> types) {
+		this.typeArguments = types;
+		setAsParentNodeOf(this.typeArguments);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/InstanceOfExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/InstanceOfExpr.java
new file mode 100644
index 0000000..ffc248c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/InstanceOfExpr.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class InstanceOfExpr extends Expression implements NodeWithType<InstanceOfExpr> {
+
+	private Expression expr;
+
+	private Type type;
+
+	public InstanceOfExpr() {
+	}
+
+	public InstanceOfExpr(final Expression expr, final Type type) {
+		setExpr(expr);
+		setType(type);
+	}
+
+	public InstanceOfExpr(final Range range, final Expression expr, final Type type) {
+		super(range);
+		setExpr(expr);
+		setType(type);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	@Override
+	public Type getType() {
+		return type;
+	}
+
+	public InstanceOfExpr setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+		return this;
+	}
+
+	@Override
+    public InstanceOfExpr setType(final Type type) {
+		this.type = type;
+		setAsParentNodeOf(this.type);
+        return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/IntegerLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/IntegerLiteralExpr.java
new file mode 100644
index 0000000..91f5dec
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/IntegerLiteralExpr.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class IntegerLiteralExpr extends StringLiteralExpr {
+
+	private static final String UNSIGNED_MIN_VALUE = "2147483648";
+
+	protected static final String MIN_VALUE = "-" + UNSIGNED_MIN_VALUE;
+
+	public IntegerLiteralExpr() {
+	}
+
+	public IntegerLiteralExpr(final String value) {
+		super(value);
+	}
+
+	public IntegerLiteralExpr(final Range range, final String value) {
+		super(range, value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public final boolean isMinValue() {
+		return value != null && //
+				value.length() == 10 && //
+				value.equals(UNSIGNED_MIN_VALUE);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr.java
new file mode 100644
index 0000000..2665aaf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class IntegerLiteralMinValueExpr extends IntegerLiteralExpr {
+
+	public IntegerLiteralMinValueExpr() {
+		super(MIN_VALUE);
+	}
+
+	public IntegerLiteralMinValueExpr(final Range range) {
+		super(range, MIN_VALUE);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LambdaExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LambdaExpr.java
new file mode 100644
index 0000000..4db1b0d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LambdaExpr.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.*;
+
+/**
+ * Lambda expression.
+ *
+ * @author Raquel Pau
+ */
+public class LambdaExpr extends Expression {
+
+	private List<Parameter> parameters;
+
+	private boolean parametersEnclosed;
+
+	private Statement body;
+
+	public LambdaExpr() {
+	}
+
+	public LambdaExpr(Range range, List<Parameter> parameters, Statement body,
+                      boolean parametersEnclosed) {
+
+		super(range);
+		setParameters(parameters);
+		setBody(body);
+        setParametersEnclosed(parametersEnclosed);
+	}
+
+	public List<Parameter> getParameters() {
+        parameters = ensureNotNull(parameters);
+        return parameters;
+	}
+
+	public LambdaExpr setParameters(List<Parameter> parameters) {
+		this.parameters = parameters;
+		setAsParentNodeOf(this.parameters);
+		return this;
+	}
+
+	public Statement getBody() {
+		return body;
+	}
+
+	public LambdaExpr setBody(Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+		return this;
+	}
+
+	@Override
+	public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(VoidVisitor<A> v, A arg) {
+		v.visit(this, arg);
+	}
+
+	public boolean isParametersEnclosed() {
+		return parametersEnclosed;
+	}
+
+	public LambdaExpr setParametersEnclosed(boolean parametersEnclosed) {
+		this.parametersEnclosed = parametersEnclosed;
+		return this;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LiteralExpr.java
new file mode 100644
index 0000000..9cafefd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LiteralExpr.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class LiteralExpr extends Expression {
+
+	public LiteralExpr() {
+	}
+
+	public LiteralExpr(Range range) {
+		super(range);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LongLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LongLiteralExpr.java
new file mode 100644
index 0000000..0e2e8f2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LongLiteralExpr.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class LongLiteralExpr extends StringLiteralExpr {
+
+	private static final String UNSIGNED_MIN_VALUE = "9223372036854775808";
+
+	protected static final String MIN_VALUE = "-" + UNSIGNED_MIN_VALUE + "L";
+
+	public LongLiteralExpr() {
+	}
+
+	public LongLiteralExpr(final String value) {
+		super(value);
+	}
+
+	public LongLiteralExpr(final Range range, final String value) {
+		super(range, value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public final boolean isMinValue() {
+		return value != null && //
+				value.length() == 20 && //
+				value.startsWith(UNSIGNED_MIN_VALUE) && //
+				(value.charAt(19) == 'L' || value.charAt(19) == 'l');
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LongLiteralMinValueExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LongLiteralMinValueExpr.java
new file mode 100644
index 0000000..d46145a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/LongLiteralMinValueExpr.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class LongLiteralMinValueExpr extends LongLiteralExpr {
+
+	public LongLiteralMinValueExpr() {
+		super(MIN_VALUE);
+	}
+
+	public LongLiteralMinValueExpr(final Range range) {
+		super(range, MIN_VALUE);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java
new file mode 100644
index 0000000..1a117ff
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MarkerAnnotationExpr extends AnnotationExpr {
+
+	public MarkerAnnotationExpr() {
+	}
+
+	public MarkerAnnotationExpr(final NameExpr name) {
+		setName(name);
+	}
+
+	public MarkerAnnotationExpr(final Range range, final NameExpr name) {
+		super(range);
+		setName(name);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MemberValuePair.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MemberValuePair.java
new file mode 100644
index 0000000..f87af5d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MemberValuePair.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MemberValuePair extends Node implements NodeWithName<MemberValuePair> {
+
+	private String name;
+
+	private Expression value;
+
+	public MemberValuePair() {
+	}
+
+	public MemberValuePair(final String name, final Expression value) {
+		setName(name);
+		setValue(value);
+	}
+
+	public MemberValuePair(final Range range, final String name, final Expression value) {
+		super(range);
+		setName(name);
+		setValue(value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	public Expression getValue() {
+		return value;
+	}
+
+    @Override
+    public MemberValuePair setName(final String name) {
+		this.name = name;
+        return this;
+	}
+
+	public MemberValuePair setValue(final Expression value) {
+		this.value = value;
+		setAsParentNodeOf(this.value);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MethodCallExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MethodCallExpr.java
new file mode 100644
index 0000000..98a2464
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MethodCallExpr.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MethodCallExpr extends Expression implements NodeWithTypeArguments<MethodCallExpr> {
+
+    private Expression scope;
+
+    private List<Type<?>> typeArguments;
+
+    private NameExpr name;
+
+    private List<Expression> args;
+
+    public MethodCallExpr() {
+    }
+
+    public MethodCallExpr(final Expression scope, final String name) {
+        setScope(scope);
+        setName(name);
+    }
+
+    public MethodCallExpr(final Expression scope, final String name, final List<Expression> args) {
+        setScope(scope);
+        setName(name);
+        setArgs(args);
+    }
+
+	public MethodCallExpr(final Range range, final Expression scope, final List<Type<?>> typeArguments, final String name, final List<Expression> args) {
+		super(range);
+		setScope(scope);
+		setTypeArguments(typeArguments);
+		setName(name);
+		setArgs(args);
+	}
+
+    /**
+     * Adds the given argument to the method call.
+     *
+     * @param arg
+     *            argument value
+     */
+    public MethodCallExpr addArgument(Expression arg) {
+        getArgs().add(arg);
+        arg.setParentNode(this);
+        return this;
+    }
+
+    public void addArgument(String arg) {
+        addArgument(new NameExpr(arg));
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<Expression> getArgs() {
+        args = ensureNotNull(args);
+        return args;
+    }
+
+    public String getName() {
+        return name.getName();
+    }
+
+    public NameExpr getNameExpr() {
+        return name;
+    }
+
+    public Expression getScope() {
+        return scope;
+    }
+
+	public void setArgs(final List<Expression> args) {
+		this.args = args;
+		setAsParentNodeOf(this.args);
+	}
+
+    public MethodCallExpr setName(final String name) {
+        setNameExpr(new NameExpr(name));
+        return this;
+    }
+
+    public MethodCallExpr setNameExpr(NameExpr name) {
+        this.name = name;
+        setAsParentNodeOf(this.name);
+        return this;
+    }
+
+    public MethodCallExpr setScope(final Expression scope) {
+        this.scope = scope;
+        setAsParentNodeOf(this.scope);
+        return this;
+    }
+
+    @Override
+    public List<Type<?>> getTypeArguments() {
+        return typeArguments;
+    }
+
+    @Override
+    public MethodCallExpr setTypeArguments(final List<Type<?>> types) {
+        this.typeArguments = types;
+        setAsParentNodeOf(this.typeArguments);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MethodReferenceExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MethodReferenceExpr.java
new file mode 100644
index 0000000..d048ca1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/MethodReferenceExpr.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * Method reference expressions introduced in Java 8 specifically designed to simplify lambda Expressions.
+ * These are some examples:
+ *
+ * System.out::println; 
+ *
+ * (test ? stream.map(String::trim) : stream)::toArray; 
+ * @author Raquel Pau
+ *
+ */
+public class MethodReferenceExpr extends Expression implements NodeWithTypeArguments<MethodReferenceExpr> {
+
+    private Expression scope;
+
+    private List<Type<?>> typeArguments;
+
+    private String identifier;
+
+    public MethodReferenceExpr() {
+    }
+
+    public MethodReferenceExpr(Range range, Expression scope,
+                               List<Type<?>> typeArguments, String identifier) {
+        super(range);
+        setIdentifier(identifier);
+        setScope(scope);
+        setTypeArguments(typeArguments);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getScope() {
+        return scope;
+    }
+
+    public MethodReferenceExpr setScope(Expression scope) {
+        this.scope = scope;
+        setAsParentNodeOf(this.scope);
+        return this;
+    }
+
+    @Override
+    public List<Type<?>> getTypeArguments() {
+        return typeArguments;
+    }
+
+    @Override
+    public MethodReferenceExpr setTypeArguments(final List<Type<?>> types) {
+        this.typeArguments = types;
+        setAsParentNodeOf(this.typeArguments);
+        return this;
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public MethodReferenceExpr setIdentifier(String identifier) {
+        this.identifier = identifier;
+        return this;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NameExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NameExpr.java
new file mode 100644
index 0000000..331fa2a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NameExpr.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class NameExpr extends Expression implements NodeWithName<NameExpr> {
+
+	private String name;
+
+	public NameExpr() {
+	}
+
+	public NameExpr(final String name) {
+		this.name = name;
+	}
+
+	public NameExpr(Range range, final String name) {
+		super(range);
+		this.name = name;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	@Override
+	public final String getName() {
+		return name;
+	}
+
+    @Override
+    public NameExpr setName(final String name) {
+		this.name = name;
+        return this;
+	}
+
+
+	/**
+	 * Creates a new {@link NameExpr} from a qualified name.<br>
+	 * The qualified name can contains "." (dot) characters.
+	 *
+	 * @param qualifiedName
+	 *            qualified name
+	 * @return instanceof {@link NameExpr}
+	 */
+	public static NameExpr name(String qualifiedName) {
+		String[] split = qualifiedName.split("\\.");
+		NameExpr ret = new NameExpr(split[0]);
+		for (int i = 1; i < split.length; i++) {
+			ret = new QualifiedNameExpr(ret, split[i]);
+		}
+		return ret;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NormalAnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NormalAnnotationExpr.java
new file mode 100644
index 0000000..502b11d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NormalAnnotationExpr.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.expr;
+
+import static com.github.javaparser.ast.expr.NameExpr.*;
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class NormalAnnotationExpr extends AnnotationExpr {
+
+    private List<MemberValuePair> pairs;
+
+    public NormalAnnotationExpr() {
+    }
+
+    public NormalAnnotationExpr(final NameExpr name, final List<MemberValuePair> pairs) {
+        setName(name);
+        setPairs(pairs);
+    }
+
+    public NormalAnnotationExpr(final Range range, final NameExpr name, final List<MemberValuePair> pairs) {
+        super(range);
+        setName(name);
+        setPairs(pairs);
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<MemberValuePair> getPairs() {
+        pairs = ensureNotNull(pairs);
+        return pairs;
+    }
+
+    public NormalAnnotationExpr setPairs(final List<MemberValuePair> pairs) {
+        this.pairs = pairs;
+        setAsParentNodeOf(this.pairs);
+        return this;
+    }
+
+    /**
+     * adds a pair to this annotation
+     * 
+     * @return this, the {@link NormalAnnotationExpr}
+     */
+    public NormalAnnotationExpr addPair(String key, String value) {
+        return addPair(key, name(value));
+    }
+
+    /**
+     * adds a pair to this annotation
+     * 
+     * @return this, the {@link NormalAnnotationExpr}
+     */
+    public NormalAnnotationExpr addPair(String key, NameExpr value) {
+        MemberValuePair memberValuePair = new MemberValuePair(key, value);
+        getPairs().add(memberValuePair);
+        memberValuePair.setParentNode(this);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NullLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NullLiteralExpr.java
new file mode 100644
index 0000000..cb0a92b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/NullLiteralExpr.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class NullLiteralExpr extends LiteralExpr {
+
+	public NullLiteralExpr() {
+	}
+
+	public NullLiteralExpr(final Range range) {
+		super(range);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ObjectCreationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ObjectCreationExpr.java
new file mode 100644
index 0000000..4d06ff8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ObjectCreationExpr.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * Defines constructor call expression.
+ * Example:
+ * <code>
+ *     new Object()
+ * </code>
+ *
+ * @author Julio Vilmar Gesser
+ */
+public final class ObjectCreationExpr extends Expression implements 
+        NodeWithTypeArguments<ObjectCreationExpr>,
+        NodeWithType<ObjectCreationExpr> {
+
+    private Expression scope;
+
+    private ClassOrInterfaceType type;
+
+    private List<Type<?>> typeArguments;
+
+    private List<Expression> args;
+
+    // This can be null, to indicate there is no body
+    private List<BodyDeclaration<?>> anonymousClassBody;
+
+    public ObjectCreationExpr() {
+    }
+
+    /**
+     * Defines a call to a constructor.
+     * 
+     * @param scope may be null
+     * @param type this is the class that the constructor is being called for.
+     * @param args Any arguments to pass to the constructor
+     */
+    public ObjectCreationExpr(final Expression scope, final ClassOrInterfaceType type, final List<Expression> args) {
+        setScope(scope);
+        setType(type);
+        setArgs(args);
+    }
+
+	public ObjectCreationExpr(final Range range,
+			final Expression scope, final ClassOrInterfaceType type, final List<Type<?>> typeArguments,
+                              final List<Expression> args, final List<BodyDeclaration<?>> anonymousBody) {
+		super(range);
+		setScope(scope);
+		setType(type);
+		setTypeArguments(typeArguments);
+		setArgs(args);
+		setAnonymousClassBody(anonymousBody);
+	}
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * This can be null, to indicate there is no body
+     */
+    public List<BodyDeclaration<?>> getAnonymousClassBody() {
+        return anonymousClassBody;
+    }
+
+    public void addAnonymousClassBody(BodyDeclaration<?> body) {
+        if (anonymousClassBody == null)
+            anonymousClassBody = new ArrayList<>();
+        anonymousClassBody.add(body);
+        body.setParentNode(this);
+    }
+
+    public List<Expression> getArgs() {
+        args = ensureNotNull(args);
+        return args;
+    }
+
+    public Expression getScope() {
+        return scope;
+    }
+
+    @Override
+    public ClassOrInterfaceType getType() {
+        return type;
+    }
+
+    public ObjectCreationExpr setAnonymousClassBody(final List<BodyDeclaration<?>> anonymousClassBody) {
+        this.anonymousClassBody = anonymousClassBody;
+        setAsParentNodeOf(this.anonymousClassBody);
+        return this;
+    }
+
+    public ObjectCreationExpr setArgs(final List<Expression> args) {
+        this.args = args;
+        setAsParentNodeOf(this.args);
+        return this;
+    }
+
+    public ObjectCreationExpr setScope(final Expression scope) {
+        this.scope = scope;
+        setAsParentNodeOf(this.scope);
+        return this;
+    }
+
+    @Override
+    public ObjectCreationExpr setType(final Type<?> type) {
+        if (!(type instanceof ClassOrInterfaceType))// needed so we can use NodeWithType
+            throw new RuntimeException("You can only add ClassOrInterfaceType to an ObjectCreationExpr");
+        this.type = (ClassOrInterfaceType) type;
+        setAsParentNodeOf(this.type);
+        return this;
+    }
+
+    @Override
+    public List<Type<?>> getTypeArguments() {
+        return typeArguments;
+    }
+
+    @Override
+    public ObjectCreationExpr setTypeArguments(final List<Type<?>> types) {
+        this.typeArguments = types;
+        setAsParentNodeOf(this.typeArguments);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/QualifiedNameExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/QualifiedNameExpr.java
new file mode 100644
index 0000000..dd90631
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/QualifiedNameExpr.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class QualifiedNameExpr extends NameExpr {
+
+	private NameExpr qualifier;
+
+	public QualifiedNameExpr() {
+	}
+
+	public QualifiedNameExpr(final NameExpr scope, final String name) {
+		super(name);
+		setQualifier(scope);
+	}
+
+	public QualifiedNameExpr(final Range range, final NameExpr scope, final String name) {
+		super(range, name);
+		setQualifier(scope);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public NameExpr getQualifier() {
+		return qualifier;
+	}
+
+	public QualifiedNameExpr setQualifier(final NameExpr qualifier) {
+		this.qualifier = qualifier;
+		setAsParentNodeOf(this.qualifier);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java
new file mode 100644
index 0000000..bd6692c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SingleMemberAnnotationExpr extends AnnotationExpr {
+
+	private Expression memberValue;
+
+	public SingleMemberAnnotationExpr() {
+	}
+
+	public SingleMemberAnnotationExpr(final NameExpr name, final Expression memberValue) {
+		setName(name);
+		setMemberValue(memberValue);
+	}
+
+	public SingleMemberAnnotationExpr(final Range range, final NameExpr name, final Expression memberValue) {
+		super(range);
+		setName(name);
+		setMemberValue(memberValue);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getMemberValue() {
+		return memberValue;
+	}
+
+	public SingleMemberAnnotationExpr setMemberValue(final Expression memberValue) {
+		this.memberValue = memberValue;
+		setAsParentNodeOf(this.memberValue);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/StringLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/StringLiteralExpr.java
new file mode 100644
index 0000000..f66a594
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/StringLiteralExpr.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.utils.Utils;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * Java® Language Specification 3.10.5 String Literals
+ * @author Julio Vilmar Gesser
+ */
+public class StringLiteralExpr extends LiteralExpr {
+
+	protected String value;
+
+	public StringLiteralExpr() {
+        this.value = "";
+	}
+
+	public StringLiteralExpr(final String value) {
+        if (value.contains("\n") || value.contains("\r")) {
+            throw new IllegalArgumentException("Illegal literal expression: newlines (line feed or carriage return) have to be escaped");
+        }
+		this.value = value;
+	}
+
+	/**
+	 * Utility method that creates a new StringLiteralExpr. Escapes EOL characters.
+	 */
+	public static StringLiteralExpr escape(String string) {
+		return new StringLiteralExpr(Utils.escapeEndOfLines(string));
+	}
+
+	public StringLiteralExpr(final Range range, final String value) {
+		super(range);
+		this.value = value;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public final String getValue() {
+		return value;
+	}
+
+	public final StringLiteralExpr setValue(final String value) {
+		this.value = value;
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/SuperExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/SuperExpr.java
new file mode 100644
index 0000000..3f5e186
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/SuperExpr.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SuperExpr extends Expression {
+
+	private Expression classExpr;
+
+	public SuperExpr() {
+	}
+
+	public SuperExpr(final Expression classExpr) {
+		setClassExpr(classExpr);
+	}
+
+	public SuperExpr(final Range range, final Expression classExpr) {
+		super(range);
+		setClassExpr(classExpr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getClassExpr() {
+		return classExpr;
+	}
+
+	public SuperExpr setClassExpr(final Expression classExpr) {
+		this.classExpr = classExpr;
+		setAsParentNodeOf(this.classExpr);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ThisExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ThisExpr.java
new file mode 100644
index 0000000..117fed5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/ThisExpr.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ThisExpr extends Expression {
+
+	private Expression classExpr;
+
+	public ThisExpr() {
+	}
+
+	public ThisExpr(final Expression classExpr) {
+		setClassExpr(classExpr);
+	}
+
+	public ThisExpr(final Range range, final Expression classExpr) {
+		super(range);
+		setClassExpr(classExpr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getClassExpr() {
+		return classExpr;
+	}
+
+	public ThisExpr setClassExpr(final Expression classExpr) {
+		this.classExpr = classExpr;
+		setAsParentNodeOf(this.classExpr);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/TypeExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/TypeExpr.java
new file mode 100644
index 0000000..28b14e1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/TypeExpr.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * This class is just instantiated as scopes for MethodReferenceExpr nodes to encapsulate Types.
+ * @author Raquel Pau
+ *
+ */
+public class TypeExpr extends Expression implements NodeWithType<TypeExpr> {
+
+    private Type<?> type;
+
+    public TypeExpr(){}
+
+    public TypeExpr(Range range, Type<?> type) {
+        super(range);
+        setType(type);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public Type<?> getType() {
+        return type;
+    }
+
+    @Override
+    public TypeExpr setType(Type<?> type) {
+        this.type = type;
+        setAsParentNodeOf(this.type);
+        return this;
+    }
+
+
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/UnaryExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/UnaryExpr.java
new file mode 100644
index 0000000..eef9101
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/UnaryExpr.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class UnaryExpr extends Expression {
+
+	public enum Operator {
+		positive, // +
+		negative, // -
+		preIncrement, // ++
+		preDecrement, // --
+		not, // !
+		inverse, // ~
+		posIncrement, // ++
+		posDecrement, // --
+	}
+
+	private Expression expr;
+
+	private Operator op;
+
+	public UnaryExpr() {
+	}
+
+	public UnaryExpr(final Expression expr, final Operator op) {
+		setExpr(expr);
+		setOperator(op);
+	}
+
+	public UnaryExpr(final Range range, final Expression expr, final Operator op) {
+		super(range);
+		setExpr(expr);
+		setOperator(op);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public Operator getOperator() {
+		return op;
+	}
+
+	public UnaryExpr setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+		return this;
+	}
+
+	public UnaryExpr setOperator(final Operator op) {
+		this.op = op;
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/VariableDeclarationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/VariableDeclarationExpr.java
new file mode 100644
index 0000000..5bb0f62
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/expr/VariableDeclarationExpr.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.expr;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+import static java.util.Collections.*;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithElementType;
+import com.github.javaparser.ast.nodeTypes.NodeWithModifiers;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclarationExpr extends Expression implements
+        NodeWithElementType<VariableDeclarationExpr>,
+        NodeWithModifiers<VariableDeclarationExpr>,
+        NodeWithAnnotations<VariableDeclarationExpr>,
+        NodeWithVariables<VariableDeclarationExpr> {
+
+    private EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+
+    private List<AnnotationExpr> annotations;
+
+    private Type elementType;
+
+    private List<VariableDeclarator> variables;
+
+    private List<ArrayBracketPair> arrayBracketPairsAfterType;
+
+    public VariableDeclarationExpr() {
+    }
+
+    public VariableDeclarationExpr(final Type elementType, String variableName) {
+        setElementType(elementType);
+        setVariables(singletonList(new VariableDeclarator(variableName)));
+    }
+
+    public VariableDeclarationExpr(final Type elementType, VariableDeclarator var) {
+        setElementType(elementType);
+        setVariables(singletonList(var));
+    }
+
+    public VariableDeclarationExpr(final Type elementType, String variableName, Modifier... modifiers) {
+        setElementType(elementType);
+        setVariables(singletonList(new VariableDeclarator(variableName)));
+        setModifiers(Arrays.stream(modifiers)
+                .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))));
+    }
+
+    public VariableDeclarationExpr(final Type elementType, VariableDeclarator var, Modifier... modifiers) {
+        setElementType(elementType);
+        setVariables(singletonList(var));
+        setModifiers(Arrays.stream(modifiers)
+                .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))));
+    }
+
+    public VariableDeclarationExpr(final Type elementType, final List<VariableDeclarator> variables) {
+        setElementType(elementType);
+        setVariables(variables);
+    }
+
+    public VariableDeclarationExpr(final EnumSet<Modifier> modifiers, final Type elementType,
+                                   final List<VariableDeclarator> variables) {
+        setModifiers(modifiers);
+        setElementType(elementType);
+        setVariables(variables);
+    }
+
+    public VariableDeclarationExpr(final Range range,
+                                   final EnumSet<Modifier> modifiers, final List<AnnotationExpr> annotations,
+                                   final Type elementType,
+                                   final List<VariableDeclarator> variables,
+                                   final List<ArrayBracketPair> arrayBracketPairsAfterType) {
+        super(range);
+        setModifiers(modifiers);
+        setAnnotations(annotations);
+        setElementType(elementType);
+        setVariables(variables);
+        setArrayBracketPairsAfterElementType(arrayBracketPairsAfterType);
+    }
+
+    /**
+     * Creates a {@link VariableDeclarationExpr}.
+     *
+     * @return instance of {@link VariableDeclarationExpr}
+     */
+    public static VariableDeclarationExpr create(Type type, String name) {
+        return new VariableDeclarationExpr(type, name);
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public List<AnnotationExpr> getAnnotations() {
+        annotations = ensureNotNull(annotations);
+        return annotations;
+    }
+
+    /**
+     * Return the modifiers of this variable declaration.
+     * 
+     * @see Modifier
+     * @return modifiers
+     */
+    @Override
+    public EnumSet<Modifier> getModifiers() {
+        return modifiers;
+    }
+
+    @Override
+    public Type getElementType() {
+        return elementType;
+    }
+
+    @Override
+    public List<VariableDeclarator> getVariables() {
+        variables = ensureNotNull(variables);
+        return variables;
+    }
+
+    @Override
+    public VariableDeclarationExpr setAnnotations(final List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+        setAsParentNodeOf(this.annotations);
+        return this;
+    }
+
+    @Override
+    public VariableDeclarationExpr setModifiers(final EnumSet<Modifier> modifiers) {
+        this.modifiers = modifiers;
+        return this;
+    }
+
+    @Override
+    public VariableDeclarationExpr setElementType(final Type elementType) {
+        this.elementType = elementType;
+        setAsParentNodeOf(this.elementType);
+        return this;
+    }
+
+    @Override
+    public VariableDeclarationExpr setVariables(final List<VariableDeclarator> variables) {
+        this.variables = variables;
+        setAsParentNodeOf(this.variables);
+        return this;
+    }
+
+    public List<ArrayBracketPair> getArrayBracketPairsAfterElementType() {
+        arrayBracketPairsAfterType = ensureNotNull(arrayBracketPairsAfterType);
+        return arrayBracketPairsAfterType;
+    }
+
+    @Override
+    public VariableDeclarationExpr setArrayBracketPairsAfterElementType(List<ArrayBracketPair> arrayBracketPairsAfterType) {
+        this.arrayBracketPairsAfterType = arrayBracketPairsAfterType;
+        setAsParentNodeOf(arrayBracketPairsAfterType);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithAnnotations.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithAnnotations.java
new file mode 100644
index 0000000..71ff717
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithAnnotations.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+
+import static com.github.javaparser.ast.expr.NameExpr.*;
+
+/**
+ * An element which can be the target of annotations.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public interface NodeWithAnnotations<T> {
+    List<AnnotationExpr> getAnnotations();
+
+    T setAnnotations(List<AnnotationExpr> annotations);
+
+    /**
+     * Annotates this
+     * 
+     * @param name the name of the annotation
+     * @return the {@link NormalAnnotationExpr} added
+     */
+    public default NormalAnnotationExpr addAnnotation(String name) {
+        NormalAnnotationExpr normalAnnotationExpr = new NormalAnnotationExpr(
+                name(name), null);
+        getAnnotations().add(normalAnnotationExpr);
+        normalAnnotationExpr.setParentNode((Node) this);
+        return normalAnnotationExpr;
+    }
+
+    /**
+     * Annotates this and automatically add the import
+     * 
+     * @param clazz the class of the annotation
+     * @return the {@link NormalAnnotationExpr} added
+     */
+    public default NormalAnnotationExpr addAnnotation(Class<? extends Annotation> clazz) {
+        ((Node) this).tryAddImportToParentCompilationUnit(clazz);
+        return addAnnotation(clazz.getSimpleName());
+    }
+
+    /**
+     * Annotates this with a marker annotation
+     * 
+     * @param name the name of the annotation
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    public default T addMarkerAnnotation(String name) {
+        MarkerAnnotationExpr markerAnnotationExpr = new MarkerAnnotationExpr(
+                name(name));
+        getAnnotations().add(markerAnnotationExpr);
+        markerAnnotationExpr.setParentNode((Node) this);
+        return (T) this;
+    }
+
+    /**
+     * Annotates this with a marker annotation and automatically add the import
+     * 
+     * @param clazz the class of the annotation
+     * @return this
+     */
+    public default T addMarkerAnnotation(Class<? extends Annotation> clazz) {
+        ((Node) this).tryAddImportToParentCompilationUnit(clazz);
+        return addMarkerAnnotation(clazz.getSimpleName());
+    }
+
+    /**
+     * Annotates this with a single member annotation
+     * 
+     * @param name the name of the annotation
+     * @param value the value, don't forget to add \"\" for a string value
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    public default T addSingleMemberAnnotation(String name, String value) {
+        SingleMemberAnnotationExpr singleMemberAnnotationExpr = new SingleMemberAnnotationExpr(
+                name(name), name(value));
+        getAnnotations().add(singleMemberAnnotationExpr);
+        singleMemberAnnotationExpr.setParentNode((Node) this);
+        return (T) this;
+    }
+
+    /**
+     * Annotates this with a single member annotation and automatically add the import
+     * 
+     * @param clazz the class of the annotation
+     * @param value the value, don't forget to add \"\" for a string value
+     * @return this
+     */
+    public default T addSingleMemberAnnotation(Class<? extends Annotation> clazz,
+                                               String value) {
+        ((Node) this).tryAddImportToParentCompilationUnit(clazz);
+        return addSingleMemberAnnotation(clazz.getSimpleName(), value);
+    }
+
+    /**
+     * Check whether an annotation with this name is present on this element
+     * 
+     * @param annotationName the name of the annotation
+     * @return true if found, false if not
+     */
+    public default boolean isAnnotationPresent(String annotationName) {
+        return getAnnotations().stream().anyMatch(a -> a.getName().getName().equals(annotationName));
+    }
+
+    /**
+     * Check whether an annotation with this class is present on this element
+     * 
+     * @param annotationClass the class of the annotation
+     * @return true if found, false if not
+     */
+    public default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
+        return isAnnotationPresent(annotationClass.getSimpleName());
+    }
+
+    /**
+     * Try to find an annotation by its name
+     * 
+     * @param annotationName the name of the annotation
+     * @return null if not found, the annotation otherwise
+     */
+    public default AnnotationExpr getAnnotationByName(String annotationName) {
+        return getAnnotations().stream().filter(a -> a.getName().getName().equals(annotationName)).findFirst()
+                .orElse(null);
+    }
+
+    /**
+     * Try to find an annotation by its class
+     * 
+     * @param annotationClass the class of the annotation
+     * @return null if not found, the annotation otherwise
+     */
+    public default AnnotationExpr getAnnotationByClass(Class<? extends Annotation> annotationClass) {
+        return getAnnotationByName(annotationClass.getSimpleName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt.java
new file mode 100644
index 0000000..381318b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithBlockStmt.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.stmt.BlockStmt;
+
+public interface NodeWithBlockStmt<T> {
+    BlockStmt getBody();
+
+    T setBody(BlockStmt block);
+
+    default BlockStmt createBody() {
+        BlockStmt block = new BlockStmt();
+        setBody(block);
+        block.setParentNode((Node) this);
+
+        return block;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithBody.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithBody.java
new file mode 100644
index 0000000..2adfe86
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithBody.java
@@ -0,0 +1,18 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+
+public interface NodeWithBody<T> {
+    public Statement getBody();
+
+    public T setBody(final Statement body);
+
+    public default BlockStmt createBlockStatementAsBody() {
+        BlockStmt b = new BlockStmt();
+        b.setParentNode((Node) this);
+        setBody(b);
+        return b;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithDeclaration.java
new file mode 100644
index 0000000..875d28d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithDeclaration.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.nodeTypes;
+
+/**
+ * Element with a declaration representable as a String.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public interface NodeWithDeclaration {
+
+    /**
+     * As {@link NodeWithDeclaration#getDeclarationAsString(boolean, boolean, boolean)} including
+     * the modifiers, the throws clause and the parameters with both type and name.
+     * @return String representation of declaration
+     */
+    String getDeclarationAsString();
+
+    /**
+     * As {@link NodeWithDeclaration#getDeclarationAsString(boolean, boolean, boolean)} including
+     * the parameters with both type and name.
+     * @param includingModifiers flag to include the modifiers (if present) in the string produced
+     * @param includingThrows flag to include the throws clause (if present) in the string produced
+     * @return String representation of declaration based on parameter flags
+     */
+    String getDeclarationAsString(boolean includingModifiers, boolean includingThrows);
+
+    /**
+     * A simple representation of the element declaration.
+     * It should fit one string.
+     * @param includingModifiers flag to include the modifiers (if present) in the string produced
+     * @param includingThrows flag to include the throws clause (if present) in the string produced
+     * @param includingParameterName flag to include the parameter name (while the parameter type is always included) in the string produced
+     * @return String representation of declaration based on parameter flags
+     */
+    String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithElementType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithElementType.java
new file mode 100644
index 0000000..21a41ba
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithElementType.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+
+import java.util.List;
+
+/**
+ * A node having an element type.
+ * In most cases, the element type is simply the type.
+ * In case of arrays, the element type is the type that is inside the deepest nesting:
+ * for int[][][], the element type is int.
+ *
+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with getElementType/setElementType
+ * methods
+ */
+public interface NodeWithElementType<T> {
+    /**
+     * @return the element type
+     */
+    Type<?> getElementType();
+
+    /**
+     * @param elementType the element elementType
+     * @return this
+     */
+    T setElementType(Type<?> elementType);
+
+    List<ArrayBracketPair> getArrayBracketPairsAfterElementType();
+
+    T setArrayBracketPairsAfterElementType(List<ArrayBracketPair> arrayBracketPairsAfterType);
+
+    /**
+     * Sets this type to this class and try to import it to the {@link CompilationUnit} if needed
+     * 
+     * @param typeClass the type
+     * @return this
+     */
+    default T setElementType(Class<?> typeClass) {
+        ((Node) this).tryAddImportToParentCompilationUnit(typeClass);
+        return setElementType(new ClassOrInterfaceType(typeClass.getSimpleName()));
+    }
+
+    default T setElementType(final String type) {
+        ClassOrInterfaceType classOrInterfaceType = new ClassOrInterfaceType(type);
+        return setElementType(classOrInterfaceType);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithExtends.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithExtends.java
new file mode 100644
index 0000000..083fc01
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithExtends.java
@@ -0,0 +1,37 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import java.util.List;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+
+public interface NodeWithExtends<T> {
+    public List<ClassOrInterfaceType> getExtends();
+
+    public T setExtends(final List<ClassOrInterfaceType> extendsList);
+
+    /**
+     * Add an extends to this and automatically add the import
+     * 
+     * @param clazz the class to extand from
+     * @return this
+     */
+    public default T addExtends(Class<?> clazz) {
+        ((Node) this).tryAddImportToParentCompilationUnit(clazz);
+        return addExtends(clazz.getSimpleName());
+    }
+
+    /**
+     * Add an extends to this
+     * 
+     * @param name the name of the type to extends from
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    public default T addExtends(String name) {
+        ClassOrInterfaceType classOrInterfaceType = new ClassOrInterfaceType(name);
+        getExtends().add(classOrInterfaceType);
+        classOrInterfaceType.setParentNode((Node) this);
+        return (T) this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithImplements.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithImplements.java
new file mode 100644
index 0000000..3f51925
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithImplements.java
@@ -0,0 +1,37 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import java.util.List;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+
+public interface NodeWithImplements<T> {
+    public List<ClassOrInterfaceType> getImplements();
+
+    public T setImplements(List<ClassOrInterfaceType> implementsList);
+
+    /**
+     * Add an implements to this
+     * 
+     * @param name the name of the type to extends from
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    public default T addImplements(String name) {
+        ClassOrInterfaceType classOrInterfaceType = new ClassOrInterfaceType(name);
+        getImplements().add(classOrInterfaceType);
+        classOrInterfaceType.setParentNode((Node) this);
+        return (T) this;
+    }
+
+    /**
+     * Add an implements to this and automatically add the import
+     * 
+     * @param clazz the type to implements from
+     * @return this
+     */
+    public default T addImplements(Class<?> clazz) {
+        ((Node) this).tryAddImportToParentCompilationUnit(clazz);
+        return addImplements(clazz.getSimpleName());
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithJavaDoc.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithJavaDoc.java
new file mode 100644
index 0000000..b00cffa
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithJavaDoc.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.comments.JavadocComment;
+
+/**
+ * Node which can be documented through a Javadoc comment.
+ */
+public interface NodeWithJavaDoc<T> {
+    /**
+     * Gets the JavaDoc for this node. You can set the JavaDoc by calling setComment with a JavadocComment.
+     *
+     * @return The JavaDoc for this node if it exists, null if it doesn't.
+     */
+    JavadocComment getJavaDoc();
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    @SuppressWarnings("unchecked")
+    public default T setJavaDocComment(String comment) {
+        ((Node) this).setComment(new JavadocComment(comment));
+        return (T) this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
new file mode 100644
index 0000000..827e5ed
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithMembers.java
@@ -0,0 +1,284 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import static com.github.javaparser.ast.type.VoidType.VOID_TYPE;
+import static java.util.Collections.unmodifiableList;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.stream.Stream;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+
+/**
+ * A node having members.
+ *
+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with a getMembers
+ * method.
+ *
+ */
+public interface NodeWithMembers<T> {
+    List<BodyDeclaration<?>> getMembers();
+
+    T setMembers(List<BodyDeclaration<?>> members);
+
+    /**
+     * Add a field to this and automatically add the import of the type if needed
+     *
+     * @param typeClass the type of the field
+     * @param name the name of the field
+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addField(Class<?> typeClass, String name, Modifier... modifiers) {
+        ((Node) this).tryAddImportToParentCompilationUnit(typeClass);
+        return addField(typeClass.getSimpleName(), name, modifiers);
+    }
+
+    /**
+     * Add a field to this
+     *
+     * @param type the type of the field
+     * @param name the name of the field
+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addField(String type, String name, Modifier... modifiers) {
+        return addField(new ClassOrInterfaceType(type), name, modifiers);
+    }
+
+    /**
+     * Add a field to this
+     *
+     * @param type the type of the field
+     * @param name the name of the field
+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addField(Type<?> type, String name, Modifier... modifiers) {
+        FieldDeclaration fieldDeclaration = new FieldDeclaration();
+        fieldDeclaration.setParentNode((Node) this);
+        VariableDeclarator variable = new VariableDeclarator(new VariableDeclaratorId(name));
+        fieldDeclaration.getVariables().add(variable);
+        variable.setParentNode(fieldDeclaration);
+        fieldDeclaration.setModifiers(Arrays.stream(modifiers)
+                .collect(toCollection(() -> EnumSet.noneOf(Modifier.class))));
+        variable.setType(type);
+        getMembers().add(fieldDeclaration);
+        return fieldDeclaration;
+    }
+
+    /**
+     * Add a private field to this
+     *
+     * @param typeClass the type of the field
+     * @param name the name of the field
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addPrivateField(Class<?> typeClass, String name) {
+        return addField(typeClass, name, Modifier.PRIVATE);
+    }
+
+    /**
+     * Add a private field to this and automatically add the import of the type if
+     * needed
+     *
+     * @param type the type of the field
+     * @param name the name of the field
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addPrivateField(String type, String name) {
+        return addField(type, name, Modifier.PRIVATE);
+    }
+
+    /**
+     * Add a public field to this
+     * 
+     * @param typeClass the type of the field
+     * @param name the name of the field
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addPublicField(Class<?> typeClass, String name) {
+        return addField(typeClass, name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add a public field to this and automatically add the import of the type if
+     * needed
+     *
+     * @param type the type of the field
+     * @param name the name of the field
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addPublicField(String type, String name) {
+        return addField(type, name, Modifier.PUBLIC);
+    }
+
+    /**
+     * Add a protected field to this
+     *
+     * @param typeClass the type of the field
+     * @param name the name of the field
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addProtectedField(Class<?> typeClass, String name) {
+        return addField(typeClass, name, Modifier.PROTECTED);
+    }
+
+    /**
+     * Add a protected field to this and automatically add the import of the type
+     * if needed
+     *
+     * @param type the type of the field
+     * @param name the name of the field
+     * @return the {@link FieldDeclaration} created
+     */
+    default FieldDeclaration addProtectedField(String type, String name) {
+        return addField(type, name, Modifier.PROTECTED);
+    }
+
+    /**
+     * Adds a methods with void return by default to this
+     *
+     * @param methodName the method name
+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}
+     * @return the {@link MethodDeclaration} created
+     */
+    default MethodDeclaration addMethod(String methodName, Modifier... modifiers) {
+        MethodDeclaration methodDeclaration = new MethodDeclaration();
+        methodDeclaration.setName(methodName);
+        methodDeclaration.setType(VOID_TYPE);
+        methodDeclaration.setModifiers(Arrays.stream(modifiers)
+                .collect(toCollection(() -> EnumSet.noneOf(Modifier.class))));
+        getMembers().add(methodDeclaration);
+        methodDeclaration.setParentNode((Node) this);
+        return methodDeclaration;
+    }
+
+    /**
+     * Adds a constructor to this
+     * 
+     * @param modifiers the modifiers like {@link Modifier#PUBLIC}
+     * @return the {@link MethodDeclaration} created
+     */
+    default ConstructorDeclaration addCtor(Modifier... modifiers) {
+        ConstructorDeclaration constructorDeclaration = new ConstructorDeclaration();
+        constructorDeclaration.setModifiers(Arrays.stream(modifiers)
+                .collect(toCollection(() -> EnumSet.noneOf(Modifier.class))));
+        constructorDeclaration.setName(((TypeDeclaration<?>) this).getName());
+        getMembers().add(constructorDeclaration);
+        constructorDeclaration.setParentNode((Node) this);
+        return constructorDeclaration;
+    }
+
+    default BlockStmt addInitializer() {
+        BlockStmt block = new BlockStmt();
+        InitializerDeclaration initializerDeclaration = new InitializerDeclaration(false, block);
+        getMembers().add(initializerDeclaration);
+        initializerDeclaration.setParentNode((Node) this);
+        return block;
+    }
+
+    default BlockStmt addStaticInitializer() {
+        BlockStmt block = new BlockStmt();
+        InitializerDeclaration initializerDeclaration = new InitializerDeclaration(true, block);
+        getMembers().add(initializerDeclaration);
+        initializerDeclaration.setParentNode((Node) this);
+        return block;
+    }
+
+    /**
+     * Try to find a {@link MethodDeclaration} by its name
+     *
+     * @param name the name of the method
+     * @return the methods found (multiple in case of polymorphism)
+     */
+    default List<MethodDeclaration> getMethodsByName(String name) {
+        return getMembers().stream()
+                .filter(m -> m instanceof MethodDeclaration && ((MethodDeclaration) m).getName().equals(name))
+                .map(m -> (MethodDeclaration) m).collect(toList());
+    }
+
+    /**
+     * Find all methods in the members of this node.
+     *
+     * @return the methods found. This list is immutable.
+     */
+    default List<MethodDeclaration> getMethods() {
+        return unmodifiableList(getMembers().stream()
+                .filter(m -> m instanceof MethodDeclaration)
+                .map(m -> (MethodDeclaration) m)
+                .collect(toList()));
+    }
+
+    /**
+     * Try to find a {@link MethodDeclaration} by its parameters types
+     *
+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br>
+     *            void foo(Map&lt;Integer,String&gt; myMap,int number)
+     * @return the methods found (multiple in case of polymorphism)
+     */
+    default List<MethodDeclaration> getMethodsByParameterTypes(String... paramTypes) {
+        return getMembers().stream()
+                .filter(m -> m instanceof MethodDeclaration
+                        && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString())
+                                .collect(toSet()).equals(Stream.of(paramTypes).collect(toSet())))
+                .map(m -> (MethodDeclaration) m).collect(toList());
+    }
+
+    /**
+     * Try to find a {@link MethodDeclaration} by its parameters types
+     *
+     * @param paramTypes the types of parameters like "Map&lt;Integer,String&gt;","int" to match<br>
+     *            void foo(Map&lt;Integer,String&gt; myMap,int number)
+     * @return the methods found (multiple in case of polymorphism)
+     */
+    default List<MethodDeclaration> getMethodsByParameterTypes(Class<?>... paramTypes) {
+        return getMembers().stream()
+                .filter(m -> m instanceof MethodDeclaration
+                        && ((MethodDeclaration) m).getParameters().stream().map(p -> p.getType().toString())
+                                .collect(toSet())
+                                .equals(Stream.of(paramTypes).map(Class::getSimpleName).collect(toSet())))
+                .map(m -> (MethodDeclaration) m).collect(toList());
+    }
+
+    /**
+     * Try to find a {@link FieldDeclaration} by its name
+     *
+     * @param name the name of the field
+     * @return null if not found, the FieldDeclaration otherwise
+     */
+    default FieldDeclaration getFieldByName(String name) {
+        return (FieldDeclaration) getMembers().stream()
+                .filter(m -> m instanceof FieldDeclaration && ((FieldDeclaration) m).getVariables().stream()
+                        .anyMatch(var -> var.getId().getName().equals(name)))
+                .findFirst().orElse(null);
+    }
+
+    /**
+	 * Find all fields in the members of this node.
+     *
+	 * @return the fields found. This list is immutable.
+     */
+    default List<FieldDeclaration> getFields() {
+        return unmodifiableList(getMembers().stream()
+                .filter(m -> m instanceof FieldDeclaration )
+                .map(m -> (FieldDeclaration) m)
+                .collect(toList()));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithModifiers.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithModifiers.java
new file mode 100644
index 0000000..6a1959e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithModifiers.java
@@ -0,0 +1,73 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.stream.Collectors;
+
+import com.github.javaparser.ast.Modifier;
+
+/**
+ * A Node with Modifiers.
+ */
+public interface NodeWithModifiers<T> {
+    /**
+     * Return the modifiers of this variable declaration.
+     *
+     * @see Modifier
+     * @return modifiers
+     */
+    EnumSet<Modifier> getModifiers();
+
+    T setModifiers(EnumSet<Modifier> modifiers);
+
+    @SuppressWarnings("unchecked")
+    default T addModifier(Modifier... modifiers) {
+        getModifiers().addAll(Arrays.stream(modifiers)
+                .collect(Collectors.toCollection(() -> EnumSet.noneOf(Modifier.class))));
+        return (T) this;
+    }
+
+    default boolean isStatic() {
+        return getModifiers().contains(Modifier.STATIC);
+    }
+
+    default boolean isAbstract() {
+        return getModifiers().contains(Modifier.ABSTRACT);
+    }
+
+    default boolean isFinal() {
+        return getModifiers().contains(Modifier.FINAL);
+    }
+
+    default boolean isNative() {
+        return getModifiers().contains(Modifier.NATIVE);
+    }
+
+    default boolean isPrivate() {
+        return getModifiers().contains(Modifier.PRIVATE);
+    }
+
+    default boolean isProtected() {
+        return getModifiers().contains(Modifier.PROTECTED);
+    }
+
+    default boolean isPublic() {
+        return getModifiers().contains(Modifier.PUBLIC);
+    }
+
+    default boolean isStrictfp() {
+        return getModifiers().contains(Modifier.STRICTFP);
+    }
+
+    default boolean isSynchronized() {
+        return getModifiers().contains(Modifier.SYNCHRONIZED);
+    }
+
+    default boolean isTransient() {
+        return getModifiers().contains(Modifier.TRANSIENT);
+    }
+
+    default boolean isVolatile() {
+        return getModifiers().contains(Modifier.VOLATILE);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithName.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithName.java
new file mode 100644
index 0000000..edcff5c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithName.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+/**
+ * A node having a name.
+ *  
+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with a getName method.
+ * 
+ * @since 2.0.1 
+ */
+public interface NodeWithName<T> {
+    String getName();
+
+    T setName(String name);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithParameters.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithParameters.java
new file mode 100644
index 0000000..fb8697f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithParameters.java
@@ -0,0 +1,100 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import java.util.List;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+
+public interface NodeWithParameters<T> {
+    List<Parameter> getParameters();
+
+    T setParameters(List<Parameter> parameters);
+
+    default T addParameter(Type type, String name) {
+        return addParameter(new Parameter(type, new VariableDeclaratorId(name)));
+    }
+
+    default T addParameter(Class<?> paramClass, String name) {
+        ((Node) this).tryAddImportToParentCompilationUnit(paramClass);
+        return addParameter(new ClassOrInterfaceType(paramClass.getSimpleName()), name);
+    }
+
+    /**
+     * Remember to import the class in the compilation unit yourself
+     * 
+     * @param className the name of the class, ex : org.test.Foo or Foo if you added manually the import
+     * @param name the name of the parameter
+     */
+    default T addParameter(String className, String name) {
+        return addParameter(new ClassOrInterfaceType(className), name);
+    }
+
+    @SuppressWarnings("unchecked")
+    default T addParameter(Parameter parameter) {
+        getParameters().add(parameter);
+        parameter.setParentNode((Node) this);
+        return (T) this;
+    }
+
+    default Parameter addAndGetParameter(Type type, String name) {
+        return addAndGetParameter(new Parameter(type, new VariableDeclaratorId(name)));
+    }
+
+    default Parameter addAndGetParameter(Class<?> paramClass, String name) {
+        ((Node) this).tryAddImportToParentCompilationUnit(paramClass);
+        return addAndGetParameter(new ClassOrInterfaceType(paramClass.getSimpleName()), name);
+    }
+
+    /**
+     * Remember to import the class in the compilation unit yourself
+     * 
+     * @param className the name of the class, ex : org.test.Foo or Foo if you added manually the import
+     * @param name the name of the parameter
+     * @return the {@link Parameter} created
+     */
+    default Parameter addAndGetParameter(String className, String name) {
+        return addAndGetParameter(new ClassOrInterfaceType(className), name);
+    }
+
+    default Parameter addAndGetParameter(Parameter parameter) {
+        getParameters().add(parameter);
+        parameter.setParentNode((Node) this);
+        return parameter;
+    }
+
+    /**
+     * Try to find a {@link Parameter} by its name
+     * 
+     * @param name the name of the param
+     * @return null if not found, the param found otherwise
+     */
+    default Parameter getParamByName(String name) {
+        return getParameters().stream()
+                .filter(p -> p.getName().equals(name)).findFirst().orElse(null);
+    }
+
+    /**
+     * Try to find a {@link Parameter} by its type
+     * 
+     * @param type the type of the param
+     * @return null if not found, the param found otherwise
+     */
+    default Parameter getParamByType(String type) {
+        return getParameters().stream()
+                .filter(p -> p.getType().toString().equals(type)).findFirst().orElse(null);
+    }
+
+    /**
+     * Try to find a {@link Parameter} by its type
+     * 
+     * @param type the type of the param <b>take care about generics, it wont work</b>
+     * @return null if not found, the param found otherwise
+     */
+    default Parameter getParamByType(Class<?> type) {
+        return getParameters().stream()
+                .filter(p -> p.getType().toString().equals(type.getSimpleName())).findFirst().orElse(null);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithStatements.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithStatements.java
new file mode 100644
index 0000000..b6c895e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithStatements.java
@@ -0,0 +1,46 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import java.util.List;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.Statement;
+
+public interface NodeWithStatements<T> {
+    public List<Statement> getStmts();
+
+    public T setStmts(final List<Statement> stmts);
+
+    @SuppressWarnings("unchecked")
+    public default T addStatement(Statement statement) {
+        getStmts().add(statement);
+        statement.setParentNode((Node) this);
+        return (T) this;
+    }
+
+    @SuppressWarnings("unchecked")
+    public default T addStatement(int index, final Statement statement) {
+        getStmts().add(index, statement);
+        statement.setParentNode((Node) this);
+        return (T) this;
+    }
+
+    public default T addStatement(Expression expr) {
+        ExpressionStmt statement = new ExpressionStmt(expr);
+        expr.setParentNode(statement);
+        return addStatement(statement);
+    }
+
+    public default T addStatement(String statement) {
+        return addStatement(new NameExpr(statement));
+    }
+
+    public default T addStatement(int index, final Expression expr) {
+        Statement stmt = new ExpressionStmt(expr);
+        expr.setParentNode(stmt);
+        return addStatement(index, stmt);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithThrowable.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithThrowable.java
new file mode 100644
index 0000000..beee9e7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithThrowable.java
@@ -0,0 +1,57 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import java.util.List;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.ReferenceType;
+
+public interface NodeWithThrowable<T> {
+    T setThrows(List<ReferenceType> throws_);
+
+    List<ReferenceType> getThrows();
+
+    /**
+     * Adds this type to the throws clause
+     * 
+     * @param throwType the exception type
+     * @return this
+     */
+    @SuppressWarnings("unchecked")
+    default T addThrows(ReferenceType throwType) {
+        getThrows().add(throwType);
+        throwType.setParentNode((Node) this);
+        return (T) this;
+    }
+
+    /**
+     * Adds this class to the throws clause
+     * 
+     * @param clazz the exception class
+     * @return this
+     */
+    default T addThrows(Class<? extends Throwable> clazz) {
+        ((Node) this).tryAddImportToParentCompilationUnit(clazz);
+        return addThrows(new ClassOrInterfaceType(clazz.getSimpleName()));
+    }
+
+    /**
+     * Check whether this elements throws this exception class
+     * 
+     * @param clazz the class of the exception
+     * @return true if found in throws clause, false if not
+     */
+    public default boolean isThrows(Class<? extends Throwable> clazz) {
+        return isThrows(clazz.getSimpleName());
+    }
+
+    /**
+     * Check whether this elements throws this exception class
+     * 
+     * @param throwableName the class of the exception
+     * @return true if found in throws clause, false if not
+     */
+    public default boolean isThrows(String throwableName) {
+        return getThrows().stream().anyMatch(t -> t.toString().equals(throwableName));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithType.java
new file mode 100644
index 0000000..fc183b2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithType.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+
+/**
+ * A node having a type.
+ *
+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with getType/setType
+ * methods
+ *
+ * @since 2.3.1
+ */
+public interface NodeWithType<T> {
+    /**
+     * Gets the type
+     * 
+     * @return the type
+     */
+    Type<?> getType();
+
+    /**
+     * Sets the type
+     * 
+     * @param type the type
+     * @return this
+     */
+    T setType(Type<?> type);
+
+    /**
+     * Sets this type to this class and try to import it to the {@link CompilationUnit} if needed
+     * 
+     * @param typeClass the type
+     * @return this
+     */
+    default T setType(Class<?> typeClass) {
+        ((Node) this).tryAddImportToParentCompilationUnit(typeClass);
+        return setType(new ClassOrInterfaceType(typeClass.getSimpleName()));
+    }
+
+    default T setType(final String type) {
+        ClassOrInterfaceType classOrInterfaceType = new ClassOrInterfaceType(type);
+        return setType(classOrInterfaceType);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments.java
new file mode 100644
index 0000000..3ce2797
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithTypeArguments.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.type.Type;
+
+import java.util.*;
+
+import static com.github.javaparser.utils.Utils.arrayToList;
+
+/**
+ * A node that can have type arguments.
+ * <pre>
+ *     new X();        --> typeArguments == null
+ *     new X&lt;>();      --> typeArguments.types = [], typeArguments.diamondOperator=true 
+ *     new X&lt;C,D>();   --> typeArguments.types = [C,D], typeArguments.diamondOperator=false 
+ * </pre>
+ */
+public interface NodeWithTypeArguments<T> {
+    /**
+     * @return the types that can be found in the type arguments: &lt;String, Integer>.
+     */
+    List<Type<?>> getTypeArguments();
+
+    /**
+     * Allows you to set the generic arguments
+     * @param typeArguments The list of types of the generics
+     */
+    T setTypeArguments(List<Type<?>> typeArguments);
+
+    /**
+     * @return whether the type arguments look like &lt;>.
+     */
+    default boolean isUsingDiamondOperator() {
+        if(getTypeArguments()==null){
+            return false;
+        }
+        return getTypeArguments().isEmpty();
+    }
+
+    /**
+     * Sets the type arguments to &lt>.
+     */
+    default T setDiamondOperator() {
+        final List<Type<?>> empty = new LinkedList<>();
+        setTypeArguments(empty);
+        return (T) this;
+    }
+
+    /**
+     * Removes all type arguments, including the surrounding &lt;>.
+     */
+    default T removeTypeArguments() {
+        setTypeArguments((List<Type<?>>) null);
+        return (T) this;
+    }
+
+    default T setTypeArguments(Type<?>... typeArguments) {
+        setTypeArguments(arrayToList(typeArguments));
+        return (T) this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java
new file mode 100644
index 0000000..2c6702a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/nodeTypes/NodeWithVariables.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+
+import java.util.List;
+
+/**
+ * A node which has a list of variables.
+ */
+public interface NodeWithVariables<T> {
+    List<VariableDeclarator> getVariables();
+
+    T setVariables(List<VariableDeclarator> variables);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/AssertStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/AssertStmt.java
new file mode 100644
index 0000000..85a34a8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/AssertStmt.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AssertStmt extends Statement {
+
+	private Expression check;
+
+	private Expression msg;
+
+	public AssertStmt() {
+	}
+
+	public AssertStmt(final Expression check) {
+		setCheck(check);
+	}
+
+	public AssertStmt(final Expression check, final Expression msg) {
+		setCheck(check);
+		setMessage(msg);
+	}
+
+	public AssertStmt(final Range range, final Expression check, final Expression msg) {
+		super(range);
+		
+		setCheck(check);
+		setMessage(msg);
+		
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getCheck() {
+		return check;
+	}
+
+	public Expression getMessage() {
+		return msg;
+	}
+
+	public AssertStmt setCheck(final Expression check) {
+		this.check = check;
+		setAsParentNodeOf(this.check);
+		return this;
+	}
+
+	public AssertStmt setMessage(final Expression msg) {
+		this.msg = msg;
+		setAsParentNodeOf(this.msg);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/BlockStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/BlockStmt.java
new file mode 100644
index 0000000..31cbfa3
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/BlockStmt.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.stmt;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.List;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BlockStmt extends Statement implements NodeWithStatements<BlockStmt> {
+
+    private List<Statement> stmts;
+
+    public BlockStmt() {
+    }
+
+    public BlockStmt(final List<Statement> stmts) {
+        setStmts(stmts);
+    }
+
+    public BlockStmt(final Range range, final List<Statement> stmts) {
+        super(range);
+        setStmts(stmts);
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public List<Statement> getStmts() {
+        stmts = ensureNotNull(stmts);
+        return stmts;
+    }
+
+    @Override
+    public BlockStmt setStmts(final List<Statement> stmts) {
+        this.stmts = stmts;
+        setAsParentNodeOf(this.stmts);
+        return this;
+    }
+
+
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/BreakStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/BreakStmt.java
new file mode 100644
index 0000000..04c39fb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/BreakStmt.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BreakStmt extends Statement {
+
+	private String id;
+
+	public BreakStmt() {
+	}
+
+	public BreakStmt(final String id) {
+		this.id = id;
+	}
+
+	public BreakStmt(final Range range, final String id) {
+		super(range);
+		this.id = id;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public BreakStmt setId(final String id) {
+		this.id = id;
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/CatchClause.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/CatchClause.java
new file mode 100644
index 0000000..a1f3005
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/CatchClause.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.EnumSet;
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class CatchClause extends Node implements NodeWithBlockStmt<CatchClause> {
+
+    private Parameter param;
+
+    private BlockStmt catchBlock;
+
+    public CatchClause() {
+    }
+
+    public CatchClause(final Parameter param, final BlockStmt catchBlock) {
+        setParam(param);
+        setBody(catchBlock);
+    }
+
+    public CatchClause(final Range range,
+                       final EnumSet<Modifier> exceptModifier, 
+                       final List<AnnotationExpr> exceptAnnotations,
+                       final Type exceptType,
+                       final VariableDeclaratorId exceptId, 
+                       final BlockStmt catchBlock) {
+        super(range);
+        setParam(new Parameter(range, exceptModifier, exceptAnnotations, exceptType, null, false, exceptId));
+        setBody(catchBlock);
+    }
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+    /**
+     * Use {@link #getBody()} instead
+     */
+    @Deprecated
+	public BlockStmt getCatchBlock() {
+		return catchBlock;
+	}
+
+	/**
+	 * Note that the type of the Parameter can be a UnionType. In this case, any annotations found at the start of the catch(@X A a |...)
+	 * are found directly in the Parameter. Annotations that are on the second or later type - catch(A a | @X B b ...) are found on those types.
+	 */
+	public Parameter getParam() {
+		return param;
+	}
+
+    /**
+     * Use {@link #setBody(BlockStmt)} instead
+     * 
+     * @param catchBlock
+     */
+    @Deprecated
+	public CatchClause setCatchBlock(final BlockStmt catchBlock) {
+		this.catchBlock = catchBlock;
+		setAsParentNodeOf(this.catchBlock);
+        return this;
+	}
+
+	public CatchClause setParam(final Parameter param) {
+		this.param = param;
+		setAsParentNodeOf(this.param);
+        return this;
+	}
+
+    @Override
+    public BlockStmt getBody() {
+        return catchBlock;
+    }
+
+    @Override
+    public CatchClause setBody(BlockStmt block) {
+        this.catchBlock = block;
+        setAsParentNodeOf(this.catchBlock);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ContinueStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ContinueStmt.java
new file mode 100644
index 0000000..4ba7faa
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ContinueStmt.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ContinueStmt extends Statement {
+
+	private String id;
+
+	public ContinueStmt() {
+	}
+
+	public ContinueStmt(final String id) {
+		this.id = id;
+	}
+
+	public ContinueStmt(Range range, final String id) {
+		super(range);
+		this.id = id;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public ContinueStmt setId(final String id) {
+		this.id = id;
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/DoStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/DoStmt.java
new file mode 100644
index 0000000..8f293ec
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/DoStmt.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class DoStmt extends Statement implements NodeWithBody<DoStmt> {
+
+	private Statement body;
+
+	private Expression condition;
+
+	public DoStmt() {
+	}
+
+	public DoStmt(final Statement body, final Expression condition) {
+		setBody(body);
+		setCondition(condition);
+	}
+
+	public DoStmt(Range range, final Statement body, final Expression condition) {
+		super(range);
+		setBody(body);
+		setCondition(condition);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	@Override
+    public Statement getBody() {
+		return body;
+	}
+
+	public Expression getCondition() {
+		return condition;
+	}
+
+	@Override
+    public DoStmt setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+        return this;
+	}
+
+	public DoStmt setCondition(final Expression condition) {
+		this.condition = condition;
+		setAsParentNodeOf(this.condition);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/EmptyStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/EmptyStmt.java
new file mode 100644
index 0000000..0070980
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/EmptyStmt.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EmptyStmt extends Statement {
+
+	public EmptyStmt() {
+	}
+
+	public EmptyStmt(Range range) {
+		super(range);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java
new file mode 100644
index 0000000..e29205b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ExplicitConstructorInvocationStmt extends Statement implements NodeWithTypeArguments<ExplicitConstructorInvocationStmt> {
+
+    private List<Type<?>> typeArguments;
+
+    private boolean isThis;
+
+	private Expression expr;
+
+	private List<Expression> args;
+
+	public ExplicitConstructorInvocationStmt() {
+	}
+
+	public ExplicitConstructorInvocationStmt(final boolean isThis,
+			final Expression expr, final List<Expression> args) {
+		setThis(isThis);
+		setExpr(expr);
+		setArgs(args);
+	}
+
+	public ExplicitConstructorInvocationStmt(Range range,
+	                                         final List<Type<?>> typeArguments, final boolean isThis,
+	                                         final Expression expr, final List<Expression> args) {
+		super(range);
+		setTypeArguments(typeArguments);
+		setThis(isThis);
+		setExpr(expr);
+		setArgs(args);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<Expression> getArgs() {
+        args = ensureNotNull(args);
+        return args;
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public boolean isThis() {
+		return isThis;
+	}
+
+	public ExplicitConstructorInvocationStmt setArgs(final List<Expression> args) {
+		this.args = args;
+		setAsParentNodeOf(this.args);
+		return this;
+	}
+
+	public ExplicitConstructorInvocationStmt setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+		return this;
+	}
+
+	public ExplicitConstructorInvocationStmt setThis(final boolean isThis) {
+		this.isThis = isThis;
+		return this;
+	}
+
+    @Override
+    public List<Type<?>> getTypeArguments() {
+        return typeArguments;
+    }
+
+    @Override
+    public ExplicitConstructorInvocationStmt setTypeArguments(final List<Type<?>> types) {
+        this.typeArguments = types;
+        setAsParentNodeOf(this.typeArguments);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ExpressionStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ExpressionStmt.java
new file mode 100644
index 0000000..72d8a2e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ExpressionStmt.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ExpressionStmt extends Statement {
+
+	private Expression expr;
+
+	public ExpressionStmt() {
+	}
+
+	public ExpressionStmt(final Expression expr) {
+		setExpression(expr);
+	}
+
+	public ExpressionStmt(Range range,
+	                      final Expression expr) {
+		super(range);
+		setExpression(expr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpression() {
+		return expr;
+	}
+
+	public ExpressionStmt setExpression(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ForStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ForStmt.java
new file mode 100644
index 0000000..52baddb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ForStmt.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ForStmt extends Statement implements NodeWithBody<ForStmt> {
+
+	private List<Expression> init;
+
+	private Expression compare;
+
+	private List<Expression> update;
+
+	private Statement body;
+
+	public ForStmt() {
+	}
+
+	public ForStmt(final List<Expression> init, final Expression compare,
+			final List<Expression> update, final Statement body) {
+		setCompare(compare);
+		setInit(init);
+		setUpdate(update);
+		setBody(body);
+	}
+
+	public ForStmt(Range range,
+	               final List<Expression> init, final Expression compare,
+	               final List<Expression> update, final Statement body) {
+		super(range);
+		setCompare(compare);
+		setInit(init);
+		setUpdate(update);
+		setBody(body);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	@Override
+    public Statement getBody() {
+		return body;
+	}
+
+	public Expression getCompare() {
+		return compare;
+	}
+
+	public List<Expression> getInit() {
+        init = ensureNotNull(init);
+        return init;
+	}
+
+	public List<Expression> getUpdate() {
+        update = ensureNotNull(update);
+        return update;
+	}
+
+	@Override
+    public ForStmt setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+        return this;
+	}
+
+	public ForStmt setCompare(final Expression compare) {
+		this.compare = compare;
+		setAsParentNodeOf(this.compare);
+		return this;
+	}
+
+	public ForStmt setInit(final List<Expression> init) {
+		this.init = init;
+		setAsParentNodeOf(this.init);
+		return this;
+	}
+
+	public ForStmt setUpdate(final List<Expression> update) {
+		this.update = update;
+		setAsParentNodeOf(this.update);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ForeachStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ForeachStmt.java
new file mode 100644
index 0000000..3a94572
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ForeachStmt.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ForeachStmt extends Statement implements NodeWithBody<ForeachStmt> {
+
+	private VariableDeclarationExpr var;
+
+	private Expression iterable;
+
+	private Statement body;
+
+	public ForeachStmt() {
+	}
+
+	public ForeachStmt(final VariableDeclarationExpr var,
+			final Expression iterable, final Statement body) {
+		setVariable(var);
+		setIterable(iterable);
+		setBody(body);
+	}
+
+	public ForeachStmt(Range range,
+	                   final VariableDeclarationExpr var, final Expression iterable,
+	                   final Statement body) {
+		super(range);
+		setVariable(var);
+		setIterable(iterable);
+		setBody(body);
+	}
+
+    /**
+     * Will create a {@link NameExpr} with the iterable param
+     * 
+     * @param var
+     * @param iterable
+     * @param body
+     */
+    public ForeachStmt(VariableDeclarationExpr var, String iterable, BlockStmt body) {
+        setVariable(var);
+        setIterable(new NameExpr(iterable));
+        setBody(body);
+    }
+
+    @Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	@Override
+    public Statement getBody() {
+		return body;
+	}
+
+	public Expression getIterable() {
+		return iterable;
+	}
+
+	public VariableDeclarationExpr getVariable() {
+		return var;
+	}
+
+	@Override
+    public ForeachStmt setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+        return this;
+	}
+
+	public ForeachStmt setIterable(final Expression iterable) {
+		this.iterable = iterable;
+		setAsParentNodeOf(this.iterable);
+		return this;
+	}
+
+	public ForeachStmt setVariable(final VariableDeclarationExpr var) {
+		this.var = var;
+		setAsParentNodeOf(this.var);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/IfStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/IfStmt.java
new file mode 100644
index 0000000..ace3ec8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/IfStmt.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class IfStmt extends Statement {
+
+	private Expression condition;
+
+	private Statement thenStmt;
+
+	private Statement elseStmt;
+
+	public IfStmt() {
+	}
+
+	public IfStmt(final Expression condition, final Statement thenStmt, final Statement elseStmt) {
+		setCondition(condition);
+		setThenStmt(thenStmt);
+		setElseStmt(elseStmt);
+	}
+
+	public IfStmt(Range range,
+	              final Expression condition, final Statement thenStmt, final Statement elseStmt) {
+		super(range);
+		setCondition(condition);
+		setThenStmt(thenStmt);
+		setElseStmt(elseStmt);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getCondition() {
+		return condition;
+	}
+
+	public Statement getElseStmt() {
+		return elseStmt;
+	}
+
+	public Statement getThenStmt() {
+		return thenStmt;
+	}
+
+	public IfStmt setCondition(final Expression condition) {
+		this.condition = condition;
+		setAsParentNodeOf(this.condition);
+		return this;
+	}
+
+	public IfStmt setElseStmt(final Statement elseStmt) {
+		this.elseStmt = elseStmt;
+		setAsParentNodeOf(this.elseStmt);
+		return this;
+	}
+
+	public IfStmt setThenStmt(final Statement thenStmt) {
+		this.thenStmt = thenStmt;
+		setAsParentNodeOf(this.thenStmt);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/LabeledStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/LabeledStmt.java
new file mode 100644
index 0000000..ded1ad8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/LabeledStmt.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class LabeledStmt extends Statement {
+
+	private String label;
+
+	private Statement stmt;
+
+	public LabeledStmt() {
+	}
+
+	public LabeledStmt(final String label, final Statement stmt) {
+		setLabel(label);
+		setStmt(stmt);
+	}
+
+	public LabeledStmt(Range range, final String label, final Statement stmt) {
+		super(range);
+		setLabel(label);
+		setStmt(stmt);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getLabel() {
+		return label;
+	}
+
+	public Statement getStmt() {
+		return stmt;
+	}
+
+	public LabeledStmt setLabel(final String label) {
+		this.label = label;
+		return this;
+	}
+
+	public LabeledStmt setStmt(final Statement stmt) {
+		this.stmt = stmt;
+		setAsParentNodeOf(this.stmt);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ReturnStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ReturnStmt.java
new file mode 100644
index 0000000..6ce31d0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ReturnStmt.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ReturnStmt extends Statement {
+
+	private Expression expr;
+
+	public ReturnStmt() {
+	}
+
+	public ReturnStmt(final Expression expr) {
+		setExpr(expr);
+	}
+
+	public ReturnStmt(Range range, final Expression expr) {
+		super(range);
+		setExpr(expr);
+	}
+
+    /**
+     * Will create a NameExpr with the string param
+     * 
+     * @param expr
+     */
+    public ReturnStmt(String expr) {
+        setExpr(new NameExpr(expr));
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public ReturnStmt setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/Statement.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/Statement.java
new file mode 100644
index 0000000..eacfcc4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/Statement.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Statement extends Node {
+
+	public Statement() {
+	}
+
+	public Statement(final Range range) {
+		super(range);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SwitchEntryStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SwitchEntryStmt.java
new file mode 100644
index 0000000..e17e20e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SwitchEntryStmt.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithStatements;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SwitchEntryStmt extends Statement implements NodeWithStatements<SwitchEntryStmt> {
+
+	private Expression label;
+
+	private List<Statement> stmts;
+
+	public SwitchEntryStmt() {
+	}
+
+	public SwitchEntryStmt(final Expression label, final List<Statement> stmts) {
+		setLabel(label);
+		setStmts(stmts);
+	}
+
+	public SwitchEntryStmt(Range range, final Expression label,
+	                       final List<Statement> stmts) {
+		super(range);
+		setLabel(label);
+		setStmts(stmts);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getLabel() {
+		return label;
+	}
+
+	@Override
+    public List<Statement> getStmts() {
+        stmts = ensureNotNull(stmts);
+        return stmts;
+	}
+
+	public SwitchEntryStmt setLabel(final Expression label) {
+		this.label = label;
+		setAsParentNodeOf(this.label);
+		return this;
+	}
+
+	@Override
+    public SwitchEntryStmt setStmts(final List<Statement> stmts) {
+		this.stmts = stmts;
+		setAsParentNodeOf(this.stmts);
+        return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SwitchStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SwitchStmt.java
new file mode 100644
index 0000000..c909394
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SwitchStmt.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.*;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SwitchStmt extends Statement {
+
+	private Expression selector;
+
+	private List<SwitchEntryStmt> entries;
+
+	public SwitchStmt() {
+	}
+
+	public SwitchStmt(final Expression selector,
+			final List<SwitchEntryStmt> entries) {
+		setSelector(selector);
+		setEntries(entries);
+	}
+
+	public SwitchStmt(Range range, final Expression selector,
+	                  final List<SwitchEntryStmt> entries) {
+		super(range);
+		setSelector(selector);
+		setEntries(entries);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<SwitchEntryStmt> getEntries() {
+        entries = ensureNotNull(entries);
+        return entries;
+	}
+
+	public Expression getSelector() {
+		return selector;
+	}
+
+	public SwitchStmt setEntries(final List<SwitchEntryStmt> entries) {
+		this.entries = entries;
+		setAsParentNodeOf(this.entries);
+		return this;
+	}
+
+	public SwitchStmt setSelector(final Expression selector) {
+		this.selector = selector;
+		setAsParentNodeOf(this.selector);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SynchronizedStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SynchronizedStmt.java
new file mode 100644
index 0000000..1a9d2db
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/SynchronizedStmt.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithBlockStmt;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SynchronizedStmt extends Statement implements NodeWithBlockStmt<SynchronizedStmt> {
+
+    private Expression expr;
+
+    private BlockStmt block;
+
+    public SynchronizedStmt() {
+    }
+
+    public SynchronizedStmt(final Expression expr, final BlockStmt block) {
+        setExpr(expr);
+        setBlock(block);
+    }
+
+    public SynchronizedStmt(Range range, final Expression expr,
+                            final BlockStmt block) {
+        super(range);
+        setExpr(expr);
+        setBlock(block);
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * @deprecated use {@link #getBody()}
+     * @return
+     */
+    @Deprecated
+    public BlockStmt getBlock() {
+        return block;
+    }
+
+    public Expression getExpr() {
+        return expr;
+    }
+
+    /**
+     * @deprecated Use {@link #setBody(BlockStmt)} instead
+     * @param block
+     */
+    @Deprecated
+    public SynchronizedStmt setBlock(final BlockStmt block) {
+        this.block = block;
+        setAsParentNodeOf(this.block);
+        return this;
+    }
+
+    public SynchronizedStmt setExpr(final Expression expr) {
+        this.expr = expr;
+        setAsParentNodeOf(this.expr);
+        return this;
+    }
+
+    @Override
+    public BlockStmt getBody() {
+        return block;
+    }
+
+    @Override
+    public SynchronizedStmt setBody(BlockStmt block) {
+        this.block = block;
+        setAsParentNodeOf(this.block);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ThrowStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ThrowStmt.java
new file mode 100644
index 0000000..180fdd0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/ThrowStmt.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ThrowStmt extends Statement {
+
+	private Expression expr;
+
+	public ThrowStmt() {
+	}
+
+	public ThrowStmt(final Expression expr) {
+		setExpr(expr);
+	}
+
+	public ThrowStmt(Range range, final Expression expr) {
+		super(range);
+		setExpr(expr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public ThrowStmt setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/TryStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/TryStmt.java
new file mode 100644
index 0000000..4688454
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/TryStmt.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.*;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class TryStmt extends Statement {
+	
+	private List<VariableDeclarationExpr> resources;
+
+	private BlockStmt tryBlock;
+
+	private List<CatchClause> catchs;
+
+	private BlockStmt finallyBlock;
+
+	public TryStmt() {
+	}
+
+	public TryStmt(final BlockStmt tryBlock, final List<CatchClause> catchs,
+			final BlockStmt finallyBlock) {
+		setTryBlock(tryBlock);
+		setCatchs(catchs);
+		setFinallyBlock(finallyBlock);
+	}
+
+	public TryStmt(Range range, List<VariableDeclarationExpr> resources,
+	               final BlockStmt tryBlock, final List<CatchClause> catchs, final BlockStmt finallyBlock) {
+		super(range);
+		setResources(resources);
+		setTryBlock(tryBlock);
+		setCatchs(catchs);
+		setFinallyBlock(finallyBlock);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<CatchClause> getCatchs() {
+        catchs = ensureNotNull(catchs);
+        return catchs;
+	}
+
+	public BlockStmt getFinallyBlock() {
+		return finallyBlock;
+	}
+
+	public BlockStmt getTryBlock() {
+		return tryBlock;
+	}
+	
+	public List<VariableDeclarationExpr> getResources() {
+        resources = ensureNotNull(resources);
+        return resources;
+	}
+
+	public TryStmt setCatchs(final List<CatchClause> catchs) {
+		this.catchs = catchs;
+		setAsParentNodeOf(this.catchs);
+		return this;
+	}
+
+	public TryStmt setFinallyBlock(final BlockStmt finallyBlock) {
+		this.finallyBlock = finallyBlock;
+		setAsParentNodeOf(this.finallyBlock);
+		return this;
+	}
+
+	public TryStmt setTryBlock(final BlockStmt tryBlock) {
+		this.tryBlock = tryBlock;
+		setAsParentNodeOf(this.tryBlock);
+		return this;
+	}
+	
+	public TryStmt setResources(List<VariableDeclarationExpr> resources) {
+		this.resources = resources;
+		setAsParentNodeOf(this.resources);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/TypeDeclarationStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/TypeDeclarationStmt.java
new file mode 100644
index 0000000..a9f83bf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/TypeDeclarationStmt.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class TypeDeclarationStmt extends Statement {
+
+	private TypeDeclaration typeDecl;
+
+	public TypeDeclarationStmt() {
+	}
+
+	public TypeDeclarationStmt(final TypeDeclaration typeDecl) {
+		setTypeDeclaration(typeDecl);
+	}
+
+	public TypeDeclarationStmt(Range range, final TypeDeclaration typeDecl) {
+		super(range);
+		setTypeDeclaration(typeDecl);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public TypeDeclaration getTypeDeclaration() {
+		return typeDecl;
+	}
+
+	public TypeDeclarationStmt setTypeDeclaration(final TypeDeclaration typeDecl) {
+		this.typeDecl = typeDecl;
+		setAsParentNodeOf(this.typeDecl);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/WhileStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/WhileStmt.java
new file mode 100644
index 0000000..b843494
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/stmt/WhileStmt.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.nodeTypes.NodeWithBody;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class WhileStmt extends Statement implements NodeWithBody<WhileStmt> {
+
+	private Expression condition;
+
+	private Statement body;
+
+	public WhileStmt() {
+	}
+
+	public WhileStmt(final Expression condition, final Statement body) {
+		setCondition(condition);
+		setBody(body);
+	}
+
+	public WhileStmt(Range range, final Expression condition, final Statement body) {
+		super(range);
+		setCondition(condition);
+		setBody(body);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	@Override
+    public Statement getBody() {
+		return body;
+	}
+
+	public Expression getCondition() {
+		return condition;
+	}
+
+	@Override
+    public WhileStmt setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+        return this;
+	}
+
+	public WhileStmt setCondition(final Expression condition) {
+		this.condition = condition;
+		setAsParentNodeOf(this.condition);
+		return this;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ArrayType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ArrayType.java
new file mode 100644
index 0000000..babf2a5
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ArrayType.java
@@ -0,0 +1,86 @@
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.ArrayBracketPair;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.utils.Pair;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * To indicate that a type is an array, it gets wrapped in an ArrayType for every array level it has.
+ * So, int[][] becomes ArrayType(ArrayType(int)).
+ */
+public class ArrayType extends ReferenceType<ArrayType> implements NodeWithAnnotations<ArrayType> {
+    private Type componentType;
+
+    public ArrayType(Type componentType, List<AnnotationExpr> annotations) {
+        setComponentType(componentType);
+        setAnnotations(annotations);
+    }
+
+    public ArrayType(Range range, Type componentType, List<AnnotationExpr> annotations) {
+        super(range);
+        setComponentType(componentType);
+        setAnnotations(annotations);
+    }
+
+    @Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    public Type getComponentType() {
+        return componentType;
+    }
+
+    public ArrayType setComponentType(final Type type) {
+        this.componentType = type;
+        setAsParentNodeOf(this.componentType);
+        return this;
+    }
+
+    /**
+     * Takes lists of arrayBracketPairs, assumes the lists are ordered left to right and the pairs are ordered left to right, mirroring the actual code.
+     * The type gets wrapped in ArrayTypes so that the outermost ArrayType corresponds to the rightmost ArrayBracketPair.
+     */
+    @SafeVarargs
+    public static Type wrapInArrayTypes(Type type, List<ArrayBracketPair>... arrayBracketPairLists) {
+        for (int i = arrayBracketPairLists.length - 1; i >= 0; i--) {
+            final List<ArrayBracketPair> arrayBracketPairList = arrayBracketPairLists[i];
+            if (arrayBracketPairList != null) {
+                for (int j = arrayBracketPairList.size() - 1; j >= 0; j--) {
+                    type = new ArrayType(type, arrayBracketPairList.get(j).getAnnotations());
+                }
+            }
+        }
+        return type;
+    }
+
+    /**
+     * Takes a type that may be an ArrayType. Unwraps ArrayTypes until the element type is found.
+     *
+     * @return a pair of the element type, and the unwrapped ArrayTypes, if any.
+     */
+    public static Pair<Type, List<ArrayBracketPair>> unwrapArrayTypes(Type type) {
+        final List<ArrayBracketPair> arrayBracketPairs = new ArrayList<>();
+        while (type instanceof ArrayType) {
+            ArrayType arrayType = (ArrayType) type;
+            arrayBracketPairs.add(new ArrayBracketPair(Range.UNKNOWN, arrayType.getAnnotations()));
+            type = arrayType.getComponentType();
+        }
+        return new Pair<>(type, arrayBracketPairs);
+    }
+    
+    public static ArrayType arrayOf(Type type, AnnotationExpr... annotations) {
+        return new ArrayType(type, Arrays.asList(annotations));
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ClassOrInterfaceType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ClassOrInterfaceType.java
new file mode 100644
index 0000000..ac30894
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ClassOrInterfaceType.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassOrInterfaceType extends ReferenceType<ClassOrInterfaceType> implements 
+        NodeWithName<ClassOrInterfaceType>, 
+        NodeWithAnnotations<ClassOrInterfaceType>,
+        NodeWithTypeArguments<ClassOrInterfaceType> {
+
+    private ClassOrInterfaceType scope;
+
+    private String name;
+
+    private List<Type<?>> typeArguments;
+
+    public ClassOrInterfaceType() {
+    }
+
+    public ClassOrInterfaceType(final String name) {
+        setName(name);
+    }
+
+    public ClassOrInterfaceType(final ClassOrInterfaceType scope, final String name) {
+        setScope(scope);
+        setName(name);
+    }
+
+    public ClassOrInterfaceType(final Range range, final ClassOrInterfaceType scope, final String name, final List<Type<?>> typeArguments) {
+        super(range);
+        setScope(scope);
+        setName(name);
+        setTypeArguments(typeArguments);
+    }
+
+    @Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public ClassOrInterfaceType getScope() {
+        return scope;
+    }
+
+    public boolean isBoxedType() {
+        return PrimitiveType.unboxMap.containsKey(name);
+    }
+
+    public PrimitiveType toUnboxedType() throws UnsupportedOperationException {
+        if (!isBoxedType()) {
+            throw new UnsupportedOperationException(name + " isn't a boxed type.");
+        }
+        return new PrimitiveType(PrimitiveType.unboxMap.get(name));
+    }
+
+    @Override
+    public ClassOrInterfaceType setName(final String name) {
+        this.name = name;
+        return this;
+    }
+
+    public ClassOrInterfaceType setScope(final ClassOrInterfaceType scope) {
+        this.scope = scope;
+        setAsParentNodeOf(this.scope);
+        return this;
+    }
+
+    @Override
+    public List<Type<?>> getTypeArguments() {
+        return typeArguments;
+    }
+
+    @Override
+    public ClassOrInterfaceType setTypeArguments(final List<Type<?>> types) {
+        this.typeArguments = types;
+        setAsParentNodeOf(this.typeArguments);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/IntersectionType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/IntersectionType.java
new file mode 100644
index 0000000..029d465
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/IntersectionType.java
@@ -0,0 +1,60 @@
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * Represents a set of types. A given value of this type has to be assignable to at all of the element types.
+ * As of Java 8 it is used in casts or while expressing bounds for generic types.
+ *
+ * For example:
+ * public class A&gt;T extends Serializable &amp; Cloneable&lt; { }
+ *
+ * Or:
+ * void foo((Serializable &amp; Cloneable)myObject);
+ *
+ * @since 3.0.0
+ */
+public class IntersectionType extends Type<IntersectionType> implements NodeWithAnnotations<IntersectionType> {
+
+    private List<ReferenceType> elements;
+
+    public IntersectionType(Range range, List<ReferenceType> elements) {
+        super(range);
+        setElements(elements);
+    }
+
+    public IntersectionType(List<ReferenceType> elements) {
+        super();
+        setElements(elements);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<ReferenceType> getElements() {
+        return elements;
+    }
+
+    public IntersectionType setElements(List<ReferenceType> elements) {
+        if (this.elements != null) {
+            for (ReferenceType element : elements){
+                element.setParentNode(null);
+            }
+        }
+        this.elements = elements;
+        setAsParentNodeOf(this.elements);
+        return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/PrimitiveType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/PrimitiveType.java
new file mode 100644
index 0000000..29299a4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/PrimitiveType.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+import java.util.HashMap;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class PrimitiveType extends Type<PrimitiveType> implements NodeWithAnnotations<PrimitiveType> {
+
+	public static final PrimitiveType BYTE_TYPE = new PrimitiveType(Primitive.Byte);
+
+	public static final PrimitiveType SHORT_TYPE = new PrimitiveType(Primitive.Short);
+
+	public static final PrimitiveType INT_TYPE = new PrimitiveType(Primitive.Int);
+
+	public static final PrimitiveType LONG_TYPE = new PrimitiveType(Primitive.Long);
+
+	public static final PrimitiveType FLOAT_TYPE = new PrimitiveType(Primitive.Float);
+
+	public static final PrimitiveType DOUBLE_TYPE = new PrimitiveType(Primitive.Double);
+
+	public static final PrimitiveType BOOLEAN_TYPE = new PrimitiveType(Primitive.Boolean);
+
+	public static final PrimitiveType CHAR_TYPE = new PrimitiveType(Primitive.Char);
+
+	public enum Primitive {
+		Boolean ("Boolean"),
+		Char    ("Character"),
+		Byte    ("Byte"),
+		Short   ("Short"),
+		Int     ("Integer"),
+		Long    ("Long"),
+		Float   ("Float"),
+		Double  ("Double");
+
+		final String nameOfBoxedType;
+
+		public ClassOrInterfaceType toBoxedType() {
+			return new ClassOrInterfaceType(nameOfBoxedType);
+		}
+
+		Primitive(String nameOfBoxedType) {
+			this.nameOfBoxedType = nameOfBoxedType;
+		}
+	}
+
+	static final HashMap<String, Primitive> unboxMap = new HashMap<>();
+	static {
+		for(Primitive unboxedType : Primitive.values()) {
+			unboxMap.put(unboxedType.nameOfBoxedType, unboxedType);
+		}
+	}
+
+	private Primitive type;
+
+	public PrimitiveType() {
+	}
+
+	public PrimitiveType(final Primitive type) {
+		this.type = type;
+	}
+
+	public PrimitiveType(Range range, final Primitive type) {
+		super(range);
+		setType(type);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Primitive getType() {
+		return type;
+	}
+
+	public ClassOrInterfaceType toBoxedType() {
+		return type.toBoxedType();
+	}
+
+	public PrimitiveType setType(final Primitive type) {
+		this.type = type;
+		return this;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ReferenceType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ReferenceType.java
new file mode 100644
index 0000000..1a4666b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/ReferenceType.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class ReferenceType<T extends ReferenceType> extends Type<T> {
+
+    public ReferenceType() {
+	}
+
+	public ReferenceType(final Range range) {
+		super(range);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/Type.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/Type.java
new file mode 100644
index 0000000..6c04355
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/Type.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.*;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Type<T extends Type> extends Node {
+
+    private List<AnnotationExpr> annotations;
+
+    public Type() {
+    }
+
+    public Type(List<AnnotationExpr> annotation){
+        this.annotations = annotation;
+    }
+
+    public Type(Range range) {
+        super(range);
+    }
+    
+    public Type(Range range, List<AnnotationExpr> annotations) {
+        super(range);
+        setAnnotations(annotations);
+    }
+
+    public List<AnnotationExpr> getAnnotations() {
+        annotations = ensureNotNull(annotations);
+        return annotations;
+    }
+
+    public T setAnnotations(List<AnnotationExpr> annotations) {
+        setAsParentNodeOf(annotations);
+        this.annotations = annotations;
+        return (T) this;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/TypeParameter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/TypeParameter.java
new file mode 100644
index 0000000..bfec9c9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/TypeParameter.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithName;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.ensureNotNull;
+
+/**
+ * <p>
+ * This class represents the declaration of a generics argument.
+ * </p>
+ * The TypeParameter is constructed following the syntax:<br>
+ * <pre>
+ * {@code
+ * TypeParameter ::= <IDENTIFIER> ( "extends" }{@link ClassOrInterfaceType}{@code ( "&" }{@link ClassOrInterfaceType}{@code )* )?
+ * }
+ * </pre>
+ * @author Julio Vilmar Gesser
+ */
+public final class TypeParameter extends ReferenceType<TypeParameter> implements NodeWithName<TypeParameter> {
+
+	private String name;
+
+    private List<AnnotationExpr> annotations;
+
+	private List<ClassOrInterfaceType> typeBound;
+
+	public TypeParameter() {
+	}
+
+	public TypeParameter(final String name, final List<ClassOrInterfaceType> typeBound) {
+		setName(name);
+		setTypeBound(typeBound);
+	}
+
+	public TypeParameter(Range range, final String name, final List<ClassOrInterfaceType> typeBound) {
+		super(range);
+		setName(name);
+		setTypeBound(typeBound);
+	}
+
+	public TypeParameter(Range range, String name, List<ClassOrInterfaceType> typeBound, List<AnnotationExpr> annotations) {
+		this(range, name, typeBound);
+		setTypeBound(typeBound);
+		setAnnotations(annotations);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	/**
+	 * Return the name of the paramenter.
+	 * 
+	 * @return the name of the paramenter
+	 */
+	@Override
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Return the list of {@link ClassOrInterfaceType} that this parameter
+	 * extends. Return <code>null</code> null if there are no type.
+	 * 
+	 * @return list of types that this paramente extends or <code>null</code>
+	 */
+	public List<ClassOrInterfaceType> getTypeBound() {
+        typeBound = ensureNotNull(typeBound);
+        return typeBound;
+	}
+
+	/**
+	 * Sets the name of this type parameter.
+	 * 
+	 * @param name
+	 *            the name to set
+	 */
+    @Override
+    public TypeParameter setName(final String name) {
+		this.name = name;
+        return this;
+	}
+
+	/**
+	 * Sets the list o types.
+	 * 
+	 * @param typeBound
+	 *            the typeBound to set
+	 */
+	public TypeParameter setTypeBound(final List<ClassOrInterfaceType> typeBound) {
+		this.typeBound = typeBound;
+		setAsParentNodeOf(typeBound);
+		return this;
+	}
+
+    public List<AnnotationExpr> getAnnotations() {
+        annotations = ensureNotNull(annotations);
+        return annotations;
+    }
+
+    public TypeParameter setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+	    setAsParentNodeOf(this.annotations);
+		return this;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/UnionType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/UnionType.java
new file mode 100644
index 0000000..74894af
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/UnionType.java
@@ -0,0 +1,52 @@
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * Represents a set of types. A given value of this type has to be assignable to at least one of the element types.
+ * As of Java 8 it is only used in catch clauses.
+ */
+public class UnionType extends Type<UnionType> implements NodeWithAnnotations<UnionType> {
+
+    private List<ReferenceType> elements;
+
+    public UnionType(Range range, List<ReferenceType> elements) {
+        super(range);
+        setElements(elements);
+    }
+
+    public UnionType(List<ReferenceType> elements) {
+        super();
+        setElements(elements);
+    }
+
+    public List<ReferenceType> getElements() {
+        return elements;
+    }
+
+    public UnionType setElements(List<ReferenceType> elements) {
+        if (this.elements != null) {
+            for (ReferenceType element : elements){
+                element.setParentNode(null);
+            }
+        }
+        this.elements = elements;
+        setAsParentNodeOf(this.elements);
+        return this;
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/UnknownType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/UnknownType.java
new file mode 100644
index 0000000..b76c596
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/UnknownType.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * An unknown parameter type object. It plays the role of a null object for
+ * lambda parameters that have no explicit type declared. As such, it has no
+ * lexical representation and hence gets no comment attributed.
+ *
+ * @author Didier Villevalois
+ */
+public final class UnknownType extends Type<UnknownType> {
+
+    public UnknownType() {
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public List<AnnotationExpr> getAnnotations() {
+        throw new IllegalStateException("Inferred lambda types cannot be annotated.");
+    }
+
+    @Override
+    public UnknownType setAnnotations(List<AnnotationExpr> annotations) {
+        throw new IllegalStateException("Inferred lambda types cannot be annotated.");
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/VoidType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/VoidType.java
new file mode 100644
index 0000000..d5f7273
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/VoidType.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VoidType extends Type<VoidType> implements NodeWithAnnotations<VoidType> {
+
+	public static final VoidType VOID_TYPE = new VoidType();
+
+	public VoidType() {
+	}
+
+	public VoidType(Range range) {
+		super(range);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/WildcardType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/WildcardType.java
new file mode 100644
index 0000000..d1e49bc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/type/WildcardType.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class WildcardType extends Type<WildcardType> implements NodeWithAnnotations<WildcardType> {
+
+	private ReferenceType ext;
+
+	private ReferenceType sup;
+
+	public WildcardType() {
+	}
+
+	public WildcardType(final ReferenceType ext) {
+		setExtends(ext);
+	}
+
+	public WildcardType(final ReferenceType ext, final ReferenceType sup) {
+		setExtends(ext);
+		setSuper(sup);
+	}
+
+	public WildcardType(final Range range,
+			final ReferenceType ext, final ReferenceType sup) {
+		super(range);
+		setExtends(ext);
+		setSuper(sup);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public ReferenceType getExtends() {
+		return ext;
+	}
+
+	public ReferenceType getSuper() {
+		return sup;
+	}
+
+	public WildcardType setExtends(final ReferenceType ext) {
+		this.ext = ext;
+		setAsParentNodeOf(this.ext);
+		return this;
+	}
+
+	public WildcardType setSuper(final ReferenceType sup) {
+		this.sup = sup;
+		setAsParentNodeOf(this.sup);
+		return this;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/CloneVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/CloneVisitor.java
new file mode 100644
index 0000000..33ca0e0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/CloneVisitor.java
@@ -0,0 +1,1296 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.ArrayAccessExpr;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.ArrayInitializerExpr;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.CharLiteralExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
+import com.github.javaparser.ast.expr.ConditionalExpr;
+import com.github.javaparser.ast.expr.DoubleLiteralExpr;
+import com.github.javaparser.ast.expr.EnclosedExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.InstanceOfExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
+import com.github.javaparser.ast.expr.LongLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.MemberValuePair;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.NullLiteralExpr;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.expr.QualifiedNameExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.SuperExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.expr.TypeExpr;
+import com.github.javaparser.ast.expr.UnaryExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+public class CloneVisitor implements GenericVisitor<Node, Object> {
+
+	@Override
+	public Node visit(CompilationUnit _n, Object _arg) {
+		PackageDeclaration package_ = cloneNodes(_n.getPackage(), _arg);
+		List<ImportDeclaration> imports = visit(_n.getImports(), _arg);
+        List<TypeDeclaration<?>> types = visit(_n.getTypes(), _arg);
+
+		return new CompilationUnit(
+				_n.getRange(),
+				package_, imports, types
+		);
+	}
+
+	@Override
+	public Node visit(PackageDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		PackageDeclaration r = new PackageDeclaration(
+				_n.getRange(),
+				annotations, name
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ImportDeclaration _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ImportDeclaration r = new ImportDeclaration(
+				_n.getRange(),
+				name, _n.isStatic(), _n.isAsterisk()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(TypeParameter _n, Object _arg) {
+        List<ClassOrInterfaceType> typeBound = visit(_n.getTypeBound(), _arg);
+
+        List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+        TypeParameter r = new TypeParameter(_n.getRange(),
+                _n.getName(), typeBound, annotations);
+
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LineComment _n, Object _arg) {
+		return new LineComment(_n.getRange(), _n.getContent());
+	}
+
+	@Override
+	public Node visit(BlockComment _n, Object _arg) {
+		return new BlockComment(_n.getRange(), _n.getContent());
+	}
+
+	@Override
+	public Node visit(ClassOrInterfaceDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg);
+		List<ClassOrInterfaceType> extendsList = visit(_n.getExtends(), _arg);
+		List<ClassOrInterfaceType> implementsList = visit(_n.getImplements(), _arg);
+        List<BodyDeclaration<?>> members = visit(_n.getMembers(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ClassOrInterfaceDeclaration r = new ClassOrInterfaceDeclaration(
+				_n.getRange(),
+				_n.getModifiers(), annotations, _n.isInterface(), _n.getName(), typeParameters, extendsList, implementsList, members
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EnumDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<ClassOrInterfaceType> implementsList = visit(_n.getImplements(), _arg);
+		List<EnumConstantDeclaration> entries = visit(_n.getEntries(), _arg);
+        List<BodyDeclaration<?>> members = visit(_n.getMembers(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EnumDeclaration r = new EnumDeclaration(
+				_n.getRange(),
+				 _n.getModifiers(), annotations, _n.getName(), implementsList, entries, members
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EmptyTypeDeclaration _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EmptyTypeDeclaration r = new EmptyTypeDeclaration(
+				_n.getRange()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EnumConstantDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<Expression> args = visit(_n.getArgs(), _arg);
+        List<BodyDeclaration<?>> classBody = visit(_n.getClassBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EnumConstantDeclaration r = new EnumConstantDeclaration(
+				_n.getRange(),
+				 annotations, _n.getName(), args, classBody
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AnnotationDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+        List<BodyDeclaration<?>> members = visit(_n.getMembers(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AnnotationDeclaration r = new AnnotationDeclaration(
+				_n.getRange(),
+				 _n.getModifiers(), annotations, _n.getName(), members
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AnnotationMemberDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Type<?> type_ = cloneNodes(_n.getType(), _arg);
+		Expression defaultValue = cloneNodes(_n.getDefaultValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AnnotationMemberDeclaration r = new AnnotationMemberDeclaration(
+				_n.getRange(),
+				 _n.getModifiers(), annotations, type_, _n.getName(), defaultValue
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(FieldDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations_ = visit(_n.getAnnotations(), _arg);
+		Type<?> elementType_ = cloneNodes(_n.getElementType(), _arg);
+		List<VariableDeclarator> variables_ = visit(_n.getVariables(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+        List<ArrayBracketPair> arrayBracketPairsAfterType_ = visit(_n.getArrayBracketPairsAfterElementType(), _arg);
+
+        FieldDeclaration r = new FieldDeclaration(
+				_n.getRange(),
+				 _n.getModifiers(), 
+                annotations_, 
+                elementType_, 
+                variables_,
+                arrayBracketPairsAfterType_
+                
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(VariableDeclarator _n, Object _arg) {
+		VariableDeclaratorId id = cloneNodes(_n.getId(), _arg);
+		Expression init = cloneNodes(_n.getInit(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		VariableDeclarator r = new VariableDeclarator(
+				_n.getRange(),
+				id, init
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(VariableDeclaratorId _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		List<ArrayBracketPair> arrayBracketPairsAfterId_ = visit(_n.getArrayBracketPairsAfterId(), _arg);
+
+		VariableDeclaratorId r = new VariableDeclaratorId(
+				_n.getRange(),
+				_n.getName(),
+				arrayBracketPairsAfterId_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ConstructorDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg);
+		List<Parameter> parameters = visit(_n.getParameters(), _arg);
+		List<ReferenceType> throws_ = visit(_n.getThrows(), _arg);
+		BlockStmt block = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ConstructorDeclaration r = new ConstructorDeclaration(
+				_n.getRange(),
+				 _n.getModifiers(), annotations, typeParameters, _n.getName(), parameters, throws_, block
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MethodDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations_ = visit(_n.getAnnotations(), _arg);
+		List<TypeParameter> typeParameters_ = visit(_n.getTypeParameters(), _arg);
+		Type<?> type_ = cloneNodes(_n.getElementType(), _arg);
+        NameExpr nameExpr_ = cloneNodes(_n.getNameExpr(), _arg);
+        List<Parameter> parameters_ = visit(_n.getParameters(), _arg);
+		List<ReferenceType> throws_ = visit(_n.getThrows(), _arg);
+		BlockStmt block_ = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		List<ArrayBracketPair> arrayBracketPairsAfterElementType_ = visit(_n.getArrayBracketPairsAfterElementType(), _arg);
+		List<ArrayBracketPair> arrayBracketPairsAfterParameterList_ = visit(_n.getArrayBracketPairsAfterParameterList(), _arg);
+
+		MethodDeclaration r = new MethodDeclaration(
+				_n.getRange(),
+				 _n.getModifiers(), 
+                annotations_, 
+                typeParameters_, 
+                type_,
+                arrayBracketPairsAfterElementType_,
+                nameExpr_, 
+                parameters_, 
+                arrayBracketPairsAfterParameterList_, 
+                throws_, 
+                block_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(Parameter _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Type<?> type_ = cloneNodes(_n.getElementType(), _arg);
+		VariableDeclaratorId id = cloneNodes(_n.getId(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+        List<ArrayBracketPair> arrayBracketPairsAfterType_ = visit(_n.getArrayBracketPairsAfterElementType(), _arg);
+
+        Parameter r = new Parameter(
+				_n.getRange(),
+				_n.getModifiers(), 
+                annotations, 
+                type_,
+                arrayBracketPairsAfterType_,
+                _n.isVarArgs(), 
+                id
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EmptyMemberDeclaration _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EmptyMemberDeclaration r = new EmptyMemberDeclaration(
+				_n.getRange()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(InitializerDeclaration _n, Object _arg) {
+		BlockStmt block = cloneNodes(_n.getBlock(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		InitializerDeclaration r = new InitializerDeclaration(
+				_n.getRange(),
+				 _n.isStatic(), block
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(JavadocComment _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		JavadocComment r = new JavadocComment(
+				_n.getRange(),
+				_n.getContent()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ClassOrInterfaceType _n, Object _arg) {
+		ClassOrInterfaceType scope = cloneNodes(_n.getScope(), _arg);
+		List<Type<?>> typeArguments_ = visit(_n.getTypeArguments(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ClassOrInterfaceType r = new ClassOrInterfaceType(
+				_n.getRange(),
+				scope,
+				_n.getName(),
+				_n.getTypeArguments()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(PrimitiveType _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+
+		PrimitiveType r = new PrimitiveType(
+				_n.getRange(),
+				_n.getType()
+		);
+		r.setComment(comment);
+		r.setAnnotations(annotations);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayType _n, Object _arg) {
+		List<AnnotationExpr> ann = visit(_n.getAnnotations(), _arg);
+		Type<?> type_ = cloneNodes(_n.getComponentType(), _arg);
+
+		ArrayType r = new ArrayType(_n.getRange(), type_, ann);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayCreationLevel _n, Object _arg) {
+		List<AnnotationExpr> ann = visit(_n.getAnnotations(), _arg);
+		Expression dimension_ = cloneNodes(_n.getDimension(), _arg);
+
+		ArrayCreationLevel r = new ArrayCreationLevel(_n.getRange(), dimension_, ann);
+
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+    public Node visit(IntersectionType _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+        List<ReferenceType> elements = visit(_n.getElements(), _arg);
+
+        IntersectionType r = new IntersectionType(_n.getRange(), elements);
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+		r.setAnnotations(annotations);
+        return r;
+    }
+
+    @Override
+    public Node visit(UnionType _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+        List<ReferenceType> elements = visit(_n.getElements(), _arg);
+
+        UnionType r = new UnionType(_n.getRange(),
+                elements);
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+		r.setAnnotations(annotations);
+        return r;
+    }
+
+	@Override
+	public Node visit(VoidType _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		VoidType r = new VoidType(_n.getRange());
+		r.setAnnotations(annotations);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(WildcardType _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		ReferenceType ext = cloneNodes(_n.getExtends(), _arg);
+		ReferenceType sup = cloneNodes(_n.getSuper(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		WildcardType r = new WildcardType(
+				_n.getRange(),
+				ext, sup
+		);
+		r.setComment(comment);
+		r.setAnnotations(annotations);
+		return r;
+	}
+
+	@Override
+	public Node visit(UnknownType _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		UnknownType r = new UnknownType();
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayAccessExpr _n, Object _arg) {
+		Expression name = cloneNodes(_n.getName(), _arg);
+		Expression index = cloneNodes(_n.getIndex(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ArrayAccessExpr r = new ArrayAccessExpr(
+				_n.getRange(),
+				name, index
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayCreationExpr _n, Object _arg) {
+		Type<?> type_ = cloneNodes(_n.getType(), _arg);
+		List<ArrayCreationLevel> levels_ = visit(_n.getLevels(), _arg);
+		ArrayInitializerExpr initializer_ = cloneNodes(_n.getInitializer(), _arg);
+
+		ArrayCreationExpr r = new ArrayCreationExpr(_n.getRange(), type_, levels_, initializer_);
+
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayInitializerExpr _n, Object _arg) {
+		List<Expression> values = visit(_n.getValues(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ArrayInitializerExpr r = new ArrayInitializerExpr(
+				_n.getRange(),
+				values
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AssignExpr _n, Object _arg) {
+		Expression target = cloneNodes(_n.getTarget(), _arg);
+		Expression value = cloneNodes(_n.getValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AssignExpr r = new AssignExpr(
+				_n.getRange(),
+				target, value, _n.getOperator());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BinaryExpr _n, Object _arg) {
+		Expression left = cloneNodes(_n.getLeft(), _arg);
+		Expression right = cloneNodes(_n.getRight(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BinaryExpr r = new BinaryExpr(
+				_n.getRange(),
+				left, right, _n.getOperator()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(CastExpr _n, Object _arg) {
+		Type<?> type_ = cloneNodes(_n.getType(), _arg);
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		CastExpr r = new CastExpr(
+				_n.getRange(),
+				type_, expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ClassExpr _n, Object _arg) {
+		Type<?> type_ = cloneNodes(_n.getType(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ClassExpr r = new ClassExpr(
+				_n.getRange(),
+				type_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ConditionalExpr _n, Object _arg) {
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Expression thenExpr = cloneNodes(_n.getThenExpr(), _arg);
+		Expression elseExpr = cloneNodes(_n.getElseExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ConditionalExpr r = new ConditionalExpr(
+				_n.getRange(),
+				condition, thenExpr, elseExpr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EnclosedExpr _n, Object _arg) {
+		Expression inner = cloneNodes(_n.getInner(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EnclosedExpr r = new EnclosedExpr(
+				_n.getRange(),
+				inner
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(FieldAccessExpr _n, Object _arg) {
+		Expression scope_ = cloneNodes(_n.getScope(), _arg);
+		List<Type<?>> typeArguments_ = visit(_n.getTypeArguments(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		FieldAccessExpr r = new FieldAccessExpr(
+				_n.getRange(),
+				scope_, 
+                typeArguments_, 
+                _n.getField()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(InstanceOfExpr _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Type<?> type_ = cloneNodes(_n.getType(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		InstanceOfExpr r = new InstanceOfExpr(
+				_n.getRange(),
+				expr, type_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(StringLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		StringLiteralExpr r = new StringLiteralExpr(
+				_n.getRange(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(IntegerLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		IntegerLiteralExpr r = new IntegerLiteralExpr(
+				_n.getRange(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LongLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		LongLiteralExpr r = new LongLiteralExpr(
+				_n.getRange(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(IntegerLiteralMinValueExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		IntegerLiteralMinValueExpr r = new IntegerLiteralMinValueExpr(_n.getRange());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LongLiteralMinValueExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		LongLiteralMinValueExpr r = new LongLiteralMinValueExpr(_n.getRange());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(CharLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		CharLiteralExpr r = new CharLiteralExpr(
+				_n.getRange(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(DoubleLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		DoubleLiteralExpr r = new DoubleLiteralExpr(
+				_n.getRange(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BooleanLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BooleanLiteralExpr r = new BooleanLiteralExpr(
+				_n.getRange(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(NullLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		NullLiteralExpr r = new NullLiteralExpr(_n.getRange());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MethodCallExpr _n, Object _arg) {
+		Expression scope_ = cloneNodes(_n.getScope(), _arg);
+		List<Type<?>> typeArguments_ = visit(_n.getTypeArguments(), _arg);
+		List<Expression> args_ = visit(_n.getArgs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MethodCallExpr r = new MethodCallExpr(
+				_n.getRange(),
+				scope_, 
+                typeArguments_, 
+                _n.getName(), 
+                args_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(NameExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		NameExpr r = new NameExpr(
+				_n.getRange(),
+				_n.getName()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ObjectCreationExpr _n, Object _arg) {
+		Expression scope = cloneNodes(_n.getScope(), _arg);
+		ClassOrInterfaceType type_ = cloneNodes(_n.getType(), _arg);
+		List<Type<?>> typeArgs = visit(_n.getTypeArguments(), _arg);
+		List<Expression> args = visit(_n.getArgs(), _arg);
+        List<BodyDeclaration<?>> anonymousBody = visit(_n.getAnonymousClassBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ObjectCreationExpr r = new ObjectCreationExpr(
+				_n.getRange(),
+				scope, type_, typeArgs, args, anonymousBody
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(QualifiedNameExpr _n, Object _arg) {
+		NameExpr scope = cloneNodes(_n.getQualifier(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		QualifiedNameExpr r = new QualifiedNameExpr(
+				_n.getRange(),
+				scope, _n.getName()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ThisExpr _n, Object _arg) {
+		Expression classExpr = cloneNodes(_n.getClassExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ThisExpr r = new ThisExpr(
+				_n.getRange(),
+				classExpr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SuperExpr _n, Object _arg) {
+		Expression classExpr = cloneNodes(_n.getClassExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SuperExpr r = new SuperExpr(
+				_n.getRange(),
+				classExpr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(UnaryExpr _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		UnaryExpr r = new UnaryExpr(
+				_n.getRange(),
+				expr, _n.getOperator()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(VariableDeclarationExpr _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Type<?> type_ = cloneNodes(_n.getElementType(), _arg);
+		List<VariableDeclarator> vars = visit(_n.getVariables(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+        List<ArrayBracketPair> arrayBracketPairsAfterType_ = visit(_n.getArrayBracketPairsAfterElementType(), _arg);
+
+		VariableDeclarationExpr r = new VariableDeclarationExpr(
+				_n.getRange(),
+				_n.getModifiers(), 
+                annotations, 
+                type_, 
+                vars,
+                arrayBracketPairsAfterType_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MarkerAnnotationExpr _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MarkerAnnotationExpr r = new MarkerAnnotationExpr(
+				_n.getRange(),
+				name
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SingleMemberAnnotationExpr _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Expression memberValue = cloneNodes(_n.getMemberValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SingleMemberAnnotationExpr r = new SingleMemberAnnotationExpr(
+				_n.getRange(),
+				name, memberValue
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(NormalAnnotationExpr _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		List<MemberValuePair> pairs = visit(_n.getPairs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		NormalAnnotationExpr r = new NormalAnnotationExpr(
+				_n.getRange(),
+				name, pairs
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MemberValuePair _n, Object _arg) {
+		Expression value = cloneNodes(_n.getValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MemberValuePair r = new MemberValuePair(
+				_n.getRange(),
+				_n.getName(), value
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ExplicitConstructorInvocationStmt _n, Object _arg) {
+		List<Type<?>> typeArguments_ = visit(_n.getTypeArguments(), _arg);
+		Expression expr_ = cloneNodes(_n.getExpr(), _arg);
+		List<Expression> args_ = visit(_n.getArgs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ExplicitConstructorInvocationStmt r = new ExplicitConstructorInvocationStmt(
+				_n.getRange(),
+				typeArguments_, 
+                _n.isThis(), 
+                expr_, 
+                args_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(TypeDeclarationStmt _n, Object _arg) {
+        TypeDeclaration<?> typeDecl = cloneNodes(_n.getTypeDeclaration(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		TypeDeclarationStmt r = new TypeDeclarationStmt(
+				_n.getRange(),
+				typeDecl
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AssertStmt _n, Object _arg) {
+		Expression check = cloneNodes(_n.getCheck(), _arg);
+		Expression message = cloneNodes(_n.getMessage(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AssertStmt r = new AssertStmt(
+				_n.getRange(),
+				check, message
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BlockStmt _n, Object _arg) {
+		List<Statement> stmts = visit(_n.getStmts(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BlockStmt r = new BlockStmt(
+				_n.getRange(),
+				stmts
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LabeledStmt _n, Object _arg) {
+		Statement stmt = cloneNodes(_n.getStmt(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		LabeledStmt r = new LabeledStmt(
+				_n.getRange(),
+				_n.getLabel(), stmt
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EmptyStmt _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EmptyStmt r = new EmptyStmt(_n.getRange());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ExpressionStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpression(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ExpressionStmt r = new ExpressionStmt(
+				_n.getRange(),
+				expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SwitchStmt _n, Object _arg) {
+		Expression selector = cloneNodes(_n.getSelector(), _arg);
+		List<SwitchEntryStmt> entries = visit(_n.getEntries(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SwitchStmt r = new SwitchStmt(
+				_n.getRange(),
+				selector, entries
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SwitchEntryStmt _n, Object _arg) {
+		Expression label = cloneNodes(_n.getLabel(), _arg);
+		List<Statement> stmts = visit(_n.getStmts(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SwitchEntryStmt r = new SwitchEntryStmt(
+				_n.getRange(),
+				label, stmts
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BreakStmt _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BreakStmt r = new BreakStmt(
+				_n.getRange(),
+				_n.getId()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ReturnStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ReturnStmt r = new ReturnStmt(
+				_n.getRange(),
+				expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(IfStmt _n, Object _arg) {
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Statement thenStmt = cloneNodes(_n.getThenStmt(), _arg);
+		Statement elseStmt = cloneNodes(_n.getElseStmt(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		IfStmt r = new IfStmt(
+				_n.getRange(),
+				condition, thenStmt, elseStmt
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(WhileStmt _n, Object _arg) {
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		WhileStmt r = new WhileStmt(
+				_n.getRange(),
+				condition, body
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ContinueStmt _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ContinueStmt r = new ContinueStmt(
+				_n.getRange(),
+				_n.getId()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(DoStmt _n, Object _arg) {
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		DoStmt r = new DoStmt(
+				_n.getRange(),
+				body, condition
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ForeachStmt _n, Object _arg) {
+		VariableDeclarationExpr var = cloneNodes(_n.getVariable(), _arg);
+		Expression iterable = cloneNodes(_n.getIterable(), _arg);
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ForeachStmt r = new ForeachStmt(
+				_n.getRange(),
+				var, iterable, body
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ForStmt _n, Object _arg) {
+		List<Expression> init = visit(_n.getInit(), _arg);
+		Expression compare = cloneNodes(_n.getCompare(), _arg);
+		List<Expression> update = visit(_n.getUpdate(), _arg);
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ForStmt r = new ForStmt(
+				_n.getRange(),
+				init, compare, update, body
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ThrowStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ThrowStmt r = new ThrowStmt(
+				_n.getRange(),
+				expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SynchronizedStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		BlockStmt block = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SynchronizedStmt r = new SynchronizedStmt(
+				_n.getRange(),
+				expr, block
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(TryStmt _n, Object _arg) {
+		List<VariableDeclarationExpr> resources = visit(_n.getResources(),_arg);
+		BlockStmt tryBlock = cloneNodes(_n.getTryBlock(), _arg);
+		List<CatchClause> catchs = visit(_n.getCatchs(), _arg);
+		BlockStmt finallyBlock = cloneNodes(_n.getFinallyBlock(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		TryStmt r = new TryStmt(
+				_n.getRange(),
+				resources, tryBlock, catchs, finallyBlock
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(CatchClause _n, Object _arg) {
+		Parameter param = cloneNodes(_n.getParam(), _arg);
+		BlockStmt catchBlock = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		CatchClause r = new CatchClause(
+				_n.getRange(),
+				param.getModifiers(), param.getAnnotations(), param.getElementType(), param.getId(), catchBlock
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LambdaExpr _n, Object _arg) {
+
+		List<Parameter> lambdaParameters = visit(_n.getParameters(), _arg);
+
+		Statement body = cloneNodes(_n.getBody(), _arg);
+
+		return new LambdaExpr(_n.getRange(), lambdaParameters, body,
+				_n.isParametersEnclosed());
+	}
+
+	@Override
+	public Node visit(MethodReferenceExpr _n, Object arg) {
+
+		Expression scope = cloneNodes(_n.getScope(), arg);
+
+		return new MethodReferenceExpr(_n.getRange(), scope,
+				_n.getTypeArguments(), _n.getIdentifier());
+	}
+
+	@Override
+	public Node visit(TypeExpr n, Object arg) {
+
+		Type<?> t = cloneNodes(n.getType(), arg);
+
+		return new TypeExpr(n.getRange(), t);
+	}
+
+	@Override
+	public Node visit(ArrayBracketPair _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+
+		return new ArrayBracketPair(_n.getRange(), annotations);
+	}
+
+	public <T extends Node> List<T> visit(List<T> _nodes, Object _arg) {
+        if (_nodes == null)
+            return null;
+        List<T> r = new ArrayList<>(_nodes.size());
+        for (T n : _nodes) {
+            T rN = cloneNodes(n, _arg);
+            if (rN != null)
+                r.add(rN);
+        }
+        return r;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected <T extends Node> T cloneNodes(T _node, Object _arg) {
+        if (_node == null)
+            return null;
+        Node r = _node.accept(this, _arg);
+        if (r == null)
+            return null;
+        return (T) r;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/DumpVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/DumpVisitor.java
new file mode 100644
index 0000000..569f395
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/DumpVisitor.java
@@ -0,0 +1,1644 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.utils.PositionUtils.sortByBeginPosition;
+import static com.github.javaparser.utils.Utils.EOL;
+import static com.github.javaparser.utils.Utils.isNullOrEmpty;
+
+/**
+ * Dumps the AST to formatted Java source code.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public class DumpVisitor implements VoidVisitor<Object> {
+
+	private boolean printComments;
+
+	public DumpVisitor() {
+		this(true);
+	}
+
+	public DumpVisitor(boolean printComments) {
+		this.printComments = printComments;
+	}
+
+	public static class SourcePrinter {
+
+		private final String indentation;
+
+		public SourcePrinter(final String indentation) {
+			this.indentation = indentation;
+		}
+
+		private int level = 0;
+
+		private boolean indented = false;
+
+		private final StringBuilder buf = new StringBuilder();
+
+		public void indent() {
+			level++;
+		}
+
+		public void unindent() {
+			level--;
+		}
+
+		private void makeIndent() {
+			for (int i = 0; i < level; i++) {
+				buf.append(indentation);
+			}
+		}
+
+		public void print(final String arg) {
+			if (!indented) {
+				makeIndent();
+				indented = true;
+			}
+			buf.append(arg);
+		}
+
+		public void printLn(final String arg) {
+			print(arg);
+			printLn();
+		}
+
+		public void printLn() {
+			buf.append(EOL);
+			indented = false;
+		}
+
+		public String getSource() {
+			return buf.toString();
+		}
+
+		@Override
+		public String toString() {
+			return getSource();
+		}
+	}
+
+	private final SourcePrinter printer = createSourcePrinter();
+
+	protected SourcePrinter createSourcePrinter() {
+		return new SourcePrinter("    ");
+	}
+
+	public String getSource() {
+		return printer.getSource();
+	}
+
+	private void printModifiers(final EnumSet<Modifier> modifiers) {
+		if (modifiers.size() > 0)
+			printer.print(modifiers.stream().map(Modifier::getLib).collect(Collectors.joining(" ")) + " ");
+	}
+
+	private void printMembers(final List<BodyDeclaration<?>> members, final Object arg) {
+		for (final BodyDeclaration<?> member : members) {
+			printer.printLn();
+			member.accept(this, arg);
+			printer.printLn();
+		}
+	}
+
+	private void printMemberAnnotations(final List<AnnotationExpr> annotations, final Object arg) {
+		if (!isNullOrEmpty(annotations)) {
+			for (final AnnotationExpr a : annotations) {
+				a.accept(this, arg);
+				printer.printLn();
+			}
+		}
+	}
+
+	private void printAnnotations(final List<AnnotationExpr> annotations, boolean prefixWithASpace, final Object arg) {
+		if (!isNullOrEmpty(annotations)) {
+			if(prefixWithASpace){
+				printer.print(" ");
+			}
+			for (AnnotationExpr annotation : annotations) {
+				annotation.accept(this, arg);
+				printer.print(" ");
+			}
+		}
+	}
+
+	private void printTypeArgs(final NodeWithTypeArguments<?> nodeWithTypeArguments, final Object arg) {
+		List<Type<?>> typeArguments = nodeWithTypeArguments.getTypeArguments();
+		if (!isNullOrEmpty(typeArguments)) {
+			printer.print("<");
+			for (final Iterator<Type<?>> i = typeArguments.iterator(); i.hasNext(); ) {
+				final Type<?> t = i.next();
+				t.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+			printer.print(">");
+		}
+	}
+
+	private void printTypeParameters(final List<TypeParameter> args, final Object arg) {
+		if (!isNullOrEmpty(args)) {
+			printer.print("<");
+			for (final Iterator<TypeParameter> i = args.iterator(); i.hasNext(); ) {
+				final TypeParameter t = i.next();
+				t.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+			printer.print(">");
+		}
+	}
+
+	private void printArguments(final List<Expression> args, final Object arg) {
+		printer.print("(");
+		if (!isNullOrEmpty(args)) {
+			for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) {
+				final Expression e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+	}
+
+	private void printJavaComment(final Comment javacomment, final Object arg) {
+		if (javacomment != null) {
+			javacomment.accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(final CompilationUnit n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+
+		if (n.getPackage() != null) {
+			n.getPackage().accept(this, arg);
+		}
+
+		if (!isNullOrEmpty(n.getImports())) {
+			for (final ImportDeclaration i : n.getImports()) {
+				i.accept(this, arg);
+			}
+			printer.printLn();
+		}
+
+		if (!isNullOrEmpty(n.getTypes())) {
+			for (final Iterator<TypeDeclaration<?>> i = n.getTypes().iterator(); i.hasNext(); ) {
+				i.next().accept(this, arg);
+				printer.printLn();
+				if (i.hasNext()) {
+					printer.printLn();
+				}
+			}
+		}
+
+		printOrphanCommentsEnding(n);
+	}
+
+	@Override
+	public void visit(final PackageDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), false, arg);
+		printer.print("package ");
+		n.getName().accept(this, arg);
+		printer.printLn(";");
+		printer.printLn();
+
+		printOrphanCommentsEnding(n);
+	}
+
+	@Override
+	public void visit(final NameExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getName());
+
+		printOrphanCommentsEnding(n);
+	}
+
+	@Override
+	public void visit(final QualifiedNameExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getQualifier().accept(this, arg);
+		printer.print(".");
+		printer.print(n.getName());
+
+		printOrphanCommentsEnding(n);
+	}
+
+	@Override
+	public void visit(final ImportDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (!n.isEmptyImportDeclaration()) {
+			printer.print("import ");
+			if (n.isStatic()) {
+				printer.print("static ");
+			}
+			n.getName().accept(this, arg);
+			if (n.isAsterisk()) {
+				printer.print(".*");
+			}
+		}
+		printer.printLn(";");
+
+		printOrphanCommentsEnding(n);
+	}
+
+	@Override
+	public void visit(final ClassOrInterfaceDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		if (n.isInterface()) {
+			printer.print("interface ");
+		} else {
+			printer.print("class ");
+		}
+
+		printer.print(n.getName());
+
+		printTypeParameters(n.getTypeParameters(), arg);
+
+		if (!isNullOrEmpty(n.getExtends())) {
+			printer.print(" extends ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getExtends().iterator(); i.hasNext(); ) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+
+		if (!isNullOrEmpty(n.getImplements())) {
+			printer.print(" implements ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getImplements().iterator(); i.hasNext(); ) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+
+		printer.printLn(" {");
+		printer.indent();
+		if (!isNullOrEmpty(n.getMembers())) {
+			printMembers(n.getMembers(), arg);
+		}
+
+		printOrphanCommentsEnding(n);
+
+		printer.unindent();
+		printer.print("}");
+	}
+
+	@Override
+	public void visit(final EmptyTypeDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(";");
+
+		printOrphanCommentsEnding(n);
+	}
+
+	@Override
+	public void visit(final JavadocComment n, final Object arg) {
+		printer.print("/**");
+		printer.print(n.getContent());
+		printer.printLn("*/");
+	}
+
+	@Override
+	public void visit(final ClassOrInterfaceType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+			printer.print(".");
+		}
+		for (AnnotationExpr ae : n.getAnnotations()) {
+			ae.accept(this, arg);
+			printer.print(" ");
+		}
+
+		printer.print(n.getName());
+
+		if (n.isUsingDiamondOperator()) {
+			printer.print("<>");
+		} else {
+			printTypeArgs(n, arg);
+		}
+	}
+
+	@Override
+	public void visit(final TypeParameter n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		for (AnnotationExpr ann : n.getAnnotations()) {
+			ann.accept(this, arg);
+			printer.print(" ");
+		}
+		printer.print(n.getName());
+		if (!isNullOrEmpty(n.getTypeBound())) {
+			printer.print(" extends ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getTypeBound().iterator(); i.hasNext(); ) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(" & ");
+				}
+			}
+		}
+	}
+
+	@Override
+	public void visit(final PrimitiveType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), true, arg);
+		switch (n.getType()) {
+			case Boolean:
+				printer.print("boolean");
+				break;
+			case Byte:
+				printer.print("byte");
+				break;
+			case Char:
+				printer.print("char");
+				break;
+			case Double:
+				printer.print("double");
+				break;
+			case Float:
+				printer.print("float");
+				break;
+			case Int:
+				printer.print("int");
+				break;
+			case Long:
+				printer.print("long");
+				break;
+			case Short:
+				printer.print("short");
+				break;
+		}
+	}
+
+	@Override
+    public void visit(final ArrayType n, final Object arg) {
+        final List<ArrayType> arrayTypeBuffer = new LinkedList<>();
+        Type type = n;
+        while (type instanceof ArrayType) {
+            final ArrayType arrayType = (ArrayType) type;
+            arrayTypeBuffer.add(arrayType);
+            type = arrayType.getComponentType();
+        }
+
+        type.accept(this, arg);
+        for (ArrayType arrayType : arrayTypeBuffer) {
+            printAnnotations(arrayType.getAnnotations(), true, arg);
+            printer.print("[]");
+        }
+    }
+
+	@Override
+	public void visit(final ArrayCreationLevel n, final Object arg) {
+		printAnnotations(n.getAnnotations(), true, arg);
+		printer.print("[");
+		if (n.getDimension() != null) {
+			n.getDimension().accept(this, arg);
+		}
+		printer.print("]");
+	}
+
+	@Override
+	public void visit(final IntersectionType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), false, arg);
+		boolean isFirst = true;
+		for (ReferenceType element : n.getElements()) {
+			element.accept(this, arg);
+			if (isFirst) {
+				isFirst = false;
+			} else {
+				printer.print(" & ");
+			}
+		}
+	}
+
+    @Override public void visit(final UnionType n, final Object arg) {
+        printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), true, arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" | ");
+            }
+	        element.accept(this, arg);
+        }
+    }
+
+
+	@Override
+	public void visit(final WildcardType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), false, arg);
+		printer.print("?");
+		if (n.getExtends() != null) {
+			printer.print(" extends ");
+			n.getExtends().accept(this, arg);
+		}
+		if (n.getSuper() != null) {
+			printer.print(" super ");
+			n.getSuper().accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(final UnknownType n, final Object arg) {
+		// Nothing to dump
+	}
+
+	@Override
+	public void visit(final FieldDeclaration n, final Object arg) {
+		printOrphanCommentsBeforeThisChildNode(n);
+
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+		n.getElementType().accept(this, arg);
+		for(ArrayBracketPair pair: n.getArrayBracketPairsAfterElementType()){
+			pair.accept(this, arg);
+		}
+
+		printer.print(" ");
+		for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+			final VariableDeclarator var = i.next();
+			var.accept(this, arg);
+			if (i.hasNext()) {
+				printer.print(", ");
+			}
+		}
+
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final VariableDeclarator n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getId().accept(this, arg);
+		if (n.getInit() != null) {
+			printer.print(" = ");
+			n.getInit().accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(final VariableDeclaratorId n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getName());
+		for(ArrayBracketPair pair: n.getArrayBracketPairsAfterId()){
+			pair.accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(final ArrayInitializerExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("{");
+		if (!isNullOrEmpty(n.getValues())) {
+			printer.print(" ");
+			for (final Iterator<Expression> i = n.getValues().iterator(); i.hasNext(); ) {
+				final Expression expr = i.next();
+				expr.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+			printer.print(" ");
+		}
+		printer.print("}");
+	}
+
+	@Override
+	public void visit(final VoidType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), false, arg);
+		printer.print("void");
+	}
+
+	@Override
+	public void visit(final ArrayAccessExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		printer.print("[");
+		n.getIndex().accept(this, arg);
+		printer.print("]");
+	}
+
+	@Override
+	public void visit(final ArrayCreationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("new ");
+		n.getType().accept(this, arg);
+		for (ArrayCreationLevel level : n.getLevels()) {
+			level.accept(this, arg);
+		}
+		if (n.getInitializer() != null) {
+			printer.print(" ");
+			n.getInitializer().accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(final AssignExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getTarget().accept(this, arg);
+		printer.print(" ");
+		switch (n.getOperator()) {
+			case assign:
+				printer.print("=");
+				break;
+			case and:
+				printer.print("&=");
+				break;
+			case or:
+				printer.print("|=");
+				break;
+			case xor:
+				printer.print("^=");
+				break;
+			case plus:
+				printer.print("+=");
+				break;
+			case minus:
+				printer.print("-=");
+				break;
+			case rem:
+				printer.print("%=");
+				break;
+			case slash:
+				printer.print("/=");
+				break;
+			case star:
+				printer.print("*=");
+				break;
+			case lShift:
+				printer.print("<<=");
+				break;
+			case rSignedShift:
+				printer.print(">>=");
+				break;
+			case rUnsignedShift:
+				printer.print(">>>=");
+				break;
+		}
+		printer.print(" ");
+		n.getValue().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final BinaryExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getLeft().accept(this, arg);
+		printer.print(" ");
+		switch (n.getOperator()) {
+			case or:
+				printer.print("||");
+				break;
+			case and:
+				printer.print("&&");
+				break;
+			case binOr:
+				printer.print("|");
+				break;
+			case binAnd:
+				printer.print("&");
+				break;
+			case xor:
+				printer.print("^");
+				break;
+			case equals:
+				printer.print("==");
+				break;
+			case notEquals:
+				printer.print("!=");
+				break;
+			case less:
+				printer.print("<");
+				break;
+			case greater:
+				printer.print(">");
+				break;
+			case lessEquals:
+				printer.print("<=");
+				break;
+			case greaterEquals:
+				printer.print(">=");
+				break;
+			case lShift:
+				printer.print("<<");
+				break;
+			case rSignedShift:
+				printer.print(">>");
+				break;
+			case rUnsignedShift:
+				printer.print(">>>");
+				break;
+			case plus:
+				printer.print("+");
+				break;
+			case minus:
+				printer.print("-");
+				break;
+			case times:
+				printer.print("*");
+				break;
+			case divide:
+				printer.print("/");
+				break;
+			case remainder:
+				printer.print("%");
+				break;
+		}
+		printer.print(" ");
+		n.getRight().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final CastExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("(");
+		n.getType().accept(this, arg);
+		printer.print(") ");
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final ClassExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+		printer.print(".class");
+	}
+
+	@Override
+	public void visit(final ConditionalExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		printer.print(" ? ");
+		n.getThenExpr().accept(this, arg);
+		printer.print(" : ");
+		n.getElseExpr().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final EnclosedExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("(");
+		if (n.getInner() != null) {
+			n.getInner().accept(this, arg);
+		}
+		printer.print(")");
+	}
+
+	@Override
+	public void visit(final FieldAccessExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getScope().accept(this, arg);
+		printer.print(".");
+		printer.print(n.getField());
+	}
+
+	@Override
+	public void visit(final InstanceOfExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+		printer.print(" instanceof ");
+		n.getType().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final CharLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("'");
+		printer.print(n.getValue());
+		printer.print("'");
+	}
+
+	@Override
+	public void visit(final DoubleLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override
+	public void visit(final IntegerLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override
+	public void visit(final LongLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override
+	public void visit(final IntegerLiteralMinValueExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override
+	public void visit(final LongLiteralMinValueExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override
+	public void visit(final StringLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("\"");
+		printer.print(n.getValue());
+		printer.print("\"");
+	}
+
+	@Override
+	public void visit(final BooleanLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(String.valueOf(n.getValue()));
+	}
+
+	@Override
+	public void visit(final NullLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("null");
+	}
+
+	@Override
+	public void visit(final ThisExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+			printer.print(".");
+		}
+		printer.print("this");
+	}
+
+	@Override
+	public void visit(final SuperExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+			printer.print(".");
+		}
+		printer.print("super");
+	}
+
+	@Override
+	public void visit(final MethodCallExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+			printer.print(".");
+		}
+		printTypeArgs(n, arg);
+		printer.print(n.getName());
+		printArguments(n.getArgs(), arg);
+	}
+
+	@Override
+	public void visit(final ObjectCreationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+			printer.print(".");
+		}
+
+		printer.print("new ");
+
+		printTypeArgs(n, arg);
+		if (!isNullOrEmpty(n.getTypeArguments())) {
+			printer.print(" ");
+		}
+
+		n.getType().accept(this, arg);
+
+		printArguments(n.getArgs(), arg);
+
+		if (n.getAnonymousClassBody() != null) {
+			printer.printLn(" {");
+			printer.indent();
+			printMembers(n.getAnonymousClassBody(), arg);
+			printer.unindent();
+			printer.print("}");
+		}
+	}
+
+	@Override
+	public void visit(final UnaryExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		switch (n.getOperator()) {
+			case positive:
+				printer.print("+");
+				break;
+			case negative:
+				printer.print("-");
+				break;
+			case inverse:
+				printer.print("~");
+				break;
+			case not:
+				printer.print("!");
+				break;
+			case preIncrement:
+				printer.print("++");
+				break;
+			case preDecrement:
+				printer.print("--");
+				break;
+			default:
+		}
+
+		n.getExpr().accept(this, arg);
+
+		switch (n.getOperator()) {
+			case posIncrement:
+				printer.print("++");
+				break;
+			case posDecrement:
+				printer.print("--");
+				break;
+			default:
+		}
+	}
+
+	@Override
+	public void visit(final ConstructorDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		printTypeParameters(n.getTypeParameters(), arg);
+		if (!n.getTypeParameters().isEmpty()) {
+			printer.print(" ");
+		}
+		printer.print(n.getName());
+
+		printer.print("(");
+		if (!n.getParameters().isEmpty()) {
+			for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+				final Parameter p = i.next();
+				p.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+
+		if (!isNullOrEmpty(n.getThrows())) {
+			printer.print(" throws ");
+			for (final Iterator<ReferenceType> i = n.getThrows().iterator(); i.hasNext(); ) {
+				final ReferenceType name = i.next();
+				name.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(" ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final MethodDeclaration n, final Object arg) {
+		printOrphanCommentsBeforeThisChildNode(n);
+
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+		if (n.isDefault()) {
+			printer.print("default ");
+		}
+		printTypeParameters(n.getTypeParameters(), arg);
+		if (!isNullOrEmpty(n.getTypeParameters())) {
+			printer.print(" ");
+		}
+
+		n.getElementType().accept(this, arg);
+		for(ArrayBracketPair pair: n.getArrayBracketPairsAfterElementType()){
+			pair.accept(this, arg);
+		}
+		printer.print(" ");
+		printer.print(n.getName());
+
+		printer.print("(");
+		if (!isNullOrEmpty(n.getParameters())) {
+			for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+				final Parameter p = i.next();
+				p.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+
+		for(ArrayBracketPair pair: n.getArrayBracketPairsAfterParameterList()){
+			pair.accept(this, arg);
+		}
+
+		if (!isNullOrEmpty(n.getThrows())) {
+			printer.print(" throws ");
+			for (final Iterator<ReferenceType> i = n.getThrows().iterator(); i.hasNext(); ) {
+				final ReferenceType name = i.next();
+				name.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		if (n.getBody() == null) {
+			printer.print(";");
+		} else {
+			printer.print(" ");
+			n.getBody().accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(final Parameter n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), false, arg);
+		printModifiers(n.getModifiers());
+		if (n.getElementType() != null) {
+			n.getElementType().accept(this, arg);
+		}
+		for(ArrayBracketPair pair: n.getArrayBracketPairsAfterElementType()){
+			pair.accept(this, arg);
+		}
+		if (n.isVarArgs()) {
+			printer.print("...");
+		}
+		printer.print(" ");
+		n.getId().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final ExplicitConstructorInvocationStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.isThis()) {
+			printTypeArgs(n, arg);
+			printer.print("this");
+		} else {
+			if (n.getExpr() != null) {
+				n.getExpr().accept(this, arg);
+				printer.print(".");
+			}
+			printTypeArgs(n, arg);
+			printer.print("super");
+		}
+		printArguments(n.getArgs(), arg);
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final VariableDeclarationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), false, arg);
+		printModifiers(n.getModifiers());
+
+		n.getElementType().accept(this, arg);
+		for(ArrayBracketPair pair: n.getArrayBracketPairsAfterElementType()){
+			pair.accept(this, arg);
+		}
+		printer.print(" ");
+
+		for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+			final VariableDeclarator v = i.next();
+			v.accept(this, arg);
+			if (i.hasNext()) {
+				printer.print(", ");
+			}
+		}
+	}
+
+	@Override
+	public void visit(final TypeDeclarationStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getTypeDeclaration().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final AssertStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("assert ");
+		n.getCheck().accept(this, arg);
+		if (n.getMessage() != null) {
+			printer.print(" : ");
+			n.getMessage().accept(this, arg);
+		}
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final BlockStmt n, final Object arg) {
+		printOrphanCommentsBeforeThisChildNode(n);
+		printJavaComment(n.getComment(), arg);
+		printer.printLn("{");
+		if (n.getStmts() != null) {
+			printer.indent();
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+				printer.printLn();
+			}
+			printer.unindent();
+		}
+		printOrphanCommentsEnding(n);
+		printer.print("}");
+
+	}
+
+	@Override
+	public void visit(final LabeledStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getLabel());
+		printer.print(": ");
+		n.getStmt().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final EmptyStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final ExpressionStmt n, final Object arg) {
+		printOrphanCommentsBeforeThisChildNode(n);
+		printJavaComment(n.getComment(), arg);
+		n.getExpression().accept(this, arg);
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final SwitchStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("switch(");
+		n.getSelector().accept(this, arg);
+		printer.printLn(") {");
+		if (n.getEntries() != null) {
+			printer.indent();
+			for (final SwitchEntryStmt e : n.getEntries()) {
+				e.accept(this, arg);
+			}
+			printer.unindent();
+		}
+		printer.print("}");
+
+	}
+
+	@Override
+	public void visit(final SwitchEntryStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getLabel() != null) {
+			printer.print("case ");
+			n.getLabel().accept(this, arg);
+			printer.print(":");
+		} else {
+			printer.print("default:");
+		}
+		printer.printLn();
+		printer.indent();
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+				printer.printLn();
+			}
+		}
+		printer.unindent();
+	}
+
+	@Override
+	public void visit(final BreakStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("break");
+		if (n.getId() != null) {
+			printer.print(" ");
+			printer.print(n.getId());
+		}
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final ReturnStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("return");
+		if (n.getExpr() != null) {
+			printer.print(" ");
+			n.getExpr().accept(this, arg);
+		}
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final EnumDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		printer.print("enum ");
+		printer.print(n.getName());
+
+		if (!n.getImplements().isEmpty()) {
+			printer.print(" implements ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getImplements().iterator(); i.hasNext(); ) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+
+		printer.printLn(" {");
+		printer.indent();
+		if (n.getEntries() != null) {
+			printer.printLn();
+			for (final Iterator<EnumConstantDeclaration> i = n.getEntries().iterator(); i.hasNext(); ) {
+				final EnumConstantDeclaration e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		if (!n.getMembers().isEmpty()) {
+			printer.printLn(";");
+			printMembers(n.getMembers(), arg);
+		} else {
+			if (!n.getEntries().isEmpty()) {
+				printer.printLn();
+			}
+		}
+		printer.unindent();
+		printer.print("}");
+	}
+
+	@Override
+	public void visit(final EnumConstantDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printer.print(n.getName());
+
+		if (!n.getArgs().isEmpty()) {
+			printArguments(n.getArgs(), arg);
+		}
+
+		if (!n.getClassBody().isEmpty()) {
+			printer.printLn(" {");
+			printer.indent();
+			printMembers(n.getClassBody(), arg);
+			printer.unindent();
+			printer.printLn("}");
+		}
+	}
+
+	@Override
+	public void visit(final EmptyMemberDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final InitializerDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.isStatic()) {
+			printer.print("static ");
+		}
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final IfStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("if (");
+		n.getCondition().accept(this, arg);
+		final boolean thenBlock = n.getThenStmt() instanceof BlockStmt;
+		if (thenBlock) // block statement should start on the same line
+			printer.print(") ");
+		else {
+			printer.printLn(")");
+			printer.indent();
+		}
+		n.getThenStmt().accept(this, arg);
+		if (!thenBlock)
+			printer.unindent();
+		if (n.getElseStmt() != null) {
+			if (thenBlock)
+				printer.print(" ");
+			else
+				printer.printLn();
+			final boolean elseIf = n.getElseStmt() instanceof IfStmt;
+			final boolean elseBlock = n.getElseStmt() instanceof BlockStmt;
+			if (elseIf || elseBlock) // put chained if and start of block statement on a same level
+				printer.print("else ");
+			else {
+				printer.printLn("else");
+				printer.indent();
+			}
+			n.getElseStmt().accept(this, arg);
+			if (!(elseIf || elseBlock))
+				printer.unindent();
+		}
+	}
+
+	@Override
+	public void visit(final WhileStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("while (");
+		n.getCondition().accept(this, arg);
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final ContinueStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("continue");
+		if (n.getId() != null) {
+			printer.print(" ");
+			printer.print(n.getId());
+		}
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final DoStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("do ");
+		n.getBody().accept(this, arg);
+		printer.print(" while (");
+		n.getCondition().accept(this, arg);
+		printer.print(");");
+	}
+
+	@Override
+	public void visit(final ForeachStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("for (");
+		n.getVariable().accept(this, arg);
+		printer.print(" : ");
+		n.getIterable().accept(this, arg);
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final ForStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("for (");
+		if (n.getInit() != null) {
+			for (final Iterator<Expression> i = n.getInit().iterator(); i.hasNext(); ) {
+				final Expression e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print("; ");
+		if (n.getCompare() != null) {
+			n.getCompare().accept(this, arg);
+		}
+		printer.print("; ");
+		if (n.getUpdate() != null) {
+			for (final Iterator<Expression> i = n.getUpdate().iterator(); i.hasNext(); ) {
+				final Expression e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final ThrowStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("throw ");
+		n.getExpr().accept(this, arg);
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final SynchronizedStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("synchronized (");
+		n.getExpr().accept(this, arg);
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final TryStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("try ");
+		if (!n.getResources().isEmpty()) {
+			printer.print("(");
+			Iterator<VariableDeclarationExpr> resources = n.getResources().iterator();
+			boolean first = true;
+			while (resources.hasNext()) {
+				visit(resources.next(), arg);
+				if (resources.hasNext()) {
+					printer.print(";");
+					printer.printLn();
+					if (first) {
+						printer.indent();
+					}
+				}
+				first = false;
+			}
+			if (n.getResources().size() > 1) {
+				printer.unindent();
+			}
+			printer.print(") ");
+		}
+		n.getTryBlock().accept(this, arg);
+		if (n.getCatchs() != null) {
+			for (final CatchClause c : n.getCatchs()) {
+				c.accept(this, arg);
+			}
+		}
+		if (n.getFinallyBlock() != null) {
+			printer.print(" finally ");
+			n.getFinallyBlock().accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(final CatchClause n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(" catch (");
+		n.getParam().accept(this, arg);
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+
+	}
+
+	@Override
+	public void visit(final AnnotationDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		printer.print("@interface ");
+		printer.print(n.getName());
+		printer.printLn(" {");
+		printer.indent();
+		if (n.getMembers() != null) {
+			printMembers(n.getMembers(), arg);
+		}
+		printer.unindent();
+		printer.print("}");
+	}
+
+	@Override
+	public void visit(final AnnotationMemberDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		n.getType().accept(this, arg);
+		printer.print(" ");
+		printer.print(n.getName());
+		printer.print("()");
+		if (n.getDefaultValue() != null) {
+			printer.print(" default ");
+			n.getDefaultValue().accept(this, arg);
+		}
+		printer.print(";");
+	}
+
+	@Override
+	public void visit(final MarkerAnnotationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("@");
+		n.getName().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final SingleMemberAnnotationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("@");
+		n.getName().accept(this, arg);
+		printer.print("(");
+		n.getMemberValue().accept(this, arg);
+		printer.print(")");
+	}
+
+	@Override
+	public void visit(final NormalAnnotationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("@");
+		n.getName().accept(this, arg);
+		printer.print("(");
+		if (n.getPairs() != null) {
+			for (final Iterator<MemberValuePair> i = n.getPairs().iterator(); i.hasNext(); ) {
+				final MemberValuePair m = i.next();
+				m.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+	}
+
+	@Override
+	public void visit(final MemberValuePair n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getName());
+		printer.print(" = ");
+		n.getValue().accept(this, arg);
+	}
+
+	@Override
+	public void visit(final LineComment n, final Object arg) {
+		if (!this.printComments) {
+			return;
+		}
+		printer.print("//");
+		String tmp = n.getContent();
+		tmp = tmp.replace('\r', ' ');
+		tmp = tmp.replace('\n', ' ');
+		printer.printLn(tmp);
+	}
+
+	@Override
+	public void visit(final BlockComment n, final Object arg) {
+		if (!this.printComments) {
+			return;
+		}
+		printer.print("/*");
+		printer.print(n.getContent());
+		printer.printLn("*/");
+	}
+
+	@Override
+	public void visit(LambdaExpr n, Object arg) {
+		printJavaComment(n.getComment(), arg);
+
+		final List<Parameter> parameters = n.getParameters();
+		final boolean printPar = n.isParametersEnclosed();
+
+		if (printPar) {
+			printer.print("(");
+		}
+		if (parameters != null) {
+			for (Iterator<Parameter> i = parameters.iterator(); i.hasNext(); ) {
+				Parameter p = i.next();
+				p.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		if (printPar) {
+			printer.print(")");
+		}
+
+		printer.print(" -> ");
+		final Statement body = n.getBody();
+		if (body instanceof ExpressionStmt) {
+			// Print the expression directly
+			((ExpressionStmt) body).getExpression().accept(this, arg);
+		} else {
+			body.accept(this, arg);
+		}
+	}
+
+
+	@Override
+	public void visit(MethodReferenceExpr n, Object arg) {
+		printJavaComment(n.getComment(), arg);
+		Expression scope = n.getScope();
+		String identifier = n.getIdentifier();
+		if (scope != null) {
+			n.getScope().accept(this, arg);
+		}
+
+		printer.print("::");
+		printTypeArgs(n, arg);
+		if (identifier != null) {
+			printer.print(identifier);
+		}
+
+	}
+
+	@Override
+	public void visit(TypeExpr n, Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getType() != null) {
+			n.getType().accept(this, arg);
+		}
+	}
+
+	@Override
+	public void visit(ArrayBracketPair arrayBracketPair, Object arg) {
+		printAnnotations(arrayBracketPair.getAnnotations(), true, arg);
+		printer.print("[]");
+	}
+
+	private void printOrphanCommentsBeforeThisChildNode(final Node node) {
+		if (node instanceof Comment) return;
+
+		Node parent = node.getParentNode();
+		if (parent == null) return;
+		List<Node> everything = new LinkedList<>();
+		everything.addAll(parent.getChildrenNodes());
+		sortByBeginPosition(everything);
+		int positionOfTheChild = -1;
+		for (int i = 0; i < everything.size(); i++) {
+			if (everything.get(i) == node) positionOfTheChild = i;
+		}
+		if (positionOfTheChild == -1) throw new RuntimeException("My index not found!!! " + node);
+		int positionOfPreviousChild = -1;
+		for (int i = positionOfTheChild - 1; i >= 0 && positionOfPreviousChild == -1; i--) {
+			if (!(everything.get(i) instanceof Comment)) positionOfPreviousChild = i;
+		}
+		for (int i = positionOfPreviousChild + 1; i < positionOfTheChild; i++) {
+			Node nodeToPrint = everything.get(i);
+			if (!(nodeToPrint instanceof Comment))
+				throw new RuntimeException("Expected comment, instead " + nodeToPrint.getClass() + ". Position of previous child: " + positionOfPreviousChild + ", position of child " + positionOfTheChild);
+			nodeToPrint.accept(this, null);
+		}
+	}
+
+
+	private void printOrphanCommentsEnding(final Node node) {
+		List<Node> everything = new LinkedList<>();
+		everything.addAll(node.getChildrenNodes());
+		sortByBeginPosition(everything);
+		if (everything.isEmpty()) {
+			return;
+		}
+
+		int commentsAtEnd = 0;
+		boolean findingComments = true;
+		while (findingComments && commentsAtEnd < everything.size()) {
+			Node last = everything.get(everything.size() - 1 - commentsAtEnd);
+			findingComments = (last instanceof Comment);
+			if (findingComments) {
+				commentsAtEnd++;
+			}
+		}
+		for (int i = 0; i < commentsAtEnd; i++) {
+			everything.get(everything.size() - commentsAtEnd + i).accept(this, null);
+		}
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/EqualsVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/EqualsVisitor.java
new file mode 100644
index 0000000..e10184c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/EqualsVisitor.java
@@ -0,0 +1,1514 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import java.util.List;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.ArrayAccessExpr;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.ArrayInitializerExpr;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.CharLiteralExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
+import com.github.javaparser.ast.expr.ConditionalExpr;
+import com.github.javaparser.ast.expr.DoubleLiteralExpr;
+import com.github.javaparser.ast.expr.EnclosedExpr;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.InstanceOfExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
+import com.github.javaparser.ast.expr.LongLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.MemberValuePair;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.NullLiteralExpr;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.expr.QualifiedNameExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.SuperExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.expr.TypeExpr;
+import com.github.javaparser.ast.expr.UnaryExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class EqualsVisitor implements GenericVisitor<Boolean, Node> {
+
+	private static final EqualsVisitor SINGLETON = new EqualsVisitor();
+
+	public static boolean equals(final Node n1, final Node n2) {
+		return SINGLETON.nodeEquals(n1, n2);
+	}
+
+	private EqualsVisitor() {
+		// hide constructor
+	}
+
+    /**
+     * Check for equality that can be applied to each kind of node,
+     * to not repeat it in every method we store that here.
+     */
+    private boolean commonNodeEquality(Node n1, Node n2) {
+        if (!nodeEquals(n1.getComment(), n2.getComment())) {
+            return false;
+        }
+		return nodesEquals(n1.getOrphanComments(), n2.getOrphanComments());
+	}
+
+	private <T extends Node> boolean nodesEquals(final List<T> nodes1, final List<T> nodes2) {
+		if (nodes1 == null) {
+			return nodes2 == null;
+		} else if (nodes2 == null) {
+			return false;
+		}
+		if (nodes1.size() != nodes2.size()) {
+			return false;
+		}
+		for (int i = 0; i < nodes1.size(); i++) {
+			if (!nodeEquals(nodes1.get(i), nodes2.get(i))) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	private <T extends Node> boolean nodeEquals(final T n1, final T n2) {
+		if (n1 == n2) {
+			return true;
+		}
+		if (n1 == null || n2 == null) {
+			return false;
+		}
+		if (n1.getClass() != n2.getClass()) {
+			return false;
+		}
+        if (!commonNodeEquality(n1, n2)){
+            return false;
+        }
+		return n1.accept(this, n2);
+	}
+
+	private boolean objEquals(final Object n1, final Object n2) {
+		if (n1 == n2) {
+			return true;
+		}
+		if (n1 == null || n2 == null) {
+			return false;
+		}
+		return n1.equals(n2);
+	}
+
+	@Override public Boolean visit(final CompilationUnit n1, final Node arg) {
+		final CompilationUnit n2 = (CompilationUnit) arg;
+
+		if (!nodeEquals(n1.getPackage(), n2.getPackage())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getImports(), n2.getImports())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypes(), n2.getTypes())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getComments(), n2.getComments())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final PackageDeclaration n1, final Node arg) {
+		final PackageDeclaration n2 = (PackageDeclaration) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ImportDeclaration n1, final Node arg) {
+		final ImportDeclaration n2 = (ImportDeclaration) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final TypeParameter n1, final Node arg) {
+		final TypeParameter n2 = (TypeParameter) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeBound(), n2.getTypeBound())) {
+			return false;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override public Boolean visit(final LineComment n1, final Node arg) {
+		final LineComment n2 = (LineComment) arg;
+
+		if (!objEquals(n1.getContent(), n2.getContent())) {
+			return false;
+		}
+
+        if (!objEquals(n1.getBegin().line, n2.getBegin().line)) {
+      		return false;
+      	}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final BlockComment n1, final Node arg) {
+		final BlockComment n2 = (BlockComment) arg;
+
+		if (!objEquals(n1.getContent(), n2.getContent())) {
+			return false;
+		}
+
+        if (!objEquals(n1.getBegin().line, n2.getBegin().line)) {
+      			return false;
+      	}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ClassOrInterfaceDeclaration n1, final Node arg) {
+		final ClassOrInterfaceDeclaration n2 = (ClassOrInterfaceDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (n1.isInterface() != n2.isInterface()) {
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeParameters(), n2.getTypeParameters())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getExtends(), n2.getExtends())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getImplements(), n2.getImplements())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getMembers(), n2.getMembers())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final EnumDeclaration n1, final Node arg) {
+		final EnumDeclaration n2 = (EnumDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getImplements(), n2.getImplements())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getEntries(), n2.getEntries())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getMembers(), n2.getMembers())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final EmptyTypeDeclaration n1, final Node arg) {
+		return true;
+	}
+
+	@Override public Boolean visit(final EnumConstantDeclaration n1, final Node arg) {
+		final EnumConstantDeclaration n2 = (EnumConstantDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getClassBody(), n2.getClassBody())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final AnnotationDeclaration n1, final Node arg) {
+		final AnnotationDeclaration n2 = (AnnotationDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getMembers(), n2.getMembers())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final AnnotationMemberDeclaration n1, final Node arg) {
+		final AnnotationMemberDeclaration n2 = (AnnotationMemberDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getDefaultValue(), n2.getDefaultValue())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final FieldDeclaration n1, final Node arg) {
+		final FieldDeclaration n2 = (FieldDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getElementType(), n2.getElementType())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getVariables(), n2.getVariables())) {
+			return false;
+		}
+
+		if(!nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType())){
+			return false;
+		}
+		
+		return true;
+	}
+
+	@Override public Boolean visit(final VariableDeclarator n1, final Node arg) {
+		final VariableDeclarator n2 = (VariableDeclarator) arg;
+
+		if (!nodeEquals(n1.getId(), n2.getId())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getInit(), n2.getInit())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final VariableDeclaratorId n1, final Node arg) {
+		final VariableDeclaratorId n2 = (VariableDeclaratorId) arg;
+
+		if(!nodesEquals(n1.getArrayBracketPairsAfterId(), n2.getArrayBracketPairsAfterId())){
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ConstructorDeclaration n1, final Node arg) {
+		final ConstructorDeclaration n2 = (ConstructorDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getParameters(), n2.getParameters())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getThrows(), n2.getThrows())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeParameters(), n2.getTypeParameters())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final MethodDeclaration n1, final Node arg) {
+		final MethodDeclaration n2 = (MethodDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if(!nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType())){
+			return false;
+		}
+
+		if(!nodesEquals(n1.getArrayBracketPairsAfterParameterList(), n2.getArrayBracketPairsAfterParameterList())){
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getElementType(), n2.getElementType())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getParameters(), n2.getParameters())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getThrows(), n2.getThrows())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeParameters(), n2.getTypeParameters())) {
+			return false;
+		}
+		if(n1.isDefault() != n2.isDefault()){
+			return false;
+		}
+		return true;
+	}
+	
+	@Override public Boolean visit(final Parameter n1, final Node arg) {
+		final Parameter n2 = (Parameter) arg;
+		if (!nodeEquals(n1.getElementType(), n2.getElementType())) {
+			return false;
+		}
+
+		if(!nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType())){
+			return false;
+		}
+
+		if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getId(), n2.getId())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		return true;
+	}
+	
+	@Override public Boolean visit(final EmptyMemberDeclaration n1, final Node arg) {
+		return true;
+	}
+
+	@Override public Boolean visit(final InitializerDeclaration n1, final Node arg) {
+		final InitializerDeclaration n2 = (InitializerDeclaration) arg;
+
+		if (!nodeEquals(n1.getBlock(), n2.getBlock())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final JavadocComment n1, final Node arg) {
+		final JavadocComment n2 = (JavadocComment) arg;
+
+		if (!objEquals(n1.getContent(), n2.getContent())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ClassOrInterfaceType n1, final Node arg) {
+		final ClassOrInterfaceType n2 = (ClassOrInterfaceType) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeArguments(), n2.getTypeArguments())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final PrimitiveType n1, final Node arg) {
+		final PrimitiveType n2 = (PrimitiveType) arg;
+
+		if (n1.getType() != n2.getType()) {
+			return false;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public Boolean visit(ArrayType n1, Node arg) {
+		final ArrayType n2 = (ArrayType) arg;
+
+		if (!nodeEquals(n1.getComponentType(), n2.getComponentType())) {
+			return false;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override
+	public Boolean visit(ArrayCreationLevel n1, Node arg) {
+		final ArrayCreationLevel n2 = (ArrayCreationLevel) arg;
+
+		if (!nodeEquals(n1.getDimension(), n2.getDimension())) {
+			return false;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override public Boolean visit(final IntersectionType n1, final Node arg) {
+        final IntersectionType n2 = (IntersectionType) arg;
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+        List<ReferenceType> n1Elements = n1.getElements();
+        List<ReferenceType> n2Elements = n2.getElements();
+
+        if (n1Elements !=null && n2Elements != null) {
+            if(n1Elements.size() != n2Elements.size()){
+                return false;
+            }
+            else{
+                int i = 0;
+                for(ReferenceType aux: n1Elements){
+                    if(aux.accept(this, n2Elements.get(i))) {
+                        return false;
+                    }
+                    i++;
+                }
+            }
+        }  else if (n1Elements != n2Elements){
+            return false;
+        }
+        return true;
+    }
+
+    @Override public Boolean visit(final UnionType n1, final Node arg) {
+        final UnionType n2 = (UnionType) arg;
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+        List<ReferenceType> n1Elements = n1.getElements();
+        List<ReferenceType> n2Elements = n2.getElements();
+
+        if (n1Elements !=null && n2Elements != null) {
+            if(n1Elements.size() != n2Elements.size()){
+                return false;
+            }
+            else{
+                int i = 0;
+                for(ReferenceType aux: n1Elements){
+                    if(aux.accept(this, n2Elements.get(i))) {
+                        return false;
+                    }
+                    i++;
+                }
+            }
+        }  else if (n1Elements != n2Elements){
+            return false;
+        }
+        return true;
+    }
+
+	@Override
+	public Boolean visit(VoidType n1, Node arg) {
+		VoidType n2 = (VoidType) arg;
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override public Boolean visit(final WildcardType n1, final Node arg) {
+		final WildcardType n2 = (WildcardType) arg;
+
+		if (!nodeEquals(n1.getExtends(), n2.getExtends())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getSuper(), n2.getSuper())) {
+			return false;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+		return true;
+	}
+
+	@Override public Boolean visit(final UnknownType n1, final Node arg) {
+		return true;
+	}
+
+	@Override public Boolean visit(final ArrayAccessExpr n1, final Node arg) {
+		final ArrayAccessExpr n2 = (ArrayAccessExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getIndex(), n2.getIndex())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ArrayCreationExpr n1, final Node arg) {
+		final ArrayCreationExpr n2 = (ArrayCreationExpr) arg;
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getLevels(), n2.getLevels())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getInitializer(), n2.getInitializer())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ArrayInitializerExpr n1, final Node arg) {
+		final ArrayInitializerExpr n2 = (ArrayInitializerExpr) arg;
+
+		if (!nodesEquals(n1.getValues(), n2.getValues())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final AssignExpr n1, final Node arg) {
+		final AssignExpr n2 = (AssignExpr) arg;
+
+		if (n1.getOperator() != n2.getOperator()) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getTarget(), n2.getTarget())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final BinaryExpr n1, final Node arg) {
+		final BinaryExpr n2 = (BinaryExpr) arg;
+
+		if (n1.getOperator() != n2.getOperator()) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getLeft(), n2.getLeft())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getRight(), n2.getRight())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final CastExpr n1, final Node arg) {
+		final CastExpr n2 = (CastExpr) arg;
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ClassExpr n1, final Node arg) {
+		final ClassExpr n2 = (ClassExpr) arg;
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ConditionalExpr n1, final Node arg) {
+		final ConditionalExpr n2 = (ConditionalExpr) arg;
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getThenExpr(), n2.getThenExpr())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getElseExpr(), n2.getElseExpr())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final EnclosedExpr n1, final Node arg) {
+		final EnclosedExpr n2 = (EnclosedExpr) arg;
+
+		if (!nodeEquals(n1.getInner(), n2.getInner())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final FieldAccessExpr n1, final Node arg) {
+		final FieldAccessExpr n2 = (FieldAccessExpr) arg;
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return false;
+		}
+
+		if (!objEquals(n1.getField(), n2.getField())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeArguments(), n2.getTypeArguments())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final InstanceOfExpr n1, final Node arg) {
+		final InstanceOfExpr n2 = (InstanceOfExpr) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final StringLiteralExpr n1, final Node arg) {
+		final StringLiteralExpr n2 = (StringLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final IntegerLiteralExpr n1, final Node arg) {
+		final IntegerLiteralExpr n2 = (IntegerLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final LongLiteralExpr n1, final Node arg) {
+		final LongLiteralExpr n2 = (LongLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final IntegerLiteralMinValueExpr n1, final Node arg) {
+		final IntegerLiteralMinValueExpr n2 = (IntegerLiteralMinValueExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final LongLiteralMinValueExpr n1, final Node arg) {
+		final LongLiteralMinValueExpr n2 = (LongLiteralMinValueExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final CharLiteralExpr n1, final Node arg) {
+		final CharLiteralExpr n2 = (CharLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final DoubleLiteralExpr n1, final Node arg) {
+		final DoubleLiteralExpr n2 = (DoubleLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final BooleanLiteralExpr n1, final Node arg) {
+		final BooleanLiteralExpr n2 = (BooleanLiteralExpr) arg;
+
+		if (n1.getValue() != n2.getValue()) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final NullLiteralExpr n1, final Node arg) {
+		return true;
+	}
+
+	@Override public Boolean visit(final MethodCallExpr n1, final Node arg) {
+		final MethodCallExpr n2 = (MethodCallExpr) arg;
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeArguments(), n2.getTypeArguments())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final NameExpr n1, final Node arg) {
+		final NameExpr n2 = (NameExpr) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ObjectCreationExpr n1, final Node arg) {
+		final ObjectCreationExpr n2 = (ObjectCreationExpr) arg;
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnonymousClassBody(), n2.getAnonymousClassBody())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeArguments(), n2.getTypeArguments())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final QualifiedNameExpr n1, final Node arg) {
+		final QualifiedNameExpr n2 = (QualifiedNameExpr) arg;
+
+		if (!nodeEquals(n1.getQualifier(), n2.getQualifier())) {
+			return false;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ThisExpr n1, final Node arg) {
+		final ThisExpr n2 = (ThisExpr) arg;
+
+		if (!nodeEquals(n1.getClassExpr(), n2.getClassExpr())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final SuperExpr n1, final Node arg) {
+		final SuperExpr n2 = (SuperExpr) arg;
+
+		if (!nodeEquals(n1.getClassExpr(), n2.getClassExpr())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final UnaryExpr n1, final Node arg) {
+		final UnaryExpr n2 = (UnaryExpr) arg;
+
+		if (n1.getOperator() != n2.getOperator()) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final VariableDeclarationExpr n1, final Node arg) {
+		final VariableDeclarationExpr n2 = (VariableDeclarationExpr) arg;
+
+        if (!n1.getModifiers().equals(n2.getModifiers())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getElementType(), n2.getElementType())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getVariables(), n2.getVariables())) {
+			return false;
+		}
+
+		if(!nodesEquals(n1.getArrayBracketPairsAfterElementType(), n2.getArrayBracketPairsAfterElementType())){
+			return false;
+		}
+		
+		return true;
+	}
+
+	@Override public Boolean visit(final MarkerAnnotationExpr n1, final Node arg) {
+		final MarkerAnnotationExpr n2 = (MarkerAnnotationExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final SingleMemberAnnotationExpr n1, final Node arg) {
+		final SingleMemberAnnotationExpr n2 = (SingleMemberAnnotationExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getMemberValue(), n2.getMemberValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final NormalAnnotationExpr n1, final Node arg) {
+		final NormalAnnotationExpr n2 = (NormalAnnotationExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getPairs(), n2.getPairs())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final MemberValuePair n1, final Node arg) {
+		final MemberValuePair n2 = (MemberValuePair) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getValue(), n2.getValue())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ExplicitConstructorInvocationStmt n1, final Node arg) {
+		final ExplicitConstructorInvocationStmt n2 = (ExplicitConstructorInvocationStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getTypeArguments(), n2.getTypeArguments())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final TypeDeclarationStmt n1, final Node arg) {
+		final TypeDeclarationStmt n2 = (TypeDeclarationStmt) arg;
+
+		if (!nodeEquals(n1.getTypeDeclaration(), n2.getTypeDeclaration())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final AssertStmt n1, final Node arg) {
+		final AssertStmt n2 = (AssertStmt) arg;
+
+		if (!nodeEquals(n1.getCheck(), n2.getCheck())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getMessage(), n2.getMessage())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final BlockStmt n1, final Node arg) {
+		final BlockStmt n2 = (BlockStmt) arg;
+
+		if (!nodesEquals(n1.getStmts(), n2.getStmts())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final LabeledStmt n1, final Node arg) {
+		final LabeledStmt n2 = (LabeledStmt) arg;
+
+		if (!nodeEquals(n1.getStmt(), n2.getStmt())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final EmptyStmt n1, final Node arg) {
+		return true;
+	}
+
+	@Override public Boolean visit(final ExpressionStmt n1, final Node arg) {
+		final ExpressionStmt n2 = (ExpressionStmt) arg;
+
+		if (!nodeEquals(n1.getExpression(), n2.getExpression())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final SwitchStmt n1, final Node arg) {
+		final SwitchStmt n2 = (SwitchStmt) arg;
+
+		if (!nodeEquals(n1.getSelector(), n2.getSelector())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getEntries(), n2.getEntries())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final SwitchEntryStmt n1, final Node arg) {
+		final SwitchEntryStmt n2 = (SwitchEntryStmt) arg;
+
+		if (!nodeEquals(n1.getLabel(), n2.getLabel())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getStmts(), n2.getStmts())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final BreakStmt n1, final Node arg) {
+		final BreakStmt n2 = (BreakStmt) arg;
+
+		if (!objEquals(n1.getId(), n2.getId())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ReturnStmt n1, final Node arg) {
+		final ReturnStmt n2 = (ReturnStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final IfStmt n1, final Node arg) {
+		final IfStmt n2 = (IfStmt) arg;
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getThenStmt(), n2.getThenStmt())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getElseStmt(), n2.getElseStmt())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final WhileStmt n1, final Node arg) {
+		final WhileStmt n2 = (WhileStmt) arg;
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ContinueStmt n1, final Node arg) {
+		final ContinueStmt n2 = (ContinueStmt) arg;
+
+		if (!objEquals(n1.getId(), n2.getId())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final DoStmt n1, final Node arg) {
+		final DoStmt n2 = (DoStmt) arg;
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ForeachStmt n1, final Node arg) {
+		final ForeachStmt n2 = (ForeachStmt) arg;
+
+		if (!nodeEquals(n1.getVariable(), n2.getVariable())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getIterable(), n2.getIterable())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ForStmt n1, final Node arg) {
+		final ForStmt n2 = (ForStmt) arg;
+
+		if (!nodesEquals(n1.getInit(), n2.getInit())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getCompare(), n2.getCompare())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getUpdate(), n2.getUpdate())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final ThrowStmt n1, final Node arg) {
+		final ThrowStmt n2 = (ThrowStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final SynchronizedStmt n1, final Node arg) {
+		final SynchronizedStmt n2 = (SynchronizedStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final TryStmt n1, final Node arg) {
+		final TryStmt n2 = (TryStmt) arg;
+
+		if (!nodeEquals(n1.getTryBlock(), n2.getTryBlock())) {
+			return false;
+		}
+
+		if (!nodesEquals(n1.getCatchs(), n2.getCatchs())) {
+			return false;
+		}
+		
+		if(!nodesEquals(n1.getResources(), n2.getResources())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getFinallyBlock(), n2.getFinallyBlock())) {
+			return false;
+		}
+
+		return true;
+	}
+
+	@Override public Boolean visit(final CatchClause n1, final Node arg) {
+		final CatchClause n2 = (CatchClause) arg;
+
+		if (!nodeEquals(n1.getParam(), n2.getParam())) {
+			return false;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return false;
+		}
+
+		return true;
+	}
+
+    @Override
+    public Boolean visit(LambdaExpr n1, Node arg) {
+        LambdaExpr n2 = (LambdaExpr) arg;
+        if (!nodesEquals(n1.getParameters(), n2.getParameters())) {
+            return false;
+        }
+        if(n1.isParametersEnclosed() != n2.isParametersEnclosed()){
+            return false;
+        }
+        if (!nodeEquals(n1.getBody(), n2.getBody())) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean visit(MethodReferenceExpr n1, Node arg) {
+        MethodReferenceExpr n2 = (MethodReferenceExpr) arg;
+        if (!nodeEquals(n1.getScope(), n2.getScope())) {
+            return false;
+        }
+	    if (!nodesEquals(n1.getTypeArguments(), n2.getTypeArguments())) {
+            return false;
+        }
+        if (!objEquals(n1.getIdentifier(), n2.getIdentifier())) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean visit(TypeExpr n, Node arg) {
+        TypeExpr n2 = (TypeExpr) arg;
+        if (!nodeEquals(n.getType(), n2.getType())) {
+            return false;
+        }
+        return true;
+    }
+
+	@Override
+	public Boolean visit(ArrayBracketPair n1, Node arg) {
+		ArrayBracketPair n2 = (ArrayBracketPair) arg;
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return false;
+		}
+
+		return true;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/GenericVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/GenericVisitor.java
new file mode 100644
index 0000000..9f4e9bc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/GenericVisitor.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * A visitor that has a return value.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public interface GenericVisitor<R, A> {
+
+	//- Compilation Unit ----------------------------------
+
+	R visit(CompilationUnit n, A arg);
+
+	R visit(PackageDeclaration n, A arg);
+
+	R visit(ImportDeclaration n, A arg);
+
+	R visit(TypeParameter n, A arg);
+
+	R visit(LineComment n, A arg);
+
+	R visit(BlockComment n, A arg);
+
+	//- Body ----------------------------------------------
+
+	R visit(ClassOrInterfaceDeclaration n, A arg);
+
+	R visit(EnumDeclaration n, A arg);
+
+	R visit(EmptyTypeDeclaration n, A arg);
+
+	R visit(EnumConstantDeclaration n, A arg);
+
+	R visit(AnnotationDeclaration n, A arg);
+
+	R visit(AnnotationMemberDeclaration n, A arg);
+
+	R visit(FieldDeclaration n, A arg);
+
+	R visit(VariableDeclarator n, A arg);
+
+	R visit(VariableDeclaratorId n, A arg);
+
+	R visit(ConstructorDeclaration n, A arg);
+
+	R visit(MethodDeclaration n, A arg);
+
+	R visit(Parameter n, A arg);
+	
+	R visit(EmptyMemberDeclaration n, A arg);
+
+	R visit(InitializerDeclaration n, A arg);
+
+	R visit(JavadocComment n, A arg);
+
+	//- Type ----------------------------------------------
+
+	R visit(ClassOrInterfaceType n, A arg);
+
+	R visit(PrimitiveType n, A arg);
+
+	R visit(ArrayType n, A arg);
+	
+	R visit(ArrayCreationLevel n, A arg);
+
+    R visit(IntersectionType n, A arg);
+
+    R visit(UnionType n, A arg);
+
+	R visit(VoidType n, A arg);
+
+	R visit(WildcardType n, A arg);
+
+	R visit(UnknownType n, A arg);
+
+	//- Expression ----------------------------------------
+
+	R visit(ArrayAccessExpr n, A arg);
+
+	R visit(ArrayCreationExpr n, A arg);
+
+	R visit(ArrayInitializerExpr n, A arg);
+
+	R visit(AssignExpr n, A arg);
+
+	R visit(BinaryExpr n, A arg);
+
+	R visit(CastExpr n, A arg);
+
+	R visit(ClassExpr n, A arg);
+
+	R visit(ConditionalExpr n, A arg);
+
+	R visit(EnclosedExpr n, A arg);
+
+	R visit(FieldAccessExpr n, A arg);
+
+	R visit(InstanceOfExpr n, A arg);
+
+	R visit(StringLiteralExpr n, A arg);
+
+	R visit(IntegerLiteralExpr n, A arg);
+
+	R visit(LongLiteralExpr n, A arg);
+
+	R visit(IntegerLiteralMinValueExpr n, A arg);
+
+	R visit(LongLiteralMinValueExpr n, A arg);
+
+	R visit(CharLiteralExpr n, A arg);
+
+	R visit(DoubleLiteralExpr n, A arg);
+
+	R visit(BooleanLiteralExpr n, A arg);
+
+	R visit(NullLiteralExpr n, A arg);
+
+	R visit(MethodCallExpr n, A arg);
+
+	R visit(NameExpr n, A arg);
+
+	R visit(ObjectCreationExpr n, A arg);
+
+	R visit(QualifiedNameExpr n, A arg);
+
+	R visit(ThisExpr n, A arg);
+
+	R visit(SuperExpr n, A arg);
+
+	R visit(UnaryExpr n, A arg);
+
+	R visit(VariableDeclarationExpr n, A arg);
+
+	R visit(MarkerAnnotationExpr n, A arg);
+
+	R visit(SingleMemberAnnotationExpr n, A arg);
+
+	R visit(NormalAnnotationExpr n, A arg);
+
+	R visit(MemberValuePair n, A arg);
+
+	//- Statements ----------------------------------------
+
+	R visit(ExplicitConstructorInvocationStmt n, A arg);
+
+	R visit(TypeDeclarationStmt n, A arg);
+
+	R visit(AssertStmt n, A arg);
+
+	R visit(BlockStmt n, A arg);
+
+	R visit(LabeledStmt n, A arg);
+
+	R visit(EmptyStmt n, A arg);
+
+	R visit(ExpressionStmt n, A arg);
+
+	R visit(SwitchStmt n, A arg);
+
+	R visit(SwitchEntryStmt n, A arg);
+
+	R visit(BreakStmt n, A arg);
+
+	R visit(ReturnStmt n, A arg);
+
+	R visit(IfStmt n, A arg);
+
+	R visit(WhileStmt n, A arg);
+
+	R visit(ContinueStmt n, A arg);
+
+	R visit(DoStmt n, A arg);
+
+	R visit(ForeachStmt n, A arg);
+
+	R visit(ForStmt n, A arg);
+
+	R visit(ThrowStmt n, A arg);
+
+	R visit(SynchronizedStmt n, A arg);
+
+	R visit(TryStmt n, A arg);
+
+	R visit(CatchClause n, A arg);
+
+    R visit(LambdaExpr n, A arg);
+
+    R visit(MethodReferenceExpr n, A arg);
+
+    R visit(TypeExpr n, A arg);
+
+	R visit(ArrayBracketPair arrayBracketPair, A arg);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
new file mode 100644
index 0000000..af01fdf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
@@ -0,0 +1,1677 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class GenericVisitorAdapter<R, A> implements GenericVisitor<R, A> {
+
+	@Override
+	public R visit(final AnnotationDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getMembers() != null) {
+            for (final BodyDeclaration<?> member : n.getMembers()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final AnnotationMemberDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getDefaultValue() != null) {
+			{
+				R result = n.getDefaultValue().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ArrayAccessExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getIndex().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ArrayCreationExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		for(ArrayCreationLevel level: n.getLevels()){
+			R result = level.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getInitializer() != null) {
+			R result = n.getInitializer().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ArrayInitializerExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getValues() != null) {
+			for (final Expression expr : n.getValues()) {
+				{
+					R result = expr.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final AssertStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getCheck().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getMessage() != null) {
+			{
+				R result = n.getMessage().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final AssignExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getTarget().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getValue().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final BinaryExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getLeft().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getRight().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final BlockStmt n, final A arg) {
+		visitComment(n, arg);
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				{
+					R result = s.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+
+	}
+
+	@Override
+	public R visit(final BooleanLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final BreakStmt n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final CastExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final CatchClause n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getParam().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+
+	}
+
+	@Override
+	public R visit(final CharLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final ClassExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ClassOrInterfaceDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getExtends() != null) {
+			for (final ClassOrInterfaceType c : n.getExtends()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+
+		if (n.getImplements() != null) {
+			for (final ClassOrInterfaceType c : n.getImplements()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getMembers() != null) {
+            for (final BodyDeclaration<?> member : n.getMembers()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ClassOrInterfaceType n, final A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getScope() != null) {
+			{
+				R result = n.getScope().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getTypeArguments() != null) {
+			for (Type<?> type : n.getTypeArguments()) {
+				R result = type.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final CompilationUnit n, final A arg) {
+		visitComment(n, arg);
+		if (n.getPackage() != null) {
+			{
+				R result = n.getPackage().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getImports() != null) {
+			for (final ImportDeclaration i : n.getImports()) {
+				{
+					R result = i.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypes() != null) {
+            for (final TypeDeclaration<?> typeDeclaration : n.getTypes()) {
+				{
+					R result = typeDeclaration.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ConditionalExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getThenExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getElseExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ConstructorDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				{
+					R result = p.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final ReferenceType name : n.getThrows()) {
+				{
+					R result = name.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ContinueStmt n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final DoStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final DoubleLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final EmptyMemberDeclaration n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final EmptyStmt n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final EmptyTypeDeclaration n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final EnclosedExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getInner().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final EnumConstantDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getClassBody() != null) {
+            for (final BodyDeclaration<?> member : n.getClassBody()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final EnumDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getImplements() != null) {
+			for (final ClassOrInterfaceType c : n.getImplements()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getEntries() != null) {
+			for (final EnumConstantDeclaration e : n.getEntries()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getMembers() != null) {
+            for (final BodyDeclaration<?> member : n.getMembers()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+		visitComment(n, arg);
+		if (!n.isThis() && n.getExpr() != null) {
+			{
+				R result = n.getExpr().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getTypeArguments() != null) {
+			for (Type<?> type : n.getTypeArguments()) {
+				R result = type.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ExpressionStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getExpression().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final FieldAccessExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getScope().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+        {
+            if (n.getTypeArguments() != null) {
+                for (Type<?> type : n.getTypeArguments()) {
+                    R result = type.accept(this, arg);
+                    if (result != null) {
+                        return result;
+                    }
+                }
+            }
+        }
+		return null;
+	}
+
+	@Override
+	public R visit(final FieldDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getElementType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		for (final VariableDeclarator var : n.getVariables()) {
+			{
+				R result = var.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ForeachStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getVariable().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getIterable().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ForStmt n, final A arg) {
+		visitComment(n, arg);
+		if (n.getInit() != null) {
+			for (final Expression e : n.getInit()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getCompare() != null) {
+			{
+				R result = n.getCompare().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getUpdate() != null) {
+			for (final Expression e : n.getUpdate()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final IfStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getThenStmt().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getElseStmt() != null) {
+			{
+				R result = n.getElseStmt().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ImportDeclaration n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final InitializerDeclaration n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getBlock().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final InstanceOfExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final IntegerLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final IntegerLiteralMinValueExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final JavadocComment n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final LabeledStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getStmt().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final LongLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final LongLiteralMinValueExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final MarkerAnnotationExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final MemberValuePair n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getValue().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final MethodCallExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getScope() != null) {
+			{
+				R result = n.getScope().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getTypeArguments() != null) {
+			for (Type<?> type : n.getTypeArguments()) {
+				R result = type.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final MethodDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getElementType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				{
+					R result = p.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final ReferenceType name : n.getThrows()) {
+				{
+					R result = name.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getBody() != null) {
+			{
+				R result = n.getBody().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final NameExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final NormalAnnotationExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getPairs() != null) {
+			for (final MemberValuePair m : n.getPairs()) {
+				{
+					R result = m.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final NullLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final ObjectCreationExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getScope() != null) {
+			{
+				R result = n.getScope().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getTypeArguments() != null) {
+			for (Type<?> type : n.getTypeArguments()) {
+				R result = type.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getAnonymousClassBody() != null) {
+            for (final BodyDeclaration<?> member : n.getAnonymousClassBody()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final PackageDeclaration n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final Parameter n, final A arg) {
+		visitComment(n, arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getElementType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getId().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+	
+	@Override
+	public R visit(final PrimitiveType n, final A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final QualifiedNameExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getQualifier().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(ArrayType n, A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getComponentType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(ArrayCreationLevel n, A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			if(n.getDimension()!=null) {
+				R result = n.getDimension().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+    public R visit(final IntersectionType n, final A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+        {
+            for (ReferenceType element : n.getElements()) {
+                R result = element.accept(this, arg);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public R visit(final UnionType n, final A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+        {
+            for (ReferenceType element : n.getElements()) {
+                R result = element.accept(this, arg);
+                if (result != null) {
+                    return result;
+                }
+            }
+        }
+        return null;
+    }
+
+	@Override
+	public R visit(final ReturnStmt n, final A arg) {
+		visitComment(n, arg);
+		if (n.getExpr() != null) {
+			{
+				R result = n.getExpr().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final SingleMemberAnnotationExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getMemberValue().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final StringLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final SuperExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getClassExpr() != null) {
+			{
+				R result = n.getClassExpr().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final SwitchEntryStmt n, final A arg) {
+		visitComment(n, arg);
+		if (n.getLabel() != null) {
+			{
+				R result = n.getLabel().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				{
+					R result = s.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final SwitchStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getSelector().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getEntries() != null) {
+			for (final SwitchEntryStmt e : n.getEntries()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+
+	}
+
+	@Override
+	public R visit(final SynchronizedStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			if (n.getExpr() != null) {
+			    R result = n.getExpr().accept(this, arg);
+			    if (result != null) {
+				    return result;
+			    }
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ThisExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getClassExpr() != null) {
+			{
+				R result = n.getClassExpr().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ThrowStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final TryStmt n, final A arg) {
+		visitComment(n, arg);
+		if (n.getResources() != null) {
+			for (final VariableDeclarationExpr v : n.getResources()) {
+				{
+					R result = v.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getTryBlock().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getCatchs() != null) {
+			for (final CatchClause c : n.getCatchs()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getFinallyBlock() != null) {
+			{
+				R result = n.getFinallyBlock().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final TypeDeclarationStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getTypeDeclaration().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final TypeParameter n, final A arg) {
+		visitComment(n, arg);
+		if (n.getTypeBound() != null) {
+			for (final ClassOrInterfaceType c : n.getTypeBound()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final UnaryExpr n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final UnknownType n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final VariableDeclarationExpr n, final A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getElementType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		for (final VariableDeclarator v : n.getVariables()) {
+			{
+				R result = v.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final VariableDeclarator n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getId().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getInit() != null) {
+			{
+				R result = n.getInit().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final VariableDeclaratorId n, final A arg) {
+		visitComment(n, arg);
+		return null;
+	}
+
+	@Override
+	public R visit(final VoidType n, final A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final WhileStmt n, final A arg) {
+		visitComment(n, arg);
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final WildcardType n, final A arg) {
+		visitComment(n, arg);
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			R result = a.accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getExtends() != null) {
+			{
+				R result = n.getExtends().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getSuper() != null) {
+			{
+				R result = n.getSuper().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+    @Override
+    public R visit(LambdaExpr n, A arg) {
+		visitComment(n, arg);
+		if (n.getParameters() != null) {
+			for (final Parameter a : n.getParameters()) {
+				R result = a.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getBody() != null) {
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+    }
+
+    @Override
+    public R visit(MethodReferenceExpr n, A arg) {
+        visitComment(n, arg);
+        {
+            if (n.getTypeArguments() != null) {
+                for (Type<?> type : n.getTypeArguments()) {
+                    R result = type.accept(this, arg);
+                    if (result != null) {
+                        return result;
+                    }
+                }
+            }
+        }
+        if (n.getScope() != null) {
+			R result = n.getScope().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+    }
+
+    @Override
+    public R visit(TypeExpr n, A arg){
+		visitComment(n, arg);
+		if (n.getType() != null) {
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+    }
+
+	@Override
+	public R visit(ArrayBracketPair n, A arg) {
+		for (final AnnotationExpr a : n.getAnnotations()) {
+			{
+				R result = a.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final BlockComment n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final LineComment n, final A arg) {
+		return null;
+	}
+
+	private void visitComment(Node n, A arg) {
+		if(n.getComment()!=null){
+			Comment result = (Comment) n.getComment().accept(this, arg);
+			if(result!=null){
+				n.setComment(result);
+			}
+		}
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java
new file mode 100644
index 0000000..78b0e29
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java
@@ -0,0 +1,1149 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import java.util.List;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.ArrayAccessExpr;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.ArrayInitializerExpr;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.CharLiteralExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
+import com.github.javaparser.ast.expr.ConditionalExpr;
+import com.github.javaparser.ast.expr.DoubleLiteralExpr;
+import com.github.javaparser.ast.expr.EnclosedExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.InstanceOfExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
+import com.github.javaparser.ast.expr.LongLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.MemberValuePair;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.NullLiteralExpr;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.expr.QualifiedNameExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.SuperExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.expr.TypeExpr;
+import com.github.javaparser.ast.expr.UnaryExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.stmt.WhileStmt;
+
+/**
+ * This visitor adapter can be used to save time when some specific nodes needs
+ * to be changed. To do that just extend this class and override the methods
+ * from the nodes who needs to be changed, returning the changed node.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public class ModifierVisitorAdapter<A> implements GenericVisitor<Node, A> {
+
+	private void removeNulls(final List<?> list) {
+		for (int i = list.size() - 1; i >= 0; i--) {
+			if (list.get(i) == null) {
+				list.remove(i);
+			}
+		}
+	}
+
+	@Override public Node visit(final AnnotationDeclaration n, final A arg) {
+		visitAnnotations(n, arg);
+		visitComment(n, arg);
+        final List<BodyDeclaration<?>> members = n.getMembers();
+		if (members != null) {
+			for (int i = 0; i < members.size(); i++) {
+                members.set(i, (BodyDeclaration<?>) members.get(i).accept(this, arg));
+			}
+			removeNulls(members);
+		}
+		return n;
+	}
+
+	private void visitAnnotations(NodeWithAnnotations<?> n, A arg) {
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+	}
+
+	@Override public Node visit(final AnnotationMemberDeclaration n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		n.setType((Type) n.getType().accept(this, arg));
+		if (n.getDefaultValue() != null) {
+			n.setDefaultValue((Expression) n.getDefaultValue().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ArrayAccessExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setName((Expression) n.getName().accept(this, arg));
+		n.setIndex((Expression) n.getIndex().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ArrayCreationExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setType((Type) n.getType().accept(this, arg));
+
+		final List<ArrayCreationLevel> values = n.getLevels();
+		for (int i = 0; i < values.size(); i++) {
+			values.set(i, (ArrayCreationLevel) values.get(i).accept(this, arg));
+		}
+		removeNulls(values);
+
+		if (n.getInitializer() != null) {
+			n.setInitializer((ArrayInitializerExpr) n.getInitializer().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ArrayInitializerExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getValues() != null) {
+			final List<Expression> values = n.getValues();
+			if (values != null) {
+				for (int i = 0; i < values.size(); i++) {
+					values.set(i, (Expression) values.get(i).accept(this, arg));
+				}
+				removeNulls(values);
+			}
+		}
+		return n;
+	}
+
+	@Override public Node visit(final AssertStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setCheck((Expression) n.getCheck().accept(this, arg));
+		if (n.getMessage() != null) {
+			n.setMessage((Expression) n.getMessage().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final AssignExpr n, final A arg) {
+		visitComment(n, arg);
+		final Expression target = (Expression) n.getTarget().accept(this, arg);
+		if (target == null) {
+			return null;
+		}
+        n.setTarget(target);
+
+		final Expression value = (Expression) n.getValue().accept(this, arg);
+		if (value == null) {
+			return null;
+		}
+		n.setValue(value);
+
+		return n;
+	}
+
+	@Override public Node visit(final BinaryExpr n, final A arg) {
+		visitComment(n, arg);
+		final Expression left = (Expression) n.getLeft().accept(this, arg);
+		final Expression right = (Expression) n.getRight().accept(this, arg);
+		if (left == null) {
+			return right;
+		}
+		if (right == null) {
+			return left;
+		}
+		n.setLeft(left);
+		n.setRight(right);
+		return n;
+	}
+
+	@Override public Node visit(final BlockStmt n, final A arg) {
+		visitComment(n, arg);
+		final List<Statement> stmts = n.getStmts();
+		if (stmts != null) {
+			for (int i = 0; i < stmts.size(); i++) {
+				stmts.set(i, (Statement) stmts.get(i).accept(this, arg));
+			}
+			removeNulls(stmts);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final BooleanLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final BreakStmt n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final CastExpr n, final A arg) {
+		visitComment(n, arg);
+		final Type type = (Type) n.getType().accept(this, arg);
+		final Expression expr = (Expression) n.getExpr().accept(this, arg);
+		if (type == null) {
+			return expr;
+		}
+		if (expr == null) {
+			return null;
+		}
+		n.setType(type);
+		n.setExpr(expr);
+		return n;
+	}
+
+	@Override public Node visit(final CatchClause n, final A arg) {
+		visitComment(n, arg);
+		n.setParam((Parameter)n.getParam().accept(this, arg));
+		n.setBody((BlockStmt) n.getBody().accept(this, arg));
+		return n;
+
+	}
+
+	@Override public Node visit(final CharLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final ClassExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setType((Type) n.getType().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ClassOrInterfaceDeclaration n, final A arg) {
+		visitAnnotations(n, arg);
+		visitComment(n, arg);
+		final List<TypeParameter> typeParameters = n.getTypeParameters();
+		if (typeParameters != null) {
+			for (int i = 0; i < typeParameters.size(); i++) {
+				typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg));
+			}
+			removeNulls(typeParameters);
+		}
+		final List<ClassOrInterfaceType> extendz = n.getExtends();
+		if (extendz != null) {
+			for (int i = 0; i < extendz.size(); i++) {
+				extendz.set(i, (ClassOrInterfaceType) extendz.get(i).accept(this, arg));
+			}
+			removeNulls(extendz);
+		}
+		final List<ClassOrInterfaceType> implementz = n.getImplements();
+		if (implementz != null) {
+			for (int i = 0; i < implementz.size(); i++) {
+				implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg));
+			}
+			removeNulls(implementz);
+		}
+        final List<BodyDeclaration<?>> members = n.getMembers();
+		if (members != null) {
+			for (int i = 0; i < members.size(); i++) {
+                members.set(i, (BodyDeclaration<?>) members.get(i).accept(this, arg));
+			}
+			removeNulls(members);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ClassOrInterfaceType n, final A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		if (n.getScope() != null) {
+			n.setScope((ClassOrInterfaceType) n.getScope().accept(this, arg));
+		}
+		final List<Type<?>> typeArguments = n.getTypeArguments();
+		if (typeArguments != null) {
+			for (int i = 0; i < typeArguments.size(); i++) {
+				typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg));
+			}
+			removeNulls(typeArguments);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final CompilationUnit n, final A arg) {
+		visitComment(n, arg);
+		if (n.getPackage() != null) {
+			n.setPackage((PackageDeclaration) n.getPackage().accept(this, arg));
+		}
+		final List<ImportDeclaration> imports = n.getImports();
+		if (imports != null) {
+			for (int i = 0; i < imports.size(); i++) {
+				imports.set(i, (ImportDeclaration) imports.get(i).accept(this, arg));
+			}
+			removeNulls(imports);
+		}
+        final List<TypeDeclaration<?>> types = n.getTypes();
+		if (types != null) {
+			for (int i = 0; i < types.size(); i++) {
+                types.set(i, (TypeDeclaration<?>) types.get(i).accept(this, arg));
+			}
+			removeNulls(types);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ConditionalExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setCondition((Expression) n.getCondition().accept(this, arg));
+		n.setThenExpr((Expression) n.getThenExpr().accept(this, arg));
+		n.setElseExpr((Expression) n.getElseExpr().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ConstructorDeclaration n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<TypeParameter> typeParameters = n.getTypeParameters();
+		if (typeParameters != null) {
+			for (int i = 0; i < typeParameters.size(); i++) {
+				typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg));
+			}
+			removeNulls(typeParameters);
+		}
+		final List<Parameter> parameters = n.getParameters();
+		if (parameters != null) {
+			for (int i = 0; i < parameters.size(); i++) {
+				parameters.set(i, (Parameter) parameters.get(i).accept(this, arg));
+			}
+			removeNulls(parameters);
+		}
+		final List<ReferenceType> throwz = n.getThrows();
+		if (throwz != null) {
+			for (int i = 0; i < throwz.size(); i++) {
+				throwz.set(i, (ReferenceType) throwz.get(i).accept(this, arg));
+			}
+			removeNulls(throwz);
+		}
+		n.setBody((BlockStmt) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ContinueStmt n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final DoStmt n, final A arg) {
+		visitComment(n, arg);
+		final Statement body = (Statement) n.getBody().accept(this, arg);
+		if (body == null) {
+			return null;
+		}
+		n.setBody(body);
+
+		final Expression condition = (Expression) n.getCondition().accept(this, arg);
+		if (condition == null) {
+			return null;
+		}
+		n.setCondition(condition);
+
+		return n;
+	}
+
+	@Override public Node visit(final DoubleLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final EmptyMemberDeclaration n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final EmptyStmt n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final EmptyTypeDeclaration n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final EnclosedExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setInner((Expression) n.getInner().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final EnumConstantDeclaration n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+        final List<BodyDeclaration<?>> classBody = n.getClassBody();
+		if (classBody != null) {
+			for (int i = 0; i < classBody.size(); i++) {
+                classBody.set(i, (BodyDeclaration<?>) classBody.get(i).accept(this, arg));
+			}
+			removeNulls(classBody);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final EnumDeclaration n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<ClassOrInterfaceType> implementz = n.getImplements();
+		if (implementz != null) {
+			for (int i = 0; i < implementz.size(); i++) {
+				implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg));
+			}
+			removeNulls(implementz);
+		}
+		final List<EnumConstantDeclaration> entries = n.getEntries();
+		if (entries != null) {
+			for (int i = 0; i < entries.size(); i++) {
+				entries.set(i, (EnumConstantDeclaration) entries.get(i).accept(this, arg));
+			}
+			removeNulls(entries);
+		}
+        final List<BodyDeclaration<?>> members = n.getMembers();
+		if (members != null) {
+			for (int i = 0; i < members.size(); i++) {
+                members.set(i, (BodyDeclaration<?>) members.get(i).accept(this, arg));
+			}
+			removeNulls(members);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+		visitComment(n, arg);
+		if (!n.isThis() && n.getExpr() != null) {
+			n.setExpr((Expression) n.getExpr().accept(this, arg));
+		}
+        final List<Type<?>> typeArguments = n.getTypeArguments();
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg));
+            }
+            removeNulls(typeArguments);
+        }
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ExpressionStmt n, final A arg) {
+		visitComment(n, arg);
+		final Expression expr = (Expression) n.getExpression().accept(this, arg);
+		if (expr == null) {
+			return null;
+		}
+		n.setExpression(expr);
+		return n;
+	}
+
+	@Override public Node visit(final FieldAccessExpr n, final A arg) {
+		visitComment(n, arg);
+		final Expression scope = (Expression) n.getScope().accept(this, arg);
+		if (scope == null) {
+			return null;
+		}
+		n.setScope(scope);
+		return n;
+	}
+
+	@Override public Node visit(final FieldDeclaration n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		n.setElementType((Type) n.getElementType().accept(this, arg));
+		final List<VariableDeclarator> variables = n.getVariables();
+		for (int i = 0; i < variables.size(); i++) {
+			variables.set(i, (VariableDeclarator) variables.get(i).accept(this, arg));
+		}
+		removeNulls(variables);
+		return n;
+	}
+
+	@Override public Node visit(final ForeachStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setVariable((VariableDeclarationExpr) n.getVariable().accept(this, arg));
+		n.setIterable((Expression) n.getIterable().accept(this, arg));
+		n.setBody((Statement) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ForStmt n, final A arg) {
+		visitComment(n, arg);
+		final List<Expression> init = n.getInit();
+		if (init != null) {
+			for (int i = 0; i < init.size(); i++) {
+				init.set(i, (Expression) init.get(i).accept(this, arg));
+			}
+			removeNulls(init);
+		}
+		if (n.getCompare() != null) {
+			n.setCompare((Expression) n.getCompare().accept(this, arg));
+		}
+		final List<Expression> update = n.getUpdate();
+		if (update != null) {
+			for (int i = 0; i < update.size(); i++) {
+				update.set(i, (Expression) update.get(i).accept(this, arg));
+			}
+			removeNulls(update);
+		}
+		n.setBody((Statement) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final IfStmt n, final A arg) {
+		visitComment(n, arg);
+		final Expression condition = (Expression)
+			n.getCondition().accept(this, arg);
+		if (condition == null) {
+			return null;
+		}
+		n.setCondition(condition);
+		final Statement thenStmt = (Statement) n.getThenStmt().accept(this, arg);
+		if (thenStmt == null) {
+			// Remove the entire statement if the then-clause was removed.
+			// DumpVisitor, used for toString, has no null check for the
+			// then-clause.
+			return null;
+		}
+		n.setThenStmt(thenStmt);
+		if (n.getElseStmt() != null) {
+			n.setElseStmt((Statement) n.getElseStmt().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ImportDeclaration n, final A arg) {
+		visitComment(n, arg);
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final InitializerDeclaration n, final A arg) {
+		visitComment(n, arg);
+		n.setBlock((BlockStmt) n.getBlock().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final InstanceOfExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		n.setType((Type) n.getType().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final IntegerLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final IntegerLiteralMinValueExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final JavadocComment n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final LabeledStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setStmt((Statement) n.getStmt().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final LongLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final LongLiteralMinValueExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final MarkerAnnotationExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final MemberValuePair n, final A arg) {
+		visitComment(n, arg);
+		n.setValue((Expression) n.getValue().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final MethodCallExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getScope() != null) {
+			n.setScope((Expression) n.getScope().accept(this, arg));
+		}
+        final List<Type<?>> typeArguments = n.getTypeArguments();
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg));
+            }
+            removeNulls(typeArguments);
+        }
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final MethodDeclaration n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<TypeParameter> typeParameters = n.getTypeParameters();
+		if (typeParameters != null) {
+			for (int i = 0; i < typeParameters.size(); i++) {
+				typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg));
+			}
+			removeNulls(typeParameters);
+		}
+		n.setElementType((Type) n.getElementType().accept(this, arg));
+		final List<Parameter> parameters = n.getParameters();
+		if (parameters != null) {
+			for (int i = 0; i < parameters.size(); i++) {
+				parameters.set(i, (Parameter) parameters.get(i).accept(this, arg));
+			}
+			removeNulls(parameters);
+		}
+		final List<ReferenceType> throwz = n.getThrows();
+		if (throwz != null) {
+			for (int i = 0; i < throwz.size(); i++) {
+				throwz.set(i, (ReferenceType) throwz.get(i).accept(this, arg));
+			}
+			removeNulls(throwz);
+		}
+		if (n.getBody() != null) {
+			n.setBody((BlockStmt) n.getBody().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final NameExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final NormalAnnotationExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		final List<MemberValuePair> pairs = n.getPairs();
+		if (pairs != null) {
+			for (int i = 0; i < pairs.size(); i++) {
+				pairs.set(i, (MemberValuePair) pairs.get(i).accept(this, arg));
+			}
+			removeNulls(pairs);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final NullLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final ObjectCreationExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getScope() != null) {
+			n.setScope((Expression) n.getScope().accept(this, arg));
+		}
+        final List<Type<?>> typeArguments = n.getTypeArguments();
+        if (typeArguments != null) {
+            for (int i = 0; i < typeArguments.size(); i++) {
+                typeArguments.set(i, (Type<?>) typeArguments.get(i).accept(this, arg));
+            }
+            removeNulls(typeArguments);
+        }
+		n.setType((ClassOrInterfaceType) n.getType().accept(this, arg));
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+        final List<BodyDeclaration<?>> anonymousClassBody = n.getAnonymousClassBody();
+		if (anonymousClassBody != null) {
+			for (int i = 0; i < anonymousClassBody.size(); i++) {
+                anonymousClassBody.set(i, (BodyDeclaration<?>) anonymousClassBody.get(i).accept(this, arg));
+			}
+			removeNulls(anonymousClassBody);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final PackageDeclaration n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		return n;
+	}
+	
+	@Override public Node visit(final Parameter n, final A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		n.setId((VariableDeclaratorId) n.getId().accept(this, arg));
+		n.setElementType((Type) n.getElementType().accept(this, arg));
+		return n;
+	}
+	
+	@Override public Node visit(final PrimitiveType n, final A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final QualifiedNameExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setQualifier((NameExpr) n.getQualifier().accept(this, arg));
+		return n;
+	}
+
+	@Override
+	public Node visit(ArrayType n, A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		n.setComponentType((Type) n.getComponentType().accept(this, arg));
+		return n;
+	}
+
+	@Override
+	public Node visit(ArrayCreationLevel n, A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		if(n.getDimension()!=null) {
+			n.setDimension((Expression) n.getDimension().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override
+    public Node visit(final IntersectionType n, final A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+        final List<ReferenceType> elements = n.getElements();
+        if (elements != null) {
+            for (int i = 0; i < elements.size(); i++) {
+                elements.set(i, (ReferenceType) elements.get(i).accept(this, arg));
+            }
+            removeNulls(elements);
+        }
+        return n;
+    }
+
+    @Override
+    public Node visit(final UnionType n, final A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		final List<ReferenceType> elements = n.getElements();
+        if (elements != null) {
+            for (int i = 0; i < elements.size(); i++) {
+                elements.set(i, (ReferenceType) elements.get(i).accept(this, arg));
+            }
+            removeNulls(elements);
+        }
+        return n;
+    }
+
+	@Override public Node visit(final ReturnStmt n, final A arg) {
+		visitComment(n, arg);
+		if (n.getExpr() != null) {
+			n.setExpr((Expression) n.getExpr().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final SingleMemberAnnotationExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		n.setMemberValue((Expression) n.getMemberValue().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final StringLiteralExpr n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final SuperExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getClassExpr() != null) {
+			n.setClassExpr((Expression) n.getClassExpr().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final SwitchEntryStmt n, final A arg) {
+		visitComment(n, arg);
+		if (n.getLabel() != null) {
+			n.setLabel((Expression) n.getLabel().accept(this, arg));
+		}
+		final List<Statement> stmts = n.getStmts();
+		if (stmts != null) {
+			for (int i = 0; i < stmts.size(); i++) {
+				stmts.set(i, (Statement) stmts.get(i).accept(this, arg));
+			}
+			removeNulls(stmts);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final SwitchStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setSelector((Expression) n.getSelector().accept(this, arg));
+		final List<SwitchEntryStmt> entries = n.getEntries();
+		if (entries != null) {
+			for (int i = 0; i < entries.size(); i++) {
+				entries.set(i, (SwitchEntryStmt) entries.get(i).accept(this, arg));
+			}
+			removeNulls(entries);
+		}
+		return n;
+
+	}
+
+	@Override public Node visit(final SynchronizedStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		n.setBody((BlockStmt) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ThisExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getClassExpr() != null) {
+			n.setClassExpr((Expression) n.getClassExpr().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ThrowStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final TryStmt n, final A arg) {
+		visitComment(n, arg);
+		final List<VariableDeclarationExpr> types = n.getResources();
+		for (int i = 0; i < types.size(); i++) {
+			n.getResources().set(i,
+					(VariableDeclarationExpr) n.getResources().get(i).accept(this, arg));
+		}
+		n.setTryBlock((BlockStmt) n.getTryBlock().accept(this, arg));
+		final List<CatchClause> catchs = n.getCatchs();
+		if (catchs != null) {
+			for (int i = 0; i < catchs.size(); i++) {
+				catchs.set(i, (CatchClause) catchs.get(i).accept(this, arg));
+			}
+			removeNulls(catchs);
+		}
+		if (n.getFinallyBlock() != null) {
+			n.setFinallyBlock((BlockStmt) n.getFinallyBlock().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final TypeDeclarationStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setTypeDeclaration((TypeDeclaration<?>) n.getTypeDeclaration().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final TypeParameter n, final A arg) {
+		visitComment(n, arg);
+		final List<ClassOrInterfaceType> typeBound = n.getTypeBound();
+		if (typeBound != null) {
+			for (int i = 0; i < typeBound.size(); i++) {
+				typeBound.set(i, (ClassOrInterfaceType) typeBound.get(i).accept(this, arg));
+			}
+			removeNulls(typeBound);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final UnaryExpr n, final A arg) {
+		visitComment(n, arg);
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final UnknownType n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final VariableDeclarationExpr n, final A arg) {
+		visitComment(n, arg);
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+
+		final Type type = (Type) n.getElementType().accept(this, arg);
+		if (type == null) {
+			return null;
+		}
+		n.setElementType(type);
+
+		final List<VariableDeclarator> vars = n.getVariables();
+		for (int i = 0; i < vars.size();) {
+			final VariableDeclarator decl = (VariableDeclarator)
+				vars.get(i).accept(this, arg);
+			if (decl == null) {
+				vars.remove(i);
+			} else {
+				vars.set(i++, decl);
+			}
+		}
+		if (vars.isEmpty()) {
+			return null;
+		}
+
+		return n;
+	}
+
+	@Override public Node visit(final VariableDeclarator n, final A arg) {
+		visitComment(n, arg);
+		final VariableDeclaratorId id = (VariableDeclaratorId)
+			n.getId().accept(this, arg);
+		if (id == null) {
+			return null;
+		}
+		n.setId(id);
+		if (n.getInit() != null) {
+			n.setInit((Expression) n.getInit().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final VariableDeclaratorId n, final A arg) {
+		visitComment(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final VoidType n, final A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		return n;
+	}
+
+	@Override public Node visit(final WhileStmt n, final A arg) {
+		visitComment(n, arg);
+		n.setCondition((Expression) n.getCondition().accept(this, arg));
+		n.setBody((Statement) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final WildcardType n, final A arg) {
+		visitComment(n, arg);
+		visitAnnotations(n, arg);
+		if (n.getExtends() != null) {
+			n.setExtends((ReferenceType) n.getExtends().accept(this, arg));
+		}
+		if (n.getSuper() != null) {
+			n.setSuper((ReferenceType) n.getSuper().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override
+	public Node visit(final LambdaExpr n, final A arg) {
+		visitComment(n, arg);
+		final List<Parameter> parameters = n.getParameters();
+		for (int i = 0; i < parameters.size(); i++) {
+			parameters.set(i, (Parameter) parameters.get(i).accept(this, arg));
+		}
+		removeNulls(parameters);
+		if (n.getBody() != null) {
+			n.setBody((Statement) n.getBody().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override
+	public Node visit(final MethodReferenceExpr n, final A arg) {
+		visitComment(n, arg);
+		final List<Type<?>> types = n.getTypeArguments();
+		for (int i = 0; i < types.size(); i++) {
+			n.getTypeArguments().set(i,
+					(Type<?>) n.getTypeArguments().get(i).accept(this, arg));
+		}
+		if (n.getScope() != null) {
+			n.setScope((Expression)n.getScope().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override
+	public Node visit(final TypeExpr n, final A arg) {
+		visitComment(n, arg);
+		if (n.getType() != null) {
+            n.setType((Type<?>) n.getType().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override
+	public Node visit(ArrayBracketPair n, A arg) {
+		visitAnnotations(n, arg);
+		return n;
+	}
+
+	@Override
+	public Node visit(final BlockComment n, final A arg) {
+		return n;
+	}
+
+	@Override
+	public Node visit(final LineComment n, final A arg) {
+		return n;
+	}
+
+	private void visitComment(Node n, final A arg) {
+		if (n != null && n.getComment() != null) {
+			n.setComment((Comment) n.getComment().accept(this, arg));
+		}
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/TreeVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/TreeVisitor.java
new file mode 100644
index 0000000..c1b7eae
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/TreeVisitor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * Iterate over all the nodes in (a part of) the AST.
+ */
+public abstract class TreeVisitor {
+
+	/**
+	 * https://en.wikipedia.org/wiki/Depth-first_search
+	 *
+	 * @param node the start node, and the first one that is passed to process(node).
+	 */
+	public void visitDepthFirst(Node node) {
+		process(node);
+		for (Node child : node.getChildrenNodes()) {
+			visitDepthFirst(child);
+		}
+	}
+
+	public abstract void process(Node node);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/VoidVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/VoidVisitor.java
new file mode 100644
index 0000000..ec1d0f6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/VoidVisitor.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * A visitor that does not return anything.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public interface VoidVisitor<A> {
+
+	//- Compilation Unit ----------------------------------
+
+	void visit(CompilationUnit n, A arg);
+
+	void visit(PackageDeclaration n, A arg);
+
+	void visit(ImportDeclaration n, A arg);
+
+	void visit(TypeParameter n, A arg);
+
+	void visit(LineComment n, A arg);
+
+	void visit(BlockComment n, A arg);
+
+	//- Body ----------------------------------------------
+
+	void visit(ClassOrInterfaceDeclaration n, A arg);
+
+	void visit(EnumDeclaration n, A arg);
+
+	void visit(EmptyTypeDeclaration n, A arg);
+
+	void visit(EnumConstantDeclaration n, A arg);
+
+	void visit(AnnotationDeclaration n, A arg);
+
+	void visit(AnnotationMemberDeclaration n, A arg);
+
+	void visit(FieldDeclaration n, A arg);
+
+	void visit(VariableDeclarator n, A arg);
+
+	void visit(VariableDeclaratorId n, A arg);
+
+	void visit(ConstructorDeclaration n, A arg);
+
+	void visit(MethodDeclaration n, A arg);
+
+	void visit(Parameter n, A arg);
+	
+	void visit(EmptyMemberDeclaration n, A arg);
+
+	void visit(InitializerDeclaration n, A arg);
+
+	void visit(JavadocComment n, A arg);
+
+	//- Type ----------------------------------------------
+
+	void visit(ClassOrInterfaceType n, A arg);
+
+	void visit(PrimitiveType n, A arg);
+
+	void visit(ArrayType n, A arg);
+	
+	void visit(ArrayCreationLevel n, A arg);
+
+    void visit(IntersectionType n, A arg);
+
+    void visit(UnionType n, A arg);
+
+	void visit(VoidType n, A arg);
+
+	void visit(WildcardType n, A arg);
+
+	void visit(UnknownType n, A arg);
+
+	//- Expression ----------------------------------------
+
+	void visit(ArrayAccessExpr n, A arg);
+
+	void visit(ArrayCreationExpr n, A arg);
+
+	void visit(ArrayInitializerExpr n, A arg);
+
+	void visit(AssignExpr n, A arg);
+
+	void visit(BinaryExpr n, A arg);
+
+	void visit(CastExpr n, A arg);
+
+	void visit(ClassExpr n, A arg);
+
+	void visit(ConditionalExpr n, A arg);
+
+	void visit(EnclosedExpr n, A arg);
+
+	void visit(FieldAccessExpr n, A arg);
+
+	void visit(InstanceOfExpr n, A arg);
+
+	void visit(StringLiteralExpr n, A arg);
+
+	void visit(IntegerLiteralExpr n, A arg);
+
+	void visit(LongLiteralExpr n, A arg);
+
+	void visit(IntegerLiteralMinValueExpr n, A arg);
+
+	void visit(LongLiteralMinValueExpr n, A arg);
+
+	void visit(CharLiteralExpr n, A arg);
+
+	void visit(DoubleLiteralExpr n, A arg);
+
+	void visit(BooleanLiteralExpr n, A arg);
+
+	void visit(NullLiteralExpr n, A arg);
+
+	void visit(MethodCallExpr n, A arg);
+
+	void visit(NameExpr n, A arg);
+
+	void visit(ObjectCreationExpr n, A arg);
+
+	void visit(QualifiedNameExpr n, A arg);
+
+	void visit(ThisExpr n, A arg);
+
+	void visit(SuperExpr n, A arg);
+
+	void visit(UnaryExpr n, A arg);
+
+	void visit(VariableDeclarationExpr n, A arg);
+
+	void visit(MarkerAnnotationExpr n, A arg);
+
+	void visit(SingleMemberAnnotationExpr n, A arg);
+
+	void visit(NormalAnnotationExpr n, A arg);
+
+	void visit(MemberValuePair n, A arg);
+
+	//- Statements ----------------------------------------
+
+	void visit(ExplicitConstructorInvocationStmt n, A arg);
+
+	void visit(TypeDeclarationStmt n, A arg);
+
+	void visit(AssertStmt n, A arg);
+
+	void visit(BlockStmt n, A arg);
+
+	void visit(LabeledStmt n, A arg);
+
+	void visit(EmptyStmt n, A arg);
+
+	void visit(ExpressionStmt n, A arg);
+
+	void visit(SwitchStmt n, A arg);
+
+	void visit(SwitchEntryStmt n, A arg);
+
+	void visit(BreakStmt n, A arg);
+
+	void visit(ReturnStmt n, A arg);
+
+	void visit(IfStmt n, A arg);
+
+	void visit(WhileStmt n, A arg);
+
+	void visit(ContinueStmt n, A arg);
+
+	void visit(DoStmt n, A arg);
+
+	void visit(ForeachStmt n, A arg);
+
+	void visit(ForStmt n, A arg);
+
+	void visit(ThrowStmt n, A arg);
+
+	void visit(SynchronizedStmt n, A arg);
+
+	void visit(TryStmt n, A arg);
+
+	void visit(CatchClause n, A arg);
+
+    void visit(LambdaExpr n, A arg);
+
+    void visit(MethodReferenceExpr n, A arg);
+
+    void visit(TypeExpr n, A arg);
+
+	void visit(ArrayBracketPair arrayBracketPair, A arg);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
new file mode 100644
index 0000000..cab3ef4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
@@ -0,0 +1,806 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.ArrayAccessExpr;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.ArrayInitializerExpr;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.CharLiteralExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
+import com.github.javaparser.ast.expr.ConditionalExpr;
+import com.github.javaparser.ast.expr.DoubleLiteralExpr;
+import com.github.javaparser.ast.expr.EnclosedExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.InstanceOfExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
+import com.github.javaparser.ast.expr.LongLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.MemberValuePair;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.NullLiteralExpr;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.expr.QualifiedNameExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.SuperExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.expr.TypeExpr;
+import com.github.javaparser.ast.expr.UnaryExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class VoidVisitorAdapter<A> implements VoidVisitor<A> {
+
+	@Override public void visit(final AnnotationDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getNameExpr().accept(this, arg);
+		if (n.getMembers() != null) {
+            for (final BodyDeclaration<?> member : n.getMembers()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final AnnotationMemberDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getType().accept(this, arg);
+		if (n.getDefaultValue() != null) {
+			n.getDefaultValue().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ArrayAccessExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		n.getIndex().accept(this, arg);
+	}
+
+	@Override public void visit(final ArrayCreationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+		for (ArrayCreationLevel level : n.getLevels()) {
+			level.accept(this, arg);
+		}
+		if (n.getInitializer() != null) {
+			n.getInitializer().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ArrayInitializerExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getValues() != null) {
+			for (final Expression expr : n.getValues()) {
+				expr.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final AssertStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCheck().accept(this, arg);
+		if (n.getMessage() != null) {
+			n.getMessage().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final AssignExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getTarget().accept(this, arg);
+		n.getValue().accept(this, arg);
+	}
+
+	@Override public void visit(final BinaryExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getLeft().accept(this, arg);
+		n.getRight().accept(this, arg);
+	}
+
+	@Override public void visit(final BlockComment n, final A arg) {
+	}
+
+	@Override public void visit(final BlockStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final BooleanLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final BreakStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final CastExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final CatchClause n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getParam().accept(this, arg);
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final CharLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final ClassExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+	}
+
+	@Override public void visit(final ClassOrInterfaceDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getNameExpr().accept(this, arg);
+		for (final TypeParameter t : n.getTypeParameters()) {
+			t.accept(this, arg);
+		}
+		for (final ClassOrInterfaceType c : n.getExtends()) {
+			c.accept(this, arg);
+		}
+		for (final ClassOrInterfaceType c : n.getImplements()) {
+			c.accept(this, arg);
+		}
+        for (final BodyDeclaration<?> member : n.getMembers()) {
+			member.accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ClassOrInterfaceType n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+		}
+		if (n.getTypeArguments() != null) {
+			for (final Type t : n.getTypeArguments()) {
+				t.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final CompilationUnit n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getPackage() != null) {
+			n.getPackage().accept(this, arg);
+		}
+		if (n.getImports() != null) {
+			for (final ImportDeclaration i : n.getImports()) {
+				i.accept(this, arg);
+			}
+		}
+		if (n.getTypes() != null) {
+            for (final TypeDeclaration<?> typeDeclaration : n.getTypes()) {
+				typeDeclaration.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final ConditionalExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		n.getThenExpr().accept(this, arg);
+		n.getElseExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final ConstructorDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				t.accept(this, arg);
+			}
+		}
+		n.getNameExpr().accept(this, arg);
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				p.accept(this, arg);
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final ReferenceType name : n.getThrows()) {
+				name.accept(this, arg);
+			}
+		}
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final ContinueStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final DoStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getBody().accept(this, arg);
+		n.getCondition().accept(this, arg);
+	}
+
+	@Override public void visit(final DoubleLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final EmptyMemberDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final EmptyStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final EmptyTypeDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getNameExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final EnclosedExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getInner().accept(this, arg);
+	}
+
+	@Override public void visit(final EnumConstantDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getClassBody() != null) {
+            for (final BodyDeclaration<?> member : n.getClassBody()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final EnumDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getNameExpr().accept(this, arg);
+		if (n.getImplements() != null) {
+			for (final ClassOrInterfaceType c : n.getImplements()) {
+				c.accept(this, arg);
+			}
+		}
+		if (n.getEntries() != null) {
+			for (final EnumConstantDeclaration e : n.getEntries()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getMembers() != null) {
+            for (final BodyDeclaration<?> member : n.getMembers()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (!n.isThis() && n.getExpr() != null) {
+			n.getExpr().accept(this, arg);
+		}
+		if (n.getTypeArguments() != null) {
+			for (final Type t : n.getTypeArguments()) {
+				t.accept(this, arg);
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final ExpressionStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpression().accept(this, arg);
+	}
+
+	@Override public void visit(final FieldAccessExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getScope().accept(this, arg);
+		n.getFieldExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final FieldDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getElementType().accept(this, arg);
+		for (final VariableDeclarator var : n.getVariables()) {
+			var.accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ForeachStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getVariable().accept(this, arg);
+		n.getIterable().accept(this, arg);
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final ForStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getInit() != null) {
+			for (final Expression e : n.getInit()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getCompare() != null) {
+			n.getCompare().accept(this, arg);
+		}
+		if (n.getUpdate() != null) {
+			for (final Expression e : n.getUpdate()) {
+				e.accept(this, arg);
+			}
+		}
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final IfStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		n.getThenStmt().accept(this, arg);
+		if (n.getElseStmt() != null) {
+			n.getElseStmt().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ImportDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+	}
+
+	@Override public void visit(final InitializerDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final InstanceOfExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+		n.getType().accept(this, arg);
+	}
+
+	@Override public void visit(final IntegerLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final IntegerLiteralMinValueExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final JavadocComment n, final A arg) {
+	}
+
+	@Override public void visit(final LabeledStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getStmt().accept(this, arg);
+	}
+
+	@Override public void visit(final LineComment n, final A arg) {
+	}
+
+	@Override public void visit(final LongLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final LongLiteralMinValueExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final MarkerAnnotationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+	}
+
+	@Override public void visit(final MemberValuePair n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getValue().accept(this, arg);
+	}
+
+	@Override public void visit(final MethodCallExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+		}
+		if (n.getTypeArguments() != null) {
+			for (final Type t : n.getTypeArguments()) {
+				t.accept(this, arg);
+			}
+		}
+		n.getNameExpr().accept(this, arg);
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final MethodDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				t.accept(this, arg);
+			}
+		}
+		n.getElementType().accept(this, arg);
+		n.getNameExpr().accept(this, arg);
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				p.accept(this, arg);
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final ReferenceType name : n.getThrows()) {
+				name.accept(this, arg);
+			}
+		}
+		if (n.getBody() != null) {
+			n.getBody().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final NameExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final NormalAnnotationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		if (n.getPairs() != null) {
+			for (final MemberValuePair m : n.getPairs()) {
+				m.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final NullLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final ObjectCreationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+		}
+		if (n.getTypeArguments() != null) {
+			for (final Type t : n.getTypeArguments()) {
+				t.accept(this, arg);
+			}
+		}
+		n.getType().accept(this, arg);
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getAnonymousClassBody() != null) {
+            for (final BodyDeclaration<?> member : n.getAnonymousClassBody()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final PackageDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getName().accept(this, arg);
+	}
+
+	@Override public void visit(final Parameter n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getElementType().accept(this, arg);
+		n.getId().accept(this, arg);
+	}
+	
+	@Override public void visit(final PrimitiveType n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+	}
+
+	@Override public void visit(final QualifiedNameExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getQualifier().accept(this, arg);
+	}
+
+	@Override
+	public void visit(ArrayType n, A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getComponentType().accept(this, arg);
+	}
+
+	@Override
+	public void visit(ArrayCreationLevel n, A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		if(n.getDimension()!=null) {
+			n.getDimension().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final IntersectionType n, final A arg) {
+        visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+        }
+    }
+
+    @Override public void visit(final UnionType n, final A arg) {
+        visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+        }
+    }
+
+	@Override public void visit(final ReturnStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getExpr() != null) {
+			n.getExpr().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final SingleMemberAnnotationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		n.getMemberValue().accept(this, arg);
+	}
+
+	@Override public void visit(final StringLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final SuperExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final SwitchEntryStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getLabel() != null) {
+			n.getLabel().accept(this, arg);
+		}
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final SwitchStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getSelector().accept(this, arg);
+		if (n.getEntries() != null) {
+			for (final SwitchEntryStmt e : n.getEntries()) {
+				e.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final SynchronizedStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final ThisExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ThrowStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final TryStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getResources() != null) {
+			for (final VariableDeclarationExpr v : n.getResources()) {
+				v.accept(this, arg);
+			}
+		}
+		n.getTryBlock().accept(this, arg);
+		if (n.getCatchs() != null) {
+			for (final CatchClause c : n.getCatchs()) {
+				c.accept(this, arg);
+			}
+		}
+		if (n.getFinallyBlock() != null) {
+			n.getFinallyBlock().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final TypeDeclarationStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getTypeDeclaration().accept(this, arg);
+	}
+
+	@Override public void visit(final TypeParameter n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getTypeBound() != null) {
+			for (final ClassOrInterfaceType c : n.getTypeBound()) {
+				c.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final UnaryExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final UnknownType n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final VariableDeclarationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		n.getElementType().accept(this, arg);
+		for (final VariableDeclarator v : n.getVariables()) {
+			v.accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final VariableDeclarator n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getId().accept(this, arg);
+		if (n.getInit() != null) {
+			n.getInit().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final VariableDeclaratorId n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final VoidType n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+
+	}
+
+	@Override public void visit(final WhileStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final WildcardType n, final A arg) {
+		visitComment(n.getComment(), arg);
+		visitAnnotations(n, arg);
+		if (n.getExtends() != null) {
+			n.getExtends().accept(this, arg);
+		}
+		if (n.getSuper() != null) {
+			n.getSuper().accept(this, arg);
+		}
+	}
+
+    @Override
+    public void visit(LambdaExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+        if (n.getParameters() != null) {
+            for (final Parameter a : n.getParameters()) {
+                a.accept(this, arg);
+            }
+        }
+        if (n.getBody() != null) {
+            n.getBody().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(MethodReferenceExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getTypeArguments() != null) {
+			for (final Type t : n.getTypeArguments()) {
+				t.accept(this, arg);
+			}
+		}
+        if (n.getScope() != null) {
+            n.getScope().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(TypeExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+    }
+
+	@Override
+	public void visit(ArrayBracketPair n, A arg) {
+		visitAnnotations(n, arg);
+	}
+
+	private void visitComment(final Comment n, final A arg) {
+		if (n != null) {
+			n.accept(this, arg);
+		}
+	}
+
+	private void visitAnnotations(NodeWithAnnotations<?> n, A arg) {
+		for (AnnotationExpr annotation : n.getAnnotations()) {
+			annotation.accept(this, arg);
+		}
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/ClassUtils.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/ClassUtils.java
new file mode 100644
index 0000000..4769868
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/ClassUtils.java
@@ -0,0 +1,69 @@
+package com.github.javaparser.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ClassUtils {
+    /**
+     * Maps primitive {@code Class}es to their corresponding wrapper {@code Class}.
+     */
+    private static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<Class<?>, Class<?>>();
+    static {
+        primitiveWrapperMap.put(Boolean.TYPE, Boolean.class);
+        primitiveWrapperMap.put(Byte.TYPE, Byte.class);
+        primitiveWrapperMap.put(Character.TYPE, Character.class);
+        primitiveWrapperMap.put(Short.TYPE, Short.class);
+        primitiveWrapperMap.put(Integer.TYPE, Integer.class);
+        primitiveWrapperMap.put(Long.TYPE, Long.class);
+        primitiveWrapperMap.put(Double.TYPE, Double.class);
+        primitiveWrapperMap.put(Float.TYPE, Float.class);
+        primitiveWrapperMap.put(Void.TYPE, Void.TYPE);
+    }
+
+    /**
+     * Maps wrapper {@code Class}es to their corresponding primitive types.
+     */
+    private static final Map<Class<?>, Class<?>> wrapperPrimitiveMap = new HashMap<Class<?>, Class<?>>();
+    static {
+        for (final Class<?> primitiveClass : primitiveWrapperMap.keySet()) {
+            final Class<?> wrapperClass = primitiveWrapperMap.get(primitiveClass);
+            if (!primitiveClass.equals(wrapperClass)) {
+                wrapperPrimitiveMap.put(wrapperClass, primitiveClass);
+            }
+        }
+    }
+
+    /**
+     * Returns whether the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte},
+     * {@link Character},
+     * {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     *
+     * @param type
+     *            The class to query or null.
+     * @return true if the given {@code type} is a primitive or primitive wrapper ({@link Boolean}, {@link Byte},
+     *         {@link Character},
+     *         {@link Short}, {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     */
+    public static boolean isPrimitiveOrWrapper(final Class<?> type) {
+        if (type == null) {
+            return false;
+        }
+        return type.isPrimitive() || isPrimitiveWrapper(type);
+    }
+
+    /**
+     * Returns whether the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character},
+     * {@link Short},
+     * {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     *
+     * @param type
+     *            The class to query or null.
+     * @return true if the given {@code type} is a primitive wrapper ({@link Boolean}, {@link Byte}, {@link Character},
+     *         {@link Short},
+     *         {@link Integer}, {@link Long}, {@link Double}, {@link Float}).
+     * @since 3.1
+     */
+    public static boolean isPrimitiveWrapper(final Class<?> type) {
+        return wrapperPrimitiveMap.containsKey(type);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/Pair.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/Pair.java
new file mode 100644
index 0000000..40ce85d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/Pair.java
@@ -0,0 +1,16 @@
+package com.github.javaparser.utils;
+
+/**
+ * Simply a pair of objects.
+ * @param <A> type of object a.
+ * @param <B> type of object b.
+ */
+public class Pair<A, B> {
+	public final A a;
+	public final B b;
+
+	public Pair(A a, B b) {
+		this.a = a;
+		this.b = b;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/PositionUtils.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/PositionUtils.java
new file mode 100644
index 0000000..e1ecf19
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/PositionUtils.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.utils;
+
+import static java.lang.Integer.signum;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
+import com.github.javaparser.ast.nodeTypes.NodeWithElementType;
+import com.github.javaparser.ast.nodeTypes.NodeWithType;
+
+public final class PositionUtils {
+
+    private PositionUtils() {
+        // prevent instantiation
+    }
+
+    public static <T extends Node> void sortByBeginPosition(List<T> nodes){
+        sortByBeginPosition(nodes, false);
+    }
+
+    public static <T extends Node> void sortByBeginPosition(List<T> nodes, final boolean ignoringAnnotations){
+        Collections.sort(nodes, (o1, o2) -> PositionUtils.compare(o1, o2, ignoringAnnotations));
+    }
+
+    public static boolean areInOrder(Node a, Node b){
+        return areInOrder(a, b, false);
+    }
+
+    public static boolean areInOrder(Node a, Node b, boolean ignoringAnnotations){
+        return compare(a, b, ignoringAnnotations) <= 0;
+    }
+
+    private static int compare(Node a, Node b, boolean ignoringAnnotations) {
+        if (ignoringAnnotations) {
+            int signLine = signum(beginLineWithoutConsideringAnnotation(a) - beginLineWithoutConsideringAnnotation(b));
+            if (signLine == 0) {
+                return signum(beginColumnWithoutConsideringAnnotation(a) - beginColumnWithoutConsideringAnnotation(b));
+            } else {
+                return signLine;
+            }
+        }
+
+        int signLine = signum( a.getBegin().line - b.getBegin().line );
+        if (signLine == 0) {
+            return signum(a.getBegin().column - b.getBegin().column);
+        } else {
+            return signLine;
+        }
+    }
+
+    public static AnnotationExpr getLastAnnotation(Node node) {
+        if (node instanceof NodeWithAnnotations){
+            List<AnnotationExpr> annotations = new LinkedList<>();
+            annotations.addAll(((NodeWithAnnotations<?>) node).getAnnotations());
+            if (annotations.isEmpty()){
+                return null;
+            }
+            sortByBeginPosition(annotations);
+            return annotations.get(annotations.size()-1);
+        } else {
+            return null;
+        }
+    }
+
+    private static int beginLineWithoutConsideringAnnotation(Node node) {
+        return beginNodeWithoutConsideringAnnotations(node).getBegin().line;
+    }
+
+
+    private static int beginColumnWithoutConsideringAnnotation(Node node) {
+        return beginNodeWithoutConsideringAnnotations(node).getBegin().column;
+    }
+
+    private static Node beginNodeWithoutConsideringAnnotations(Node node) {
+        if (node instanceof MethodDeclaration || node instanceof FieldDeclaration) {
+            NodeWithElementType<?> casted = (NodeWithElementType<?>) node;
+            return casted.getElementType();
+        } else if (node instanceof ClassOrInterfaceDeclaration) {
+            ClassOrInterfaceDeclaration casted = (ClassOrInterfaceDeclaration) node;
+            return casted.getNameExpr();
+        }  else {
+            return node;
+        }
+    }
+
+    public static boolean nodeContains(Node container, Node contained, boolean ignoringAnnotations){
+        if (!ignoringAnnotations || PositionUtils.getLastAnnotation(container)==null){
+            return container.contains(contained);
+        }
+        if (!container.contains(contained)){
+            return false;
+        }
+        // if the node is contained, but it comes immediately after the annotations,
+        // let's not consider it contained
+        if (container instanceof NodeWithAnnotations){
+            int bl = beginLineWithoutConsideringAnnotation(container);
+            int bc = beginColumnWithoutConsideringAnnotation(container);
+            if (bl>contained.getBegin().line) return false;
+            if (bl==contained.getBegin().line && bc>contained.getBegin().column) return false;
+            if (container.getEnd().line<contained.getEnd().line) return false;
+            // TODO < or <= ?
+            return !(container.getEnd().line == contained.getEnd().line && container.getEnd().column < contained.getEnd().column);
+        }
+        return true;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/Utils.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/Utils.java
new file mode 100644
index 0000000..b932085
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-core/com/github/javaparser/utils/Utils.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.utils;
+
+import com.github.javaparser.Provider;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.*;
+
+/**
+ * Any kind of utility.
+ *
+ * @author Federico Tomassetti
+ */
+public class Utils {
+	public static final String EOL = System.getProperty("line.separator");
+	public static <T> List<T> ensureNotNull(List<T> list) {
+		return list == null ? new ArrayList<T>() : list;
+	}
+
+	public static <E> boolean isNullOrEmpty(Collection<E> collection) {
+		return collection == null || collection.isEmpty();
+	}
+
+	public static <T> T assertNotNull(T o) {
+		if (o == null) {
+			throw new NullPointerException("Assertion failed.");
+		}
+		return o;
+	}
+
+	/**
+	 * @return string with ASCII characters 10 and 13 replaced by the text "\n" and "\r".
+	 */
+	public static String escapeEndOfLines(String string) {
+		StringBuilder escapedString = new StringBuilder();
+		for (char c : string.toCharArray()) {
+			switch (c) {
+				case '\n':
+					escapedString.append("\\n");
+					break;
+				case '\r':
+					escapedString.append("\\r");
+					break;
+				default:
+					escapedString.append(c);
+			}
+		}
+		return escapedString.toString();
+	}
+
+	public static String readerToString(Reader reader) throws IOException {
+		final StringBuilder result = new StringBuilder();
+		final char[] buffer = new char[8 * 1024];
+		int numChars;
+
+		while ((numChars = reader.read(buffer, 0, buffer.length)) > 0) {
+			result.append(buffer, 0, numChars);
+		}
+
+		return result.toString();
+	}
+
+	public static String providerToString(Provider provider) throws IOException {
+		final StringBuilder result = new StringBuilder();
+		final char[] buffer = new char[8 * 1024];
+		int numChars;
+
+		while ((numChars = provider.read(buffer, 0, buffer.length)) != -1) {
+			result.append(buffer, 0, numChars);
+		}
+
+		return result.toString();
+	}
+
+	/**
+	 * Puts varargs in a mutable list.
+     * This does not have the disadvantage of Arrays#asList that it has a static size. 
+	 */
+	public static <T> List<T> arrayToList(T[] array){
+		List<T> list = new LinkedList<>();
+		Collections.addAll(list, array);
+		return list;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParser.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParser.java
new file mode 100644
index 0000000..97ed881
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParser.java
@@ -0,0 +1,9318 @@
+/* ASTParser.java */
+/* Generated By:JavaCC: Do not edit this line. ASTParser.java */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+import java.io.*;
+import java.util.*;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.utils.*;
+import static com.github.javaparser.ASTParser.*;
+import static com.github.javaparser.Range.*;
+import static com.github.javaparser.Position.*;
+import static com.github.javaparser.ast.type.ArrayType.*;
+
+/**
+ * <p>This class was generated automatically by javacc, do not edit.</p>
+ */
+final class ASTParser implements ASTParserConstants {
+
+    private final Position INVALID = pos(-1, 0);
+    List<Problem> problems = new ArrayList<Problem>();
+
+    void reset(InputStream in, String encoding) throws IOException {
+        ReInit(new StreamProvider(in, encoding));
+    }
+
+    private <T> List<T> add(List<T> list, T obj) {
+        if (list == null) {
+                list = new LinkedList<T>();
+        }
+        list.add(obj);
+        return list;
+    }
+
+    private <T> List<T> add(int pos, List<T> list, T obj) {
+        if (list == null) {
+                list = new LinkedList<T>();
+        }
+        list.add(pos, obj);
+        return list;
+    }
+
+        private class ModifierHolder {
+                final EnumSet<Modifier> modifiers;
+                final List<AnnotationExpr> annotations;
+                final Position begin;
+
+                public ModifierHolder(Position begin, EnumSet<Modifier> modifiers, List<AnnotationExpr> annotations) {
+                        this.begin = begin;
+                        this.modifiers = modifiers;
+                        this.annotations = annotations;
+                }
+        }
+
+    public void addModifier(EnumSet<Modifier> modifiers, Modifier mod) {
+        if (modifiers.contains(mod)) {
+            addProblem("Duplicated modifier");
+        }
+        modifiers.add(mod);
+    }
+
+    public void addMultipleModifier(EnumSet<Modifier> modifiers, EnumSet<Modifier> mods) {
+        if(mods == null)
+            return;
+        for(Modifier m : mods)
+            if (modifiers.contains(m))
+                addProblem("Duplicated modifier");
+        for(Modifier m : mods)
+            modifiers.add(m);
+    }
+
+    /**
+     * Return the list of tokens that have been encountered while parsing code using
+     * this parser.
+     *
+     * @return a list of tokens
+     */
+    public List<Token> getTokens() {
+        return token_source.getTokens();
+    }
+
+    public CommentsCollection getCommentsCollection() {
+        return token_source.getCommentsCollection();
+    }
+
+    private void addProblem(String message) {
+        problems.add(new Problem(message + ": \"" + token.image, Optional.of(tokenRange()), Optional.empty()));
+    }
+
+    private Expression generateLambda(Expression ret, Statement lambdaBody) {
+            if (ret instanceof EnclosedExpr) {
+                Expression inner = ((EnclosedExpr) ret).getInner();
+                if (inner != null && inner instanceof NameExpr) {
+                    VariableDeclaratorId id = new VariableDeclaratorId(inner.getRange(), ((NameExpr)inner).getName(), null);
+                    List<Parameter> params = add(null, new Parameter(ret.getRange(), EnumSet.noneOf(Modifier.class), null, new UnknownType(), null, false, id));
+                    ret = new LambdaExpr(range(ret.getBegin(), lambdaBody.getEnd()), params, lambdaBody, true);
+                } else {
+                    ret = new LambdaExpr(range(ret.getBegin(), lambdaBody.getEnd()), null, lambdaBody, true);
+                }
+            } else if (ret instanceof NameExpr) {
+                    VariableDeclaratorId id = new VariableDeclaratorId(ret.getRange(), ((NameExpr)ret).getName(), null);
+                List<Parameter> params = add(null, new Parameter(ret.getRange(), EnumSet.noneOf(Modifier.class), null, new UnknownType(), null, false, id));
+                ret = new LambdaExpr(ret.getRange(), params, lambdaBody, false);
+            } else if (ret instanceof LambdaExpr) {
+                ((LambdaExpr) ret).setBody(lambdaBody);
+                ret.setEnd(lambdaBody.getEnd());
+        } else if (ret instanceof CastExpr) {
+            CastExpr castExpr = (CastExpr)ret;
+            Expression inner = generateLambda(castExpr.getExpr(), lambdaBody);
+            castExpr.setExpr(inner);
+            } else {
+                addProblem("Failed to parse lambda expression! Please create an issue at https://github.com/javaparser/javaparser/issues");
+            }
+            return ret;
+    }
+
+    private ArrayCreationExpr juggleArrayCreation(Range range, Type type, List<Expression> dimensions, List<List<AnnotationExpr>> arrayAnnotations, ArrayInitializerExpr arrayInitializerExpr) {
+        List<ArrayCreationLevel> levels = new ArrayList<ArrayCreationLevel>();
+
+        for(int i = 0; i < arrayAnnotations.size(); i++){
+            levels.add(new ArrayCreationLevel(range, dimensions.get(i), arrayAnnotations.get(i)));
+        }
+        return new ArrayCreationExpr(range, type, levels, arrayInitializerExpr);
+    }
+
+
+    static final class GTToken extends Token {
+        int realKind = ASTParserConstants.GT;
+
+        GTToken(int kind, String image) {
+            this.kind = kind;
+            this.image = image;
+        }
+
+        public static Token newToken(int kind, String image) {
+            return new GTToken(kind, image);
+        }
+    }
+
+    private static class RangedList<T> {
+        Range range = Range.UNKNOWN;
+        List<T> list;
+        RangedList(List<T> list) {
+            this.list = list;
+        }
+        void beginAt(Position begin) {
+            range=range.withBegin(begin);
+        }
+        void endAt(Position end) {
+            range=range.withEnd(end);
+        }
+        void add(T t) {
+            if (list == null) {
+                list = new LinkedList<T>();
+            }
+            list.add(t);
+        }
+    }
+
+    private Position tokenBegin() {
+        return pos(token.beginLine,token.beginColumn);
+    }
+
+    private Position tokenEnd() {
+        return pos(token.endLine,token.endColumn);
+    }
+
+    private Range tokenRange() {
+        return tokenRange(token);
+    }
+
+    public static Range tokenRange(Token token) {
+        return range(token.beginLine, token.beginColumn, token.endLine, token.endColumn);
+    }
+
+/*****************************************
+ * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
+ *****************************************/
+
+/*
+ * Program structuring syntax follows.
+ */
+  final public 
+CompilationUnit CompilationUnit() {PackageDeclaration pakage = null;
+        List<ImportDeclaration> imports = null;
+        ImportDeclaration in = null;
+        List<TypeDeclaration<?>> types = null;
+        TypeDeclaration tn = null;
+        Position begin = INVALID;
+    if (jj_2_1(2147483647)) {
+      pakage = PackageDeclaration();
+begin = begin.orIfInvalid(pakage.getBegin());
+    } else {
+      ;
+    }
+    label_1:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case IMPORT:
+      case SEMICOLON:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[0] = jj_gen;
+        break label_1;
+      }
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case IMPORT:{
+        in = ImportDeclaration();
+begin = begin.orIfInvalid(in.getBegin()); imports = add(imports, in);
+        break;
+        }
+      case SEMICOLON:{
+        in = EmptyImportDeclaration();
+begin = begin.orIfInvalid(in.getBegin()); imports = add(imports, in);
+        break;
+        }
+      default:
+        jj_la1[1] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    label_2:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ABSTRACT:
+      case CLASS:
+      case ENUM:
+      case FINAL:
+      case INTERFACE:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOLATILE:
+      case SEMICOLON:
+      case AT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[2] = jj_gen;
+        break label_2;
+      }
+      tn = TypeDeclaration();
+begin = begin.orIfInvalid(tn.getBegin()); types = add(types, tn);
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case 0:{
+      jj_consume_token(0);
+      break;
+      }
+    case 156:{
+      jj_consume_token(156);
+      break;
+      }
+    default:
+      jj_la1[3] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return new CompilationUnit(begin.invalid() ? Range.UNKNOWN : range(begin, tokenEnd()), pakage, imports, types);
+  }
+
+  final public ImportDeclaration EmptyImportDeclaration() {Position begin;
+    jj_consume_token(SEMICOLON);
+begin = tokenBegin();
+return ImportDeclaration.createEmptyDeclaration(range(begin, tokenEnd()));
+  }
+
+  final public PackageDeclaration PackageDeclaration() {List<AnnotationExpr> annotations = null;
+        NameExpr name;
+        Position begin;
+    annotations = Annotations();
+    jj_consume_token(PACKAGE);
+begin = tokenBegin();
+    name = Name();
+    jj_consume_token(SEMICOLON);
+return new PackageDeclaration(range(begin, tokenEnd()), annotations, name);
+  }
+
+  final public ImportDeclaration ImportDeclaration() {NameExpr name;
+        boolean isStatic = false;
+        boolean isAsterisk = false;
+        Position begin;
+    jj_consume_token(IMPORT);
+begin = tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case STATIC:{
+      jj_consume_token(STATIC);
+isStatic = true;
+      break;
+      }
+    default:
+      jj_la1[4] = jj_gen;
+      ;
+    }
+    name = Name();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case DOT:{
+      jj_consume_token(DOT);
+      jj_consume_token(STAR);
+isAsterisk = true;
+      break;
+      }
+    default:
+      jj_la1[5] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+return new ImportDeclaration(range(begin, tokenEnd()),name, isStatic, isAsterisk);
+  }
+
+/*
+ * Modifiers. We match all modifiers in a single rule to reduce the chances of
+ * syntax errors for simple modifier mistakes. It will also enable us to give
+ * better error messages.
+ */
+  final public 
+ModifierHolder Modifiers() {Position begin = INVALID;
+    EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
+    List<AnnotationExpr> annotations = null;
+    AnnotationExpr ann;
+    label_3:
+    while (true) {
+      if (jj_2_2(2)) {
+        ;
+      } else {
+        break label_3;
+      }
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case PUBLIC:{
+        jj_consume_token(PUBLIC);
+addModifier(modifiers, Modifier.PUBLIC); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case STATIC:{
+        jj_consume_token(STATIC);
+addModifier(modifiers, Modifier.STATIC); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case PROTECTED:{
+        jj_consume_token(PROTECTED);
+addModifier(modifiers, Modifier.PROTECTED); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case PRIVATE:{
+        jj_consume_token(PRIVATE);
+addModifier(modifiers, Modifier.PRIVATE); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case FINAL:{
+        jj_consume_token(FINAL);
+addModifier(modifiers, Modifier.FINAL); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case ABSTRACT:{
+        jj_consume_token(ABSTRACT);
+addModifier(modifiers, Modifier.ABSTRACT); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case SYNCHRONIZED:{
+        jj_consume_token(SYNCHRONIZED);
+addModifier(modifiers, Modifier.SYNCHRONIZED); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case NATIVE:{
+        jj_consume_token(NATIVE);
+addModifier(modifiers, Modifier.NATIVE); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case TRANSIENT:{
+        jj_consume_token(TRANSIENT);
+addModifier(modifiers, Modifier.TRANSIENT); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case VOLATILE:{
+        jj_consume_token(VOLATILE);
+addModifier(modifiers, Modifier.VOLATILE); begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case STRICTFP:{
+        jj_consume_token(STRICTFP);
+addModifier(modifiers, Modifier.STRICTFP);  begin = begin.orIfInvalid(tokenBegin());
+        break;
+        }
+      case AT:{
+        ann = Annotation();
+annotations = add(annotations, ann); begin = begin.orIfInvalid(ann.getBegin());
+        break;
+        }
+      default:
+        jj_la1[6] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return new ModifierHolder(begin, modifiers, annotations);
+  }
+
+/*
+ * Declaration syntax follows.
+ */
+  final public TypeDeclaration TypeDeclaration() {ModifierHolder modifier;
+   TypeDeclaration ret;
+
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case SEMICOLON:{
+      jj_consume_token(SEMICOLON);
+ret = new EmptyTypeDeclaration(tokenRange());
+      break;
+      }
+    case ABSTRACT:
+    case CLASS:
+    case ENUM:
+    case FINAL:
+    case INTERFACE:
+    case NATIVE:
+    case PRIVATE:
+    case PROTECTED:
+    case PUBLIC:
+    case STATIC:
+    case STRICTFP:
+    case SYNCHRONIZED:
+    case TRANSIENT:
+    case VOLATILE:
+    case AT:{
+      modifier = Modifiers();
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case CLASS:
+      case INTERFACE:{
+        ret = ClassOrInterfaceDeclaration(modifier);
+        break;
+        }
+      case ENUM:{
+        ret = EnumDeclaration(modifier);
+        break;
+        }
+      case AT:{
+        ret = AnnotationTypeDeclaration(modifier);
+        break;
+        }
+      default:
+        jj_la1[7] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+      }
+    default:
+      jj_la1[8] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration(ModifierHolder modifier) {boolean isInterface = false;
+    NameExpr name;
+    RangedList<TypeParameter> typePar = new RangedList<TypeParameter>(null);
+    List<ClassOrInterfaceType> extList = null;
+    List<ClassOrInterfaceType> impList = null;
+    List<BodyDeclaration<?>> members;
+    Position begin = modifier.begin;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case CLASS:{
+      jj_consume_token(CLASS);
+      break;
+      }
+    case INTERFACE:{
+      jj_consume_token(INTERFACE);
+isInterface = true;
+      break;
+      }
+    default:
+      jj_la1[9] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+begin = begin.orIfInvalid(tokenBegin());
+    name = Name();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LT:{
+      typePar = TypeParameters();
+      break;
+      }
+    default:
+      jj_la1[10] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case EXTENDS:{
+      extList = ExtendsList(isInterface);
+      break;
+      }
+    default:
+      jj_la1[11] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case IMPLEMENTS:{
+      impList = ImplementsList(isInterface);
+      break;
+      }
+    default:
+      jj_la1[12] = jj_gen;
+      ;
+    }
+    members = ClassOrInterfaceBody(isInterface);
+ClassOrInterfaceDeclaration tmp = new ClassOrInterfaceDeclaration(range(begin, tokenEnd()), modifier.modifiers, modifier.annotations, isInterface, null, typePar.list, extList, impList, members);
+    tmp.setNameExpr(name);
+    return tmp;
+  }
+
+  final public List<ClassOrInterfaceType> ExtendsList(boolean isInterface) {boolean extendsMoreThanOne = false;
+   List<ClassOrInterfaceType> ret = new LinkedList<ClassOrInterfaceType>();
+   ClassOrInterfaceType cit;
+    jj_consume_token(EXTENDS);
+    cit = AnnotatedClassOrInterfaceType();
+ret.add(cit);
+    label_4:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[13] = jj_gen;
+        break label_4;
+      }
+      jj_consume_token(COMMA);
+      cit = AnnotatedClassOrInterfaceType();
+ret.add(cit); extendsMoreThanOne = true;
+    }
+if (extendsMoreThanOne && !isInterface)
+         addProblem("A class cannot extend more than one other class");
+return ret;
+  }
+
+  final public List<ClassOrInterfaceType> ImplementsList(boolean isInterface) {List<ClassOrInterfaceType> ret = new LinkedList<ClassOrInterfaceType>();
+   ClassOrInterfaceType cit;
+    jj_consume_token(IMPLEMENTS);
+    cit = AnnotatedClassOrInterfaceType();
+ret.add(cit);
+    label_5:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[14] = jj_gen;
+        break label_5;
+      }
+      jj_consume_token(COMMA);
+      cit = AnnotatedClassOrInterfaceType();
+ret.add(cit);
+    }
+if (isInterface)
+         addProblem("An interface cannot implement other interfaces");
+return ret;
+  }
+
+  final public EnumDeclaration EnumDeclaration(ModifierHolder modifier) {NameExpr name;
+        List<ClassOrInterfaceType> impList = null;
+        EnumConstantDeclaration entry;
+        List<EnumConstantDeclaration> entries = null;
+        BodyDeclaration<?> member;
+        List<BodyDeclaration<?>> members = null;
+        Position begin = modifier.begin;
+    jj_consume_token(ENUM);
+begin = begin.orIfInvalid(tokenBegin());
+    name = Name();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case IMPLEMENTS:{
+      impList = ImplementsList(false);
+      break;
+      }
+    default:
+      jj_la1[15] = jj_gen;
+      ;
+    }
+    jj_consume_token(LBRACE);
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case IDENTIFIER:
+    case AT:{
+entries = new LinkedList<EnumConstantDeclaration>();
+      entry = EnumConstantDeclaration();
+entries.add(entry);
+      label_6:
+      while (true) {
+        if (jj_2_3(2)) {
+          ;
+        } else {
+          break label_6;
+        }
+        jj_consume_token(COMMA);
+        entry = EnumConstantDeclaration();
+entries.add(entry);
+      }
+      break;
+      }
+    default:
+      jj_la1[16] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case COMMA:{
+      jj_consume_token(COMMA);
+      break;
+      }
+    default:
+      jj_la1[17] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case SEMICOLON:{
+      jj_consume_token(SEMICOLON);
+      label_7:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case ABSTRACT:
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case CLASS:
+        case _DEFAULT:
+        case DOUBLE:
+        case ENUM:
+        case FINAL:
+        case FLOAT:
+        case INT:
+        case INTERFACE:
+        case LONG:
+        case NATIVE:
+        case PRIVATE:
+        case PROTECTED:
+        case PUBLIC:
+        case SHORT:
+        case STATIC:
+        case STRICTFP:
+        case SYNCHRONIZED:
+        case TRANSIENT:
+        case VOID:
+        case VOLATILE:
+        case IDENTIFIER:
+        case LBRACE:
+        case SEMICOLON:
+        case AT:
+        case LT:{
+          ;
+          break;
+          }
+        default:
+          jj_la1[18] = jj_gen;
+          break label_7;
+        }
+        member = ClassOrInterfaceBodyDeclaration(false);
+members = add(members, member);
+      }
+      break;
+      }
+    default:
+      jj_la1[19] = jj_gen;
+      ;
+    }
+    jj_consume_token(RBRACE);
+EnumDeclaration tmp = new EnumDeclaration(range(begin, tokenEnd()), modifier.modifiers, modifier.annotations, null, impList, entries, members);
+      tmp.setNameExpr(name);
+      return tmp;
+  }
+
+  final public EnumConstantDeclaration EnumConstantDeclaration() {List<AnnotationExpr> annotations = null;
+        AnnotationExpr ann;
+        String name;
+        List<Expression> args = null;
+        List<BodyDeclaration<?>> classBody = null;
+        Position begin = INVALID;
+
+    label_8:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case AT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[20] = jj_gen;
+        break label_8;
+      }
+      ann = Annotation();
+annotations = add(annotations, ann); begin = begin.orIfInvalid(ann.getBegin());
+    }
+    jj_consume_token(IDENTIFIER);
+name = token.image; begin = begin.orIfInvalid(tokenBegin());
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LPAREN:{
+      args = Arguments();
+      break;
+      }
+    default:
+      jj_la1[21] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LBRACE:{
+      classBody = ClassOrInterfaceBody(false);
+      break;
+      }
+    default:
+      jj_la1[22] = jj_gen;
+      ;
+    }
+return new EnumConstantDeclaration(range(begin, tokenEnd()), annotations, name, args, classBody);
+  }
+
+/**
+ * If the list inside the returned RangedList is null, there are no brackets.
+ * If it is empty, there are brackets, but nothing is in them <>.
+ * The normal case is that it contains TypeParameters, like <A, B, C>.
+ */
+  final public RangedList<TypeParameter> TypeParameters() {RangedList<TypeParameter> ret = new RangedList<TypeParameter>(new LinkedList<TypeParameter>());
+        TypeParameter tp;
+        List<AnnotationExpr> annotations = null;
+    jj_consume_token(LT);
+ret.beginAt(tokenBegin());
+    annotations = Annotations();
+    tp = TypeParameter();
+ret.add(tp); tp.setAnnotations(annotations); annotations = null;
+    label_9:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[23] = jj_gen;
+        break label_9;
+      }
+      jj_consume_token(COMMA);
+      annotations = Annotations();
+      tp = TypeParameter();
+ret.add(tp); tp.setAnnotations(annotations); annotations = null;
+    }
+    jj_consume_token(GT);
+ret.endAt(tokenEnd());
+return ret;
+  }
+
+  final public TypeParameter TypeParameter() {String name;
+        List<ClassOrInterfaceType> typeBound = null;
+        Position begin;
+    jj_consume_token(IDENTIFIER);
+name = token.image; begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case EXTENDS:{
+      typeBound = TypeBound();
+      break;
+      }
+    default:
+      jj_la1[24] = jj_gen;
+      ;
+    }
+return new TypeParameter(range(begin, tokenEnd()),name, typeBound);
+  }
+
+  final public List<ClassOrInterfaceType> TypeBound() {List<ClassOrInterfaceType> ret = new LinkedList<ClassOrInterfaceType>();
+        ClassOrInterfaceType cit;
+    jj_consume_token(EXTENDS);
+    cit = AnnotatedClassOrInterfaceType();
+ret.add(cit);
+    label_10:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BIT_AND:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[25] = jj_gen;
+        break label_10;
+      }
+      jj_consume_token(BIT_AND);
+      cit = AnnotatedClassOrInterfaceType();
+ret.add(cit);
+    }
+return ret;
+  }
+
+  final public List<BodyDeclaration<?>> ClassOrInterfaceBody(boolean isInterface) {List<BodyDeclaration<?>> ret = new LinkedList<BodyDeclaration<?>>();
+        BodyDeclaration member;
+    jj_consume_token(LBRACE);
+    label_11:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case _DEFAULT:
+      case DOUBLE:
+      case ENUM:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOID:
+      case VOLATILE:
+      case IDENTIFIER:
+      case LBRACE:
+      case SEMICOLON:
+      case AT:
+      case LT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[26] = jj_gen;
+        break label_11;
+      }
+      member = ClassOrInterfaceBodyDeclaration(isInterface);
+ret.add(member);
+    }
+    jj_consume_token(RBRACE);
+return ret;
+  }
+
+  final public BodyDeclaration<?> ClassOrInterfaceBodyDeclaration(boolean isInterface) {ModifierHolder modifier;
+   ModifierHolder modifier2 = null;
+   EnumSet<Modifier> aux = null;
+   BodyDeclaration<?> ret;
+   boolean isDefault = false;
+
+    if (jj_2_6(2)) {
+      ret = InitializerDeclaration();
+if (isInterface)
+                addProblem("An interface cannot have initializers");
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case _DEFAULT:
+      case DOUBLE:
+      case ENUM:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOID:
+      case VOLATILE:
+      case IDENTIFIER:
+      case AT:
+      case LT:{
+        modifier = Modifiers();
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case _DEFAULT:{
+          jj_consume_token(_DEFAULT);
+          modifier2 = Modifiers();
+if(!isInterface)
+            {
+              addProblem("A class cannot have default members");
+            }
+            isDefault = true;
+          break;
+          }
+        default:
+          jj_la1[27] = jj_gen;
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case CLASS:
+        case INTERFACE:{
+          ret = ClassOrInterfaceDeclaration(modifier);
+          break;
+          }
+        case ENUM:{
+          ret = EnumDeclaration(modifier);
+          break;
+          }
+        case AT:{
+          ret = AnnotationTypeDeclaration(modifier);
+          break;
+          }
+        default:
+          jj_la1[28] = jj_gen;
+          if (jj_2_4(2147483647)) {
+            ret = ConstructorDeclaration(modifier);
+          } else if (jj_2_5(2147483647)) {
+            ret = FieldDeclaration(modifier);
+          } else {
+            switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+            case BOOLEAN:
+            case BYTE:
+            case CHAR:
+            case DOUBLE:
+            case FLOAT:
+            case INT:
+            case LONG:
+            case SHORT:
+            case VOID:
+            case IDENTIFIER:
+            case LT:{
+              ret = MethodDeclaration(modifier);
+if(isDefault && ret!= null && ((MethodDeclaration)ret).getBody() == null)
+                {
+                  addProblem("\"default\" methods must have a body");
+                }
+                ((MethodDeclaration)ret).setDefault(isDefault);
+                if(modifier2!= null)
+                {
+                  aux = modifier2.modifiers;
+                }
+                addMultipleModifier(modifier.modifiers, aux);
+                ((MethodDeclaration)ret).setModifiers(modifier.modifiers);
+              break;
+              }
+            default:
+              jj_la1[29] = jj_gen;
+              jj_consume_token(-1);
+              throw new ParseException();
+            }
+          }
+        }
+if(isDefault && ! (ret instanceof MethodDeclaration))
+            {
+              addProblem("Only methods can have the keyword \"default\".");
+            }
+        break;
+        }
+      case SEMICOLON:{
+        jj_consume_token(SEMICOLON);
+ret = new EmptyMemberDeclaration(tokenRange());
+        break;
+        }
+      default:
+        jj_la1[30] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public FieldDeclaration FieldDeclaration(ModifierHolder modifier) {Type type;
+        List<VariableDeclarator> variables = new LinkedList<VariableDeclarator>();
+        VariableDeclarator val;
+    // Modifiers are already matched in the caller
+      type = Type();
+    val = VariableDeclarator();
+variables.add(val);
+    label_12:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[31] = jj_gen;
+        break label_12;
+      }
+      jj_consume_token(COMMA);
+      val = VariableDeclarator();
+variables.add(val);
+    }
+    jj_consume_token(SEMICOLON);
+Position begin = modifier.begin.orIfInvalid(type.getBegin());
+        Pair<Type, List<ArrayBracketPair>> typeListPair = unwrapArrayTypes(type);
+        return new FieldDeclaration(range(begin, tokenEnd()), modifier.modifiers, modifier.annotations, typeListPair.a, variables, typeListPair.b);
+  }
+
+  final public VariableDeclarator VariableDeclarator() {VariableDeclaratorId id;
+        Expression init = null;
+    id = VariableDeclaratorId();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case ASSIGN:{
+      jj_consume_token(ASSIGN);
+      init = VariableInitializer();
+      break;
+      }
+    default:
+      jj_la1[32] = jj_gen;
+      ;
+    }
+return new  VariableDeclarator(range(id.getBegin(), tokenEnd()), id, init);
+  }
+
+  final public VariableDeclaratorId VariableDeclaratorId() {String name;
+        Position begin;
+        ArrayBracketPair arrayBracketPair;
+        List<ArrayBracketPair> arrayBracketPairs = null;
+    jj_consume_token(IDENTIFIER);
+name = token.image; begin=tokenBegin();
+    label_13:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LBRACKET:
+      case AT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[33] = jj_gen;
+        break label_13;
+      }
+      arrayBracketPair = ArrayBracketPair();
+arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair);
+    }
+return new VariableDeclaratorId(range(begin, tokenEnd()),name, arrayBracketPairs);
+  }
+
+  final public Expression VariableInitializer() {Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LBRACE:{
+      ret = ArrayInitializer();
+      break;
+      }
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:{
+      ret = Expression();
+      break;
+      }
+    default:
+      jj_la1[34] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public ArrayInitializerExpr ArrayInitializer() {List<Expression> values = null;
+        Expression val;
+        Position begin;
+    jj_consume_token(LBRACE);
+begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case LBRACE:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:{
+      val = VariableInitializer();
+values = add(values, val);
+      label_14:
+      while (true) {
+        if (jj_2_7(2)) {
+          ;
+        } else {
+          break label_14;
+        }
+        jj_consume_token(COMMA);
+        val = VariableInitializer();
+values = add(values, val);
+      }
+      break;
+      }
+    default:
+      jj_la1[35] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case COMMA:{
+      jj_consume_token(COMMA);
+      break;
+      }
+    default:
+      jj_la1[36] = jj_gen;
+      ;
+    }
+    jj_consume_token(RBRACE);
+return new ArrayInitializerExpr(range(begin, tokenEnd()), values);
+  }
+
+  final public MethodDeclaration MethodDeclaration(ModifierHolder modifier) {RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(null);
+        Type type;
+        NameExpr name;
+        List<Parameter> parameters;
+        ArrayBracketPair arrayBracketPair;
+        List<ArrayBracketPair> arrayBracketPairs = null;
+        List<ReferenceType> throws_ = null;
+        BlockStmt block = null;
+        Position begin = modifier.begin;
+        ReferenceType throwType;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LT:{
+      typeParameters = TypeParameters();
+begin = begin.orIfInvalid(typeParameters.range.begin);
+      break;
+      }
+    default:
+      jj_la1[37] = jj_gen;
+      ;
+    }
+    type = ResultType();
+begin = begin.orIfInvalid(type.getBegin());
+    name = Name();
+    parameters = FormalParameters();
+    label_15:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LBRACKET:
+      case AT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[38] = jj_gen;
+        break label_15;
+      }
+      arrayBracketPair = ArrayBracketPair();
+arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair);
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case THROWS:{
+      jj_consume_token(THROWS);
+      throwType = ReferenceTypeWithAnnotations();
+throws_ = add(throws_, throwType);
+      label_16:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case COMMA:{
+          ;
+          break;
+          }
+        default:
+          jj_la1[39] = jj_gen;
+          break label_16;
+        }
+        jj_consume_token(COMMA);
+        throwType = ReferenceTypeWithAnnotations();
+throws_ = add(throws_, throwType);
+      }
+      break;
+      }
+    default:
+      jj_la1[40] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LBRACE:{
+      block = Block();
+      break;
+      }
+    case SEMICOLON:{
+      jj_consume_token(SEMICOLON);
+      break;
+      }
+    default:
+      jj_la1[41] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+Pair<Type, List<ArrayBracketPair>> typeListPair = unwrapArrayTypes(type);
+        return new MethodDeclaration(range(begin, pos(token.endLine, token.endColumn)), modifier.modifiers, modifier.annotations, typeParameters.list, typeListPair.a, typeListPair.b, name, parameters, arrayBracketPairs, throws_, block);
+  }
+
+  final public ReferenceType ReferenceTypeWithAnnotations() {List<AnnotationExpr> annotations;
+        ReferenceType type;
+    annotations = Annotations();
+    type = ReferenceType();
+if(annotations != null){
+            if (type.getAnnotations() != null) {
+                type.getAnnotations().addAll(annotations);
+            } else {
+                type.setAnnotations(annotations);
+            }
+        }
+        return type;
+  }
+
+  final public List<Parameter> FormalParameters() {List<Parameter> ret = null;
+        Parameter par;
+    jj_consume_token(LPAREN);
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case ABSTRACT:
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FINAL:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NATIVE:
+    case PRIVATE:
+    case PROTECTED:
+    case PUBLIC:
+    case SHORT:
+    case STATIC:
+    case STRICTFP:
+    case SYNCHRONIZED:
+    case TRANSIENT:
+    case VOLATILE:
+    case IDENTIFIER:
+    case AT:{
+      par = FormalParameter();
+ret = add(ret, par);
+      label_17:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case COMMA:{
+          ;
+          break;
+          }
+        default:
+          jj_la1[42] = jj_gen;
+          break label_17;
+        }
+        jj_consume_token(COMMA);
+        par = FormalParameter();
+ret = add(ret, par);
+      }
+      break;
+      }
+    default:
+      jj_la1[43] = jj_gen;
+      ;
+    }
+    jj_consume_token(RPAREN);
+return ret;
+  }
+
+  final public List<Parameter> FormalLambdaParameters() {List<Parameter> ret = null;
+  Parameter par;
+    jj_consume_token(COMMA);
+    par = FormalParameter();
+ret = add(ret, par);
+    label_18:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[44] = jj_gen;
+        break label_18;
+      }
+      jj_consume_token(COMMA);
+      par = FormalParameter();
+ret = add(ret, par);
+    }
+return ret;
+  }
+
+  final public List<Parameter> InferredLambdaParameters() {List<Parameter> ret = null;
+  VariableDeclaratorId id;
+    jj_consume_token(COMMA);
+    id = VariableDeclaratorId();
+ret = add(ret, new Parameter(range(id.getBegin(), id.getEnd()), EnumSet.noneOf(Modifier.class), null, new UnknownType(), null, false, id));
+    label_19:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[45] = jj_gen;
+        break label_19;
+      }
+      jj_consume_token(COMMA);
+      id = VariableDeclaratorId();
+ret = add(ret, new Parameter(range(id.getBegin(), id.getEnd()), EnumSet.noneOf(Modifier.class), null, new UnknownType(), null, false, id));
+    }
+return ret;
+  }
+
+  final public Parameter FormalParameter() {ModifierHolder modifier;
+        Type type;
+        boolean isVarArg = false;
+        VariableDeclaratorId id;
+    modifier = Modifiers();
+    type = Type();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case ELLIPSIS:{
+      jj_consume_token(ELLIPSIS);
+isVarArg = true;
+      break;
+      }
+    default:
+      jj_la1[46] = jj_gen;
+      ;
+    }
+    id = VariableDeclaratorId();
+Position begin = modifier.begin.orIfInvalid(type.getBegin());
+        Pair<Type, List<ArrayBracketPair>> typeListPair = unwrapArrayTypes(type);
+        return new Parameter(range(begin, tokenEnd()), modifier.modifiers, modifier.annotations, typeListPair.a, typeListPair.b, isVarArg, id);
+  }
+
+  final public ConstructorDeclaration ConstructorDeclaration(ModifierHolder modifier) {RangedList<TypeParameter> typeParameters = new RangedList<TypeParameter>(null);
+        NameExpr name;
+        List<Parameter> parameters;
+        List<ReferenceType> throws_ = null;
+        ExplicitConstructorInvocationStmt exConsInv = null;
+        List<Statement> stmts;
+    Position begin = modifier.begin;
+        Position blockBegin = INVALID;
+        ReferenceType throwType;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LT:{
+      typeParameters = TypeParameters();
+begin = begin.orIfInvalid(typeParameters.range.begin);
+      break;
+      }
+    default:
+      jj_la1[47] = jj_gen;
+      ;
+    }
+    // Modifiers matched in the caller
+      name = SimpleName();
+begin = begin.orIfInvalid(typeParameters.range.begin);
+    parameters = FormalParameters();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case THROWS:{
+      jj_consume_token(THROWS);
+      throwType = ReferenceTypeWithAnnotations();
+throws_ = add(throws_, throwType);
+      label_20:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case COMMA:{
+          ;
+          break;
+          }
+        default:
+          jj_la1[48] = jj_gen;
+          break label_20;
+        }
+        jj_consume_token(COMMA);
+        throwType = ReferenceTypeWithAnnotations();
+throws_ = add(throws_, throwType);
+      }
+      break;
+      }
+    default:
+      jj_la1[49] = jj_gen;
+      ;
+    }
+    jj_consume_token(LBRACE);
+blockBegin=tokenBegin();
+    if (jj_2_8(2147483647)) {
+      exConsInv = ExplicitConstructorInvocation();
+    } else {
+      ;
+    }
+    stmts = Statements();
+    jj_consume_token(RBRACE);
+if (exConsInv != null) {
+                stmts = add(0, stmts, exConsInv);
+        }
+        ConstructorDeclaration tmp = new ConstructorDeclaration(range(begin, pos(token.endLine, token.endColumn)), modifier.modifiers, modifier.annotations, typeParameters.list, null, parameters, throws_, new BlockStmt(range(blockBegin, tokenEnd()), stmts));
+    tmp.setNameExpr(name);
+    return tmp;
+  }
+
+  final public ExplicitConstructorInvocationStmt ExplicitConstructorInvocation() {boolean isThis = false;
+        List<Expression> args;
+        Expression expr = null;
+        RangedList<Type<?>> typeArgs = new RangedList<Type<?>>(null);
+        Position begin = INVALID;
+    if (jj_2_10(2147483647)) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LT:{
+        typeArgs = TypeArguments();
+begin=typeArgs.range.begin;
+        break;
+        }
+      default:
+        jj_la1[50] = jj_gen;
+        ;
+      }
+      jj_consume_token(THIS);
+begin = begin.orIfInvalid(tokenBegin()); isThis = true;
+      args = Arguments();
+      jj_consume_token(SEMICOLON);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case LT:{
+        if (jj_2_9(2147483647)) {
+          expr = PrimaryExpressionWithoutSuperSuffix();
+          jj_consume_token(DOT);
+begin=expr.getBegin();
+        } else {
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case LT:{
+          typeArgs = TypeArguments();
+begin = begin.orIfInvalid(typeArgs.range.begin);
+          break;
+          }
+        default:
+          jj_la1[51] = jj_gen;
+          ;
+        }
+        jj_consume_token(SUPER);
+begin = begin.orIfInvalid(tokenBegin());
+        args = Arguments();
+        jj_consume_token(SEMICOLON);
+        break;
+        }
+      default:
+        jj_la1[52] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return new ExplicitConstructorInvocationStmt(range(begin, tokenEnd()),typeArgs.list, isThis, expr, args);
+  }
+
+  final public List<Statement> Statements() {List<Statement> ret = null;
+        Statement stmt;
+    label_21:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ABSTRACT:
+      case ASSERT:
+      case BOOLEAN:
+      case BREAK:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case CONTINUE:
+      case DO:
+      case DOUBLE:
+      case FALSE:
+      case FINAL:
+      case FLOAT:
+      case FOR:
+      case IF:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case NEW:
+      case NULL:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case RETURN:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SUPER:
+      case SWITCH:
+      case SYNCHRONIZED:
+      case THIS:
+      case THROW:
+      case TRANSIENT:
+      case TRUE:
+      case TRY:
+      case VOID:
+      case VOLATILE:
+      case WHILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case LBRACE:
+      case SEMICOLON:
+      case AT:
+      case INCR:
+      case DECR:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[53] = jj_gen;
+        break label_21;
+      }
+      stmt = BlockStatement();
+ret = add(ret, stmt);
+    }
+return ret;
+  }
+
+  final public InitializerDeclaration InitializerDeclaration() {BlockStmt block;
+        Position begin = INVALID;
+        boolean isStatic = false;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case STATIC:{
+      jj_consume_token(STATIC);
+isStatic = true; begin=tokenBegin();
+      break;
+      }
+    default:
+      jj_la1[54] = jj_gen;
+      ;
+    }
+    block = Block();
+begin = begin.orIfInvalid(block.getBegin());
+return new InitializerDeclaration(range(begin, tokenEnd()), isStatic, block);
+  }
+
+/*
+ * Type, name and expression syntax follows.
+ */
+  final public 
+Type Type() {Type ret;
+    if (jj_2_11(2)) {
+      ret = ReferenceType();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case SHORT:{
+        ret = PrimitiveType();
+        break;
+        }
+      default:
+        jj_la1[55] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public ReferenceType ReferenceType() {Type type;
+        ArrayBracketPair arrayBracketPair;
+        List<ArrayBracketPair> arrayBracketPairs = null;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:{
+      type = PrimitiveType();
+      label_22:
+      while (true) {
+        arrayBracketPair = ArrayBracketPair();
+arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair);
+        if (jj_2_12(2)) {
+          ;
+        } else {
+          break label_22;
+        }
+      }
+      break;
+      }
+    case IDENTIFIER:{
+      type = ClassOrInterfaceType();
+      label_23:
+      while (true) {
+        if (jj_2_13(2)) {
+          ;
+        } else {
+          break label_23;
+        }
+        arrayBracketPair = ArrayBracketPair();
+arrayBracketPairs=add(arrayBracketPairs, arrayBracketPair);
+      }
+      break;
+      }
+    default:
+      jj_la1[56] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return (ReferenceType)wrapInArrayTypes(type, arrayBracketPairs);
+  }
+
+  final public ArrayBracketPair ArrayBracketPair() {List<AnnotationExpr> annotations = null;
+    Position begin = INVALID;
+    annotations = Annotations();
+    jj_consume_token(LBRACKET);
+begin = begin.orIfInvalid(tokenBegin());
+    jj_consume_token(RBRACKET);
+return new ArrayBracketPair(range(begin, tokenEnd()), annotations);
+  }
+
+  final public IntersectionType IntersectionType() {Position begin;
+        ReferenceType elementType;
+        List<ReferenceType> elements = null;
+    elementType = ReferenceType();
+begin=elementType.getBegin(); elements = add(elements, elementType);
+    jj_consume_token(BIT_AND);
+    label_24:
+    while (true) {
+      elementType = ReferenceType();
+elements = add(elements, elementType);
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case SHORT:
+      case IDENTIFIER:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[57] = jj_gen;
+        break label_24;
+      }
+    }
+return new IntersectionType(range(begin, tokenEnd()), elements);
+  }
+
+  final public ClassOrInterfaceType AnnotatedClassOrInterfaceType() {List<AnnotationExpr> annotations;
+        ClassOrInterfaceType cit;
+    annotations = Annotations();
+    cit = ClassOrInterfaceType();
+if (cit.getScope()!=null) {
+            cit.getScope().setAnnotations(annotations);
+        } else {
+            cit.setAnnotations(annotations);
+        }
+        return cit;
+  }
+
+  final public ClassOrInterfaceType ClassOrInterfaceType() {ClassOrInterfaceType ret;
+        String name;
+        RangedList<Type<?>> typeArgs = new RangedList<Type<?>>(null);
+        Position begin;
+        List<AnnotationExpr> annotations = null;
+    jj_consume_token(IDENTIFIER);
+begin=tokenBegin();
+name = token.image;
+    if (jj_2_14(2)) {
+      typeArgs = TypeArguments();
+    } else {
+      ;
+    }
+ret = new ClassOrInterfaceType(range(begin, tokenEnd()),null, name, typeArgs.list);
+    label_25:
+    while (true) {
+      if (jj_2_15(2)) {
+        ;
+      } else {
+        break label_25;
+      }
+      jj_consume_token(DOT);
+      annotations = Annotations();
+      jj_consume_token(IDENTIFIER);
+name = token.image;
+      if (jj_2_16(2)) {
+        typeArgs = TypeArguments();
+      } else {
+        ;
+      }
+ret = new ClassOrInterfaceType(range(begin, tokenEnd()),ret, name, typeArgs.list);
+            ret.setAnnotations(annotations);
+            annotations = null;
+    }
+return ret;
+  }
+
+  final public RangedList<Type<?>> TypeArguments() {RangedList<Type<?>> ret = new RangedList<Type<?>>(new LinkedList<Type<?>>());
+        Type type;
+    jj_consume_token(LT);
+ret.beginAt(tokenBegin());
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:
+    case IDENTIFIER:
+    case AT:
+    case HOOK:{
+      type = TypeArgument();
+ret.add(type);
+      label_26:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case COMMA:{
+          ;
+          break;
+          }
+        default:
+          jj_la1[58] = jj_gen;
+          break label_26;
+        }
+        jj_consume_token(COMMA);
+        type = TypeArgument();
+ret.add(type);
+      }
+      break;
+      }
+    default:
+      jj_la1[59] = jj_gen;
+      ;
+    }
+    jj_consume_token(GT);
+ret.endAt(tokenEnd());
+return ret;
+  }
+
+  final public Type TypeArgument() {Type ret;
+        List<AnnotationExpr> annotations = null;
+    annotations = Annotations();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:
+    case IDENTIFIER:{
+      ret = ReferenceType();
+      break;
+      }
+    case HOOK:{
+      ret = Wildcard();
+      break;
+      }
+    default:
+      jj_la1[60] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+ret.setAnnotations(annotations); return ret;
+  }
+
+  final public WildcardType Wildcard() {ReferenceType ext = null;
+        ReferenceType sup = null;
+        Position begin;
+        List<AnnotationExpr> annotations = null;
+    jj_consume_token(HOOK);
+begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case EXTENDS:
+    case SUPER:{
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case EXTENDS:{
+        jj_consume_token(EXTENDS);
+        annotations = Annotations();
+        ext = ReferenceType();
+ext.setAnnotations(annotations);
+        break;
+        }
+      case SUPER:{
+        jj_consume_token(SUPER);
+        annotations = Annotations();
+        sup = ReferenceType();
+sup.setAnnotations(annotations);
+        break;
+        }
+      default:
+        jj_la1[61] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+      }
+    default:
+      jj_la1[62] = jj_gen;
+      ;
+    }
+return new WildcardType(range(begin, tokenEnd()),ext, sup);
+  }
+
+  final public PrimitiveType PrimitiveType() {PrimitiveType ret;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:{
+      jj_consume_token(BOOLEAN);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Boolean);
+      break;
+      }
+    case CHAR:{
+      jj_consume_token(CHAR);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Char);
+      break;
+      }
+    case BYTE:{
+      jj_consume_token(BYTE);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Byte);
+      break;
+      }
+    case SHORT:{
+      jj_consume_token(SHORT);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Short);
+      break;
+      }
+    case INT:{
+      jj_consume_token(INT);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Int);
+      break;
+      }
+    case LONG:{
+      jj_consume_token(LONG);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Long);
+      break;
+      }
+    case FLOAT:{
+      jj_consume_token(FLOAT);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Float);
+      break;
+      }
+    case DOUBLE:{
+      jj_consume_token(DOUBLE);
+ret = new PrimitiveType(tokenRange(), PrimitiveType.Primitive.Double);
+      break;
+      }
+    default:
+      jj_la1[63] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public Type ResultType() {Type ret;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case VOID:{
+      jj_consume_token(VOID);
+ret = new VoidType(tokenRange());
+      break;
+      }
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:
+    case IDENTIFIER:{
+      ret = Type();
+      break;
+      }
+    default:
+      jj_la1[64] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public NameExpr Name() {NameExpr ret;
+    jj_consume_token(IDENTIFIER);
+ret = new NameExpr(tokenRange(), token.image);
+    label_27:
+    while (true) {
+      if (jj_2_17(2)) {
+        ;
+      } else {
+        break label_27;
+      }
+      jj_consume_token(DOT);
+      jj_consume_token(IDENTIFIER);
+ret = new QualifiedNameExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, token.image);
+    }
+return ret;
+  }
+
+  final public NameExpr SimpleName() {NameExpr ret;
+    jj_consume_token(IDENTIFIER);
+ret = new NameExpr(tokenRange(), token.image);
+return ret;
+  }
+
+/*
+ * Expression syntax follows.
+ */
+  final public 
+Expression Expression() {Expression ret;
+        AssignExpr.Operator op;
+        Expression value;
+        Statement lambdaBody = null;
+        RangedList<Type<?>> typeArgs = new RangedList<Type<?>>(null);
+    ret = ConditionalExpression();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case ASSIGN:
+    case PLUSASSIGN:
+    case MINUSASSIGN:
+    case STARASSIGN:
+    case SLASHASSIGN:
+    case ANDASSIGN:
+    case ORASSIGN:
+    case XORASSIGN:
+    case REMASSIGN:
+    case LSHIFTASSIGN:
+    case RSIGNEDSHIFTASSIGN:
+    case RUNSIGNEDSHIFTASSIGN:
+    case ARROW:
+    case DOUBLECOLON:{
+      if (jj_2_18(2)) {
+        op = AssignmentOperator();
+        value = Expression();
+ret = new AssignExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, value, op);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case ARROW:{
+          jj_consume_token(ARROW);
+          lambdaBody = LambdaBody();
+if (ret instanceof CastExpr)
+     {
+       ret = generateLambda(ret, lambdaBody);
+     }
+     else if (ret instanceof ConditionalExpr){
+         ConditionalExpr ce = (ConditionalExpr) ret;
+         if(ce.getElseExpr() != null){
+            ce.setElseExpr(generateLambda(ce.getElseExpr(), lambdaBody));
+         }
+     }
+     else
+     {
+       ret = generateLambda(ret, lambdaBody);
+     }
+          break;
+          }
+        case DOUBLECOLON:{
+          jj_consume_token(DOUBLECOLON);
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case LT:{
+            typeArgs = TypeArguments();
+            break;
+            }
+          default:
+            jj_la1[65] = jj_gen;
+            ;
+          }
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case IDENTIFIER:{
+            jj_consume_token(IDENTIFIER);
+            break;
+            }
+          case NEW:{
+            jj_consume_token(NEW);
+            break;
+            }
+          default:
+            jj_la1[66] = jj_gen;
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+ret = new MethodReferenceExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, typeArgs.list, token.image);
+          break;
+          }
+        default:
+          jj_la1[67] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      break;
+      }
+    default:
+      jj_la1[68] = jj_gen;
+      ;
+    }
+return ret;
+  }
+
+  final public AssignExpr.Operator AssignmentOperator() {AssignExpr.Operator ret;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case ASSIGN:{
+      jj_consume_token(ASSIGN);
+ret = AssignExpr.Operator.assign;
+      break;
+      }
+    case STARASSIGN:{
+      jj_consume_token(STARASSIGN);
+ret = AssignExpr.Operator.star;
+      break;
+      }
+    case SLASHASSIGN:{
+      jj_consume_token(SLASHASSIGN);
+ret = AssignExpr.Operator.slash;
+      break;
+      }
+    case REMASSIGN:{
+      jj_consume_token(REMASSIGN);
+ret = AssignExpr.Operator.rem;
+      break;
+      }
+    case PLUSASSIGN:{
+      jj_consume_token(PLUSASSIGN);
+ret = AssignExpr.Operator.plus;
+      break;
+      }
+    case MINUSASSIGN:{
+      jj_consume_token(MINUSASSIGN);
+ret = AssignExpr.Operator.minus;
+      break;
+      }
+    case LSHIFTASSIGN:{
+      jj_consume_token(LSHIFTASSIGN);
+ret = AssignExpr.Operator.lShift;
+      break;
+      }
+    case RSIGNEDSHIFTASSIGN:{
+      jj_consume_token(RSIGNEDSHIFTASSIGN);
+ret = AssignExpr.Operator.rSignedShift;
+      break;
+      }
+    case RUNSIGNEDSHIFTASSIGN:{
+      jj_consume_token(RUNSIGNEDSHIFTASSIGN);
+ret = AssignExpr.Operator.rUnsignedShift;
+      break;
+      }
+    case ANDASSIGN:{
+      jj_consume_token(ANDASSIGN);
+ret = AssignExpr.Operator.and;
+      break;
+      }
+    case XORASSIGN:{
+      jj_consume_token(XORASSIGN);
+ret = AssignExpr.Operator.xor;
+      break;
+      }
+    case ORASSIGN:{
+      jj_consume_token(ORASSIGN);
+ret = AssignExpr.Operator.or;
+      break;
+      }
+    default:
+      jj_la1[69] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public Expression ConditionalExpression() {Expression ret;
+        Expression left;
+        Expression right;
+    ret = ConditionalOrExpression();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case HOOK:{
+      jj_consume_token(HOOK);
+      left = Expression();
+      jj_consume_token(COLON);
+      right = ConditionalExpression();
+ret = new ConditionalExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, left, right);
+      break;
+      }
+    default:
+      jj_la1[70] = jj_gen;
+      ;
+    }
+return ret;
+  }
+
+  final public Expression ConditionalOrExpression() {Expression ret;
+        Expression right;
+    ret = ConditionalAndExpression();
+    label_28:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case SC_OR:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[71] = jj_gen;
+        break label_28;
+      }
+      jj_consume_token(SC_OR);
+      right = ConditionalAndExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, BinaryExpr.Operator.or);
+    }
+return ret;
+  }
+
+  final public Expression ConditionalAndExpression() {Expression ret;
+        Expression right;
+    ret = InclusiveOrExpression();
+    label_29:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case SC_AND:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[72] = jj_gen;
+        break label_29;
+      }
+      jj_consume_token(SC_AND);
+      right = InclusiveOrExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, BinaryExpr.Operator.and);
+    }
+return ret;
+  }
+
+  final public Expression InclusiveOrExpression() {Expression ret;
+        Expression right;
+    ret = ExclusiveOrExpression();
+    label_30:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BIT_OR:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[73] = jj_gen;
+        break label_30;
+      }
+      jj_consume_token(BIT_OR);
+      right = ExclusiveOrExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, BinaryExpr.Operator.binOr);
+    }
+return ret;
+  }
+
+  final public Expression ExclusiveOrExpression() {Expression ret;
+        Expression right;
+    ret = AndExpression();
+    label_31:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case XOR:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[74] = jj_gen;
+        break label_31;
+      }
+      jj_consume_token(XOR);
+      right = AndExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, BinaryExpr.Operator.xor);
+    }
+return ret;
+  }
+
+  final public Expression AndExpression() {Expression ret;
+        Expression right;
+    ret = EqualityExpression();
+    label_32:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BIT_AND:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[75] = jj_gen;
+        break label_32;
+      }
+      jj_consume_token(BIT_AND);
+      right = EqualityExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, BinaryExpr.Operator.binAnd);
+    }
+return ret;
+  }
+
+  final public Expression EqualityExpression() {Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = InstanceOfExpression();
+    label_33:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case EQ:
+      case NE:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[76] = jj_gen;
+        break label_33;
+      }
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case EQ:{
+        jj_consume_token(EQ);
+op = BinaryExpr.Operator.equals;
+        break;
+        }
+      case NE:{
+        jj_consume_token(NE);
+op = BinaryExpr.Operator.notEquals;
+        break;
+        }
+      default:
+        jj_la1[77] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = InstanceOfExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, op);
+    }
+return ret;
+  }
+
+  final public Expression InstanceOfExpression() {Expression ret;
+        Type type;
+    ret = RelationalExpression();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case INSTANCEOF:{
+      jj_consume_token(INSTANCEOF);
+      type = Type();
+ret = new InstanceOfExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, type);
+      break;
+      }
+    default:
+      jj_la1[78] = jj_gen;
+      ;
+    }
+return ret;
+  }
+
+  final public Expression RelationalExpression() {Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = ShiftExpression();
+    label_34:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LT:
+      case LE:
+      case GE:
+      case GT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[79] = jj_gen;
+        break label_34;
+      }
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LT:{
+        jj_consume_token(LT);
+op = BinaryExpr.Operator.less;
+        break;
+        }
+      case GT:{
+        jj_consume_token(GT);
+op = BinaryExpr.Operator.greater;
+        break;
+        }
+      case LE:{
+        jj_consume_token(LE);
+op = BinaryExpr.Operator.lessEquals;
+        break;
+        }
+      case GE:{
+        jj_consume_token(GE);
+op = BinaryExpr.Operator.greaterEquals;
+        break;
+        }
+      default:
+        jj_la1[80] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = ShiftExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, op);
+    }
+return ret;
+  }
+
+  final public Expression ShiftExpression() {Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = AdditiveExpression();
+    label_35:
+    while (true) {
+      if (jj_2_19(1)) {
+        ;
+      } else {
+        break label_35;
+      }
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LSHIFT:{
+        jj_consume_token(LSHIFT);
+op = BinaryExpr.Operator.lShift;
+        break;
+        }
+      default:
+        jj_la1[81] = jj_gen;
+        if (jj_2_20(1)) {
+          RSIGNEDSHIFT();
+op = BinaryExpr.Operator.rSignedShift;
+        } else if (jj_2_21(1)) {
+          RUNSIGNEDSHIFT();
+op = BinaryExpr.Operator.rUnsignedShift;
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      right = AdditiveExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, op);
+    }
+return ret;
+  }
+
+  final public Expression AdditiveExpression() {Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = MultiplicativeExpression();
+    label_36:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case PLUS:
+      case MINUS:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[82] = jj_gen;
+        break label_36;
+      }
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case PLUS:{
+        jj_consume_token(PLUS);
+op = BinaryExpr.Operator.plus;
+        break;
+        }
+      case MINUS:{
+        jj_consume_token(MINUS);
+op = BinaryExpr.Operator.minus;
+        break;
+        }
+      default:
+        jj_la1[83] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = MultiplicativeExpression();
+ret = new BinaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, right, op);
+    }
+return ret;
+  }
+
+  final public Expression MultiplicativeExpression() {Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = UnaryExpression();
+    label_37:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case STAR:
+      case SLASH:
+      case REM:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[84] = jj_gen;
+        break label_37;
+      }
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case STAR:{
+        jj_consume_token(STAR);
+op = BinaryExpr.Operator.times;
+        break;
+        }
+      case SLASH:{
+        jj_consume_token(SLASH);
+op = BinaryExpr.Operator.divide;
+        break;
+        }
+      case REM:{
+        jj_consume_token(REM);
+op = BinaryExpr.Operator.remainder;
+        break;
+        }
+      default:
+        jj_la1[85] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = UnaryExpression();
+ret = new BinaryExpr(range(ret.getBegin(), tokenEnd()), ret, right, op);
+    }
+return ret;
+  }
+
+  final public Expression UnaryExpression() {Expression ret;
+        UnaryExpr.Operator op;
+        Position begin = INVALID;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case INCR:{
+      ret = PreIncrementExpression();
+      break;
+      }
+    case DECR:{
+      ret = PreDecrementExpression();
+      break;
+      }
+    case PLUS:
+    case MINUS:{
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case PLUS:{
+        jj_consume_token(PLUS);
+op = UnaryExpr.Operator.positive; begin=tokenBegin();
+        break;
+        }
+      case MINUS:{
+        jj_consume_token(MINUS);
+op = UnaryExpr.Operator.negative; begin=tokenBegin();
+        break;
+        }
+      default:
+        jj_la1[86] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      ret = UnaryExpression();
+if(op == UnaryExpr.Operator.negative) {
+                        if (ret instanceof IntegerLiteralExpr && ((IntegerLiteralExpr)ret).isMinValue()) {
+                                ret = new IntegerLiteralMinValueExpr(range(begin, tokenEnd()));
+                        } else if (ret instanceof LongLiteralExpr && ((LongLiteralExpr)ret).isMinValue()) {
+                                ret = new LongLiteralMinValueExpr(range(begin, tokenEnd()));
+                        } else {
+                                ret = new UnaryExpr(range(begin, tokenEnd()), ret, op);
+                        }
+                 } else {
+                        ret = new UnaryExpr(range(begin, tokenEnd()), ret, op);
+                 }
+      break;
+      }
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:{
+      ret = UnaryExpressionNotPlusMinus();
+      break;
+      }
+    default:
+      jj_la1[87] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public Expression PreIncrementExpression() {Expression ret;
+        Position begin = INVALID;
+    jj_consume_token(INCR);
+begin=tokenBegin();
+    ret = UnaryExpression();
+ret = new UnaryExpr(range(begin, tokenEnd()), ret, UnaryExpr.Operator.preIncrement);
+return ret;
+  }
+
+  final public Expression PreDecrementExpression() {Expression ret;
+        Position begin;
+    jj_consume_token(DECR);
+begin=tokenBegin();
+    ret = UnaryExpression();
+ret = new UnaryExpr(range(begin, tokenEnd()), ret, UnaryExpr.Operator.preDecrement);
+return ret;
+  }
+
+  final public Expression UnaryExpressionNotPlusMinus() {Expression ret;
+        UnaryExpr.Operator op;
+        Position begin = INVALID;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BANG:
+    case TILDE:{
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case TILDE:{
+        jj_consume_token(TILDE);
+op = UnaryExpr.Operator.inverse; begin=tokenBegin();
+        break;
+        }
+      case BANG:{
+        jj_consume_token(BANG);
+op = UnaryExpr.Operator.not;     begin=tokenBegin();
+        break;
+        }
+      default:
+        jj_la1[88] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      ret = UnaryExpression();
+ret = new UnaryExpr(range(begin, tokenEnd()), ret, op);
+      break;
+      }
+    default:
+      jj_la1[89] = jj_gen;
+      if (jj_2_22(2147483647)) {
+        ret = CastExpression();
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NEW:
+        case NULL:
+        case SHORT:
+        case SUPER:
+        case THIS:
+        case TRUE:
+        case VOID:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:{
+          ret = PostfixExpression();
+          break;
+          }
+        default:
+          jj_la1[90] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+    }
+return ret;
+  }
+
+  final public Expression PostfixExpression() {Expression ret;
+        UnaryExpr.Operator op;
+    ret = PrimaryExpression();
+    if (jj_2_23(2)) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case INCR:{
+        jj_consume_token(INCR);
+op = UnaryExpr.Operator.posIncrement;
+        break;
+        }
+      case DECR:{
+        jj_consume_token(DECR);
+op = UnaryExpr.Operator.posDecrement;
+        break;
+        }
+      default:
+        jj_la1[91] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+ret = new UnaryExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, op);
+    } else {
+      ;
+    }
+return ret;
+  }
+
+  final public Expression CastExpression() {Expression ret;
+        ReferenceType referenceType;
+        PrimitiveType primitiveType;
+        Position begin = INVALID;
+        List<AnnotationExpr> annotations = null;
+        List<ReferenceType> typesOfMultiCast = null;
+    jj_consume_token(LPAREN);
+begin=tokenBegin();
+    annotations = Annotations();
+    if (jj_2_24(2)) {
+      primitiveType = PrimitiveType();
+      jj_consume_token(RPAREN);
+      ret = UnaryExpression();
+primitiveType.setAnnotations(annotations); ret = new CastExpr(range(begin, tokenEnd()), primitiveType, ret);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case SHORT:
+      case IDENTIFIER:{
+        referenceType = ReferenceType();
+typesOfMultiCast = add(typesOfMultiCast, referenceType); referenceType.setAnnotations(annotations);
+        label_38:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case BIT_AND:{
+            ;
+            break;
+            }
+          default:
+            jj_la1[92] = jj_gen;
+            break label_38;
+          }
+          jj_consume_token(BIT_AND);
+          referenceType = ReferenceType();
+typesOfMultiCast = add(typesOfMultiCast, referenceType);
+        }
+        jj_consume_token(RPAREN);
+        ret = UnaryExpressionNotPlusMinus();
+if (typesOfMultiCast.size() > 1) {
+                ret = new CastExpr(range(begin, tokenEnd()), new IntersectionType(range(begin, tokenEnd()), typesOfMultiCast), ret);
+            }
+            ret = new CastExpr(range(begin, tokenEnd()), referenceType, ret);
+        break;
+        }
+      default:
+        jj_la1[93] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public Expression PrimaryExpression() {Expression ret;
+    ret = PrimaryPrefix();
+    label_39:
+    while (true) {
+      if (jj_2_25(2)) {
+        ;
+      } else {
+        break label_39;
+      }
+      ret = PrimarySuffix(ret);
+    }
+return ret;
+  }
+
+  final public Expression PrimaryExpressionWithoutSuperSuffix() {Expression ret;
+    ret = PrimaryPrefix();
+    label_40:
+    while (true) {
+      if (jj_2_26(2147483647)) {
+        ;
+      } else {
+        break label_40;
+      }
+      ret = PrimarySuffixWithoutSuper(ret);
+    }
+return ret;
+  }
+
+  final public Expression PrimaryPrefix() {Expression ret = null;
+        NameExpr name;
+        RangedList<Type<?>> typeArgs = new RangedList<Type<?>>(null);
+        List<Expression> args = null;
+        List<Parameter> params = null;
+        boolean hasArgs = false;
+        boolean isLambda = false;
+        Type type;
+        Position begin;
+        Parameter p = null;
+        VariableDeclaratorId id = null;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case FALSE:
+    case NULL:
+    case TRUE:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:{
+      ret = Literal();
+      break;
+      }
+    case THIS:{
+      jj_consume_token(THIS);
+ret = new ThisExpr(tokenRange(), null);
+      break;
+      }
+    case SUPER:{
+      jj_consume_token(SUPER);
+ret = new SuperExpr(tokenRange(), null);
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case DOT:{
+        jj_consume_token(DOT);
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case LT:{
+          typeArgs = TypeArguments();
+          break;
+          }
+        default:
+          jj_la1[94] = jj_gen;
+          ;
+        }
+        name = SimpleName();
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case LPAREN:{
+          args = Arguments();
+hasArgs=true;
+          break;
+          }
+        default:
+          jj_la1[95] = jj_gen;
+          ;
+        }
+if (hasArgs) {
+                                MethodCallExpr m = new MethodCallExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, typeArgs.list, null, args);
+                                m.setNameExpr(name);
+                                ret = m;
+                        } else {
+                                FieldAccessExpr f = new FieldAccessExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, null, null);
+                                f.setFieldExpr(name);
+                                ret = f;
+                        }
+        break;
+        }
+      case DOUBLECOLON:{
+        jj_consume_token(DOUBLECOLON);
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case LT:{
+          typeArgs = TypeArguments();
+          break;
+          }
+        default:
+          jj_la1[96] = jj_gen;
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case IDENTIFIER:{
+          jj_consume_token(IDENTIFIER);
+          break;
+          }
+        case NEW:{
+          jj_consume_token(NEW);
+          break;
+          }
+        default:
+          jj_la1[97] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+ret = new MethodReferenceExpr(range(ret.getBegin(), pos(token.endLine, token.endColumn)), ret, typeArgs.list, token.image);
+        break;
+        }
+      default:
+        jj_la1[98] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+      }
+    case LPAREN:{
+      jj_consume_token(LPAREN);
+begin=tokenBegin();
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NATIVE:
+      case NEW:
+      case NULL:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SUPER:
+      case SYNCHRONIZED:
+      case THIS:
+      case TRANSIENT:
+      case TRUE:
+      case VOID:
+      case VOLATILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case AT:
+      case BANG:
+      case TILDE:
+      case INCR:
+      case DECR:
+      case PLUS:
+      case MINUS:{
+        if (jj_2_27(2147483647)) {
+          p = FormalParameter();
+isLambda = true;
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case COMMA:{
+            params = FormalLambdaParameters();
+            break;
+            }
+          default:
+            jj_la1[99] = jj_gen;
+            ;
+          }
+        } else {
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case BOOLEAN:
+          case BYTE:
+          case CHAR:
+          case DOUBLE:
+          case FALSE:
+          case FLOAT:
+          case INT:
+          case LONG:
+          case NEW:
+          case NULL:
+          case SHORT:
+          case SUPER:
+          case THIS:
+          case TRUE:
+          case VOID:
+          case LONG_LITERAL:
+          case INTEGER_LITERAL:
+          case FLOATING_POINT_LITERAL:
+          case CHARACTER_LITERAL:
+          case STRING_LITERAL:
+          case IDENTIFIER:
+          case LPAREN:
+          case BANG:
+          case TILDE:
+          case INCR:
+          case DECR:
+          case PLUS:
+          case MINUS:{
+            ret = Expression();
+            switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+            case COMMA:{
+              params = InferredLambdaParameters();
+isLambda = true;
+              break;
+              }
+            default:
+              jj_la1[100] = jj_gen;
+              ;
+            }
+            break;
+            }
+          default:
+            jj_la1[101] = jj_gen;
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+        }
+        break;
+        }
+      default:
+        jj_la1[102] = jj_gen;
+        ;
+      }
+      jj_consume_token(RPAREN);
+if(!isLambda) { ret = new EnclosedExpr(range(begin, tokenEnd()), ret);}
+                           else{
+                                  if(ret != null){
+                                          if(ret instanceof NameExpr)
+                                          {
+                                            id = new VariableDeclaratorId(range(ret.getBegin(), ret.getEnd()), ((NameExpr)ret).getName(), null);
+                                            p = new Parameter(range(ret.getBegin(), ret.getEnd()), EnumSet.noneOf(Modifier.class), null, new UnknownType(), null, false, id);
+                                          }
+
+                                        }
+                                        params = add(0, params, p);
+                                        // TODO p may be null here
+                                        ret = new LambdaExpr(range(p.getBegin(), tokenEnd()), params, null, true);
+                                }
+      break;
+      }
+    case NEW:{
+      ret = AllocationExpression(null);
+      break;
+      }
+    default:
+      jj_la1[106] = jj_gen;
+      if (jj_2_28(2147483647)) {
+        type = ResultType();
+        jj_consume_token(DOT);
+        jj_consume_token(CLASS);
+ret = new ClassExpr(range(type.getBegin(), tokenEnd()), type);
+      } else if (jj_2_29(2147483647)) {
+        type = ResultType();
+        jj_consume_token(DOUBLECOLON);
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case LT:{
+          typeArgs = TypeArguments();
+          break;
+          }
+        default:
+          jj_la1[103] = jj_gen;
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case IDENTIFIER:{
+          jj_consume_token(IDENTIFIER);
+          break;
+          }
+        case NEW:{
+          jj_consume_token(NEW);
+          break;
+          }
+        default:
+          jj_la1[104] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+ret = new TypeExpr(type.getRange(), type);
+                  ret = new MethodReferenceExpr(ret.getRange(), ret, typeArgs.list, token.image);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case IDENTIFIER:{
+          name = SimpleName();
+begin=tokenBegin();
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case LPAREN:{
+            args = Arguments();
+hasArgs=true;
+            break;
+            }
+          default:
+            jj_la1[105] = jj_gen;
+            ;
+          }
+if (hasArgs) {
+                                MethodCallExpr m = new MethodCallExpr(range(begin, tokenEnd()), null, null, null, args);
+                                m.setNameExpr(name);
+                                ret = m;
+                        } else {
+                                ret = name;
+                        }
+          break;
+          }
+        default:
+          jj_la1[107] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+    }
+return ret;
+  }
+
+  final public Expression PrimarySuffix(Expression scope) {Expression ret;
+    if (jj_2_30(2)) {
+      ret = PrimarySuffixWithoutSuper(scope);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case DOT:{
+        jj_consume_token(DOT);
+        jj_consume_token(SUPER);
+ret = new SuperExpr(range(scope.getBegin(), tokenEnd()), scope);
+        break;
+        }
+      default:
+        jj_la1[108] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public Expression PrimarySuffixWithoutSuper(Expression scope) {Expression ret;
+        RangedList<Type<?>> typeArgs = new RangedList<Type<?>>(null);
+        List<Expression> args = null;
+        boolean hasArgs = false;
+        NameExpr name;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case DOT:{
+      jj_consume_token(DOT);
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case THIS:{
+        jj_consume_token(THIS);
+ret = new ThisExpr(range(scope.getBegin(), tokenEnd()), scope);
+        break;
+        }
+      case NEW:{
+        ret = AllocationExpression(scope);
+        break;
+        }
+      default:
+        jj_la1[111] = jj_gen;
+        if (jj_2_31(2147483647)) {
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case LT:{
+            typeArgs = TypeArguments();
+            break;
+            }
+          default:
+            jj_la1[109] = jj_gen;
+            ;
+          }
+          name = SimpleName();
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case LPAREN:{
+            args = Arguments();
+hasArgs=true;
+            break;
+            }
+          default:
+            jj_la1[110] = jj_gen;
+            ;
+          }
+if (hasArgs) {
+                                MethodCallExpr m = new MethodCallExpr(range(scope.getBegin(), tokenEnd()), scope, typeArgs.list, null, args);
+                                m.setNameExpr(name);
+                                ret = m;
+                        } else {
+                                FieldAccessExpr f =  new FieldAccessExpr(range(scope.getBegin(), tokenEnd()), scope, typeArgs.list, null);
+                                f.setFieldExpr(name);
+                                ret = f;
+                        }
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      break;
+      }
+    case LBRACKET:{
+      jj_consume_token(LBRACKET);
+      ret = Expression();
+      jj_consume_token(RBRACKET);
+ret = new ArrayAccessExpr(range(scope.getBegin(), tokenEnd()), scope, ret);
+      break;
+      }
+    default:
+      jj_la1[112] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public Expression Literal() {Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case INTEGER_LITERAL:{
+      jj_consume_token(INTEGER_LITERAL);
+ret = new IntegerLiteralExpr(tokenRange(), token.image);
+      break;
+      }
+    case LONG_LITERAL:{
+      jj_consume_token(LONG_LITERAL);
+ret = new LongLiteralExpr(tokenRange(), token.image);
+      break;
+      }
+    case FLOATING_POINT_LITERAL:{
+      jj_consume_token(FLOATING_POINT_LITERAL);
+ret = new DoubleLiteralExpr(tokenRange(), token.image);
+      break;
+      }
+    case CHARACTER_LITERAL:{
+      jj_consume_token(CHARACTER_LITERAL);
+ret = new CharLiteralExpr(tokenRange(), token.image.substring(1, token.image.length()-1));
+      break;
+      }
+    case STRING_LITERAL:{
+      jj_consume_token(STRING_LITERAL);
+ret = new StringLiteralExpr(tokenRange(), token.image.substring(1, token.image.length()-1));
+      break;
+      }
+    case FALSE:
+    case TRUE:{
+      ret = BooleanLiteral();
+      break;
+      }
+    case NULL:{
+      ret = NullLiteral();
+      break;
+      }
+    default:
+      jj_la1[113] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public Expression BooleanLiteral() {Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case TRUE:{
+      jj_consume_token(TRUE);
+ret = new BooleanLiteralExpr(tokenRange(), true);
+      break;
+      }
+    case FALSE:{
+      jj_consume_token(FALSE);
+ret = new BooleanLiteralExpr(tokenRange(), false);
+      break;
+      }
+    default:
+      jj_la1[114] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public Expression NullLiteral() {
+    jj_consume_token(NULL);
+return new NullLiteralExpr(tokenRange());
+  }
+
+  final public List<Expression> Arguments() {List<Expression> ret = null;
+    jj_consume_token(LPAREN);
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:{
+      ret = ArgumentList();
+      break;
+      }
+    default:
+      jj_la1[115] = jj_gen;
+      ;
+    }
+    jj_consume_token(RPAREN);
+return ret;
+  }
+
+  final public List<Expression> ArgumentList() {List<Expression> ret = new LinkedList<Expression>();
+        Expression expr;
+    expr = Expression();
+ret.add(expr);
+    label_41:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[116] = jj_gen;
+        break label_41;
+      }
+      jj_consume_token(COMMA);
+      expr = Expression();
+ret.add(expr);
+    }
+return ret;
+  }
+
+  final public Expression AllocationExpression(Expression scope) {Expression ret;
+        Type type;
+        RangedList<Type<?>> typeArgs = new RangedList<Type<?>>(null);
+        List<BodyDeclaration<?>> anonymousBody = null;
+        List<Expression> args;
+        Position begin;
+        List<AnnotationExpr> annotations = null;
+    jj_consume_token(NEW);
+if(scope==null) {begin=tokenBegin();} else {begin=scope.getBegin();}
+    annotations = Annotations();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:{
+      type = PrimitiveType();
+type.setAnnotations(annotations);
+      ret = ArrayCreation(begin, type);
+      break;
+      }
+    case IDENTIFIER:
+    case AT:
+    case LT:{
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LT:{
+        typeArgs = TypeArguments();
+        annotations = Annotations();
+        break;
+        }
+      default:
+        jj_la1[117] = jj_gen;
+        ;
+      }
+      type = AnnotatedClassOrInterfaceType();
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LBRACKET:
+      case AT:{
+        ret = ArrayCreation(begin, type);
+        break;
+        }
+      case LPAREN:{
+        args = Arguments();
+        if (jj_2_32(2)) {
+          anonymousBody = ClassOrInterfaceBody(false);
+        } else {
+          ;
+        }
+ret = new ObjectCreationExpr(range(begin, tokenEnd()), scope, (ClassOrInterfaceType) type, typeArgs.list, args, anonymousBody);
+        break;
+        }
+      default:
+        jj_la1[118] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+      }
+    default:
+      jj_la1[119] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+/*
+ * The third LOOKAHEAD specification below is to parse to PrimarySuffix
+ * if there is an expression between the "[...]".
+ */
+  final public ArrayCreationExpr ArrayCreation(Position begin, Type type) {Expression expr = null;
+        ArrayInitializerExpr arrayInitializerExpr = null;
+        List<Expression> inits = null;
+        List<List<AnnotationExpr>> accum = null;
+        List<AnnotationExpr> annotations = null;
+    label_42:
+    while (true) {
+      annotations = Annotations();
+      jj_consume_token(LBRACKET);
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case BANG:
+      case TILDE:
+      case INCR:
+      case DECR:
+      case PLUS:
+      case MINUS:{
+        expr = Expression();
+        break;
+        }
+      default:
+        jj_la1[120] = jj_gen;
+        ;
+      }
+accum = add(accum, annotations); inits = add(inits, expr); annotations=null; expr=null;
+      jj_consume_token(RBRACKET);
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case LBRACKET:
+      case AT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[121] = jj_gen;
+        break label_42;
+      }
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LBRACE:{
+      arrayInitializerExpr = ArrayInitializer();
+      break;
+      }
+    default:
+      jj_la1[122] = jj_gen;
+      ;
+    }
+return juggleArrayCreation(range(begin, tokenEnd()), type, inits, accum, arrayInitializerExpr);
+  }
+
+/*
+ * Statement syntax follows.
+ */
+  final public 
+Statement Statement() {Statement ret;
+    if (jj_2_33(2)) {
+      ret = LabeledStatement();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ASSERT:{
+        ret = AssertStatement();
+        break;
+        }
+      case LBRACE:{
+        ret = Block();
+        break;
+        }
+      case SEMICOLON:{
+        ret = EmptyStatement();
+        break;
+        }
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case INCR:
+      case DECR:{
+        ret = StatementExpression();
+        break;
+        }
+      case SWITCH:{
+        ret = SwitchStatement();
+        break;
+        }
+      case IF:{
+        ret = IfStatement();
+        break;
+        }
+      case WHILE:{
+        ret = WhileStatement();
+        break;
+        }
+      case DO:{
+        ret = DoStatement();
+        break;
+        }
+      case FOR:{
+        ret = ForStatement();
+        break;
+        }
+      case BREAK:{
+        ret = BreakStatement();
+        break;
+        }
+      case CONTINUE:{
+        ret = ContinueStatement();
+        break;
+        }
+      case RETURN:{
+        ret = ReturnStatement();
+        break;
+        }
+      case THROW:{
+        ret = ThrowStatement();
+        break;
+        }
+      case SYNCHRONIZED:{
+        ret = SynchronizedStatement();
+        break;
+        }
+      case TRY:{
+        ret = TryStatement();
+        break;
+        }
+      default:
+        jj_la1[123] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public AssertStmt AssertStatement() {Expression check;
+        Expression msg = null;
+        Position begin;
+    jj_consume_token(ASSERT);
+begin=tokenBegin();
+    check = Expression();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case COLON:{
+      jj_consume_token(COLON);
+      msg = Expression();
+      break;
+      }
+    default:
+      jj_la1[124] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+return new AssertStmt(range(begin, tokenEnd()),check, msg);
+  }
+
+  final public LabeledStmt LabeledStatement() {String label;
+        Statement stmt;
+        Position begin;
+    jj_consume_token(IDENTIFIER);
+begin=tokenBegin();
+label = token.image;
+    jj_consume_token(COLON);
+    stmt = Statement();
+return new LabeledStmt(range(begin, tokenEnd()),label, stmt);
+  }
+
+  final public BlockStmt Block() {List<Statement> stmts;
+        Position begin;
+    jj_consume_token(LBRACE);
+begin=tokenBegin();
+    stmts = Statements();
+    jj_consume_token(RBRACE);
+return new BlockStmt(range(begin, tokenEnd()), stmts);
+  }
+
+/*
+ * Classes inside block stametents can only be abstract or final. The semantic must check it.
+ */
+  final public Statement BlockStatement() {Statement ret;
+        Expression expr;
+        ClassOrInterfaceDeclaration typeDecl;
+        ModifierHolder modifier;
+    if (jj_2_34(2147483647)) {
+
+      modifier = Modifiers();
+      typeDecl = ClassOrInterfaceDeclaration(modifier);
+ret = new TypeDeclarationStmt(range(typeDecl.getBegin().line, typeDecl.getBegin().column, token.endLine, token.endColumn), typeDecl);
+    } else if (jj_2_35(2147483647)) {
+      expr = VariableDeclarationExpression();
+      jj_consume_token(SEMICOLON);
+ret = new ExpressionStmt(range(expr.getBegin().line, expr.getBegin().column, token.endLine, token.endColumn), expr);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ASSERT:
+      case BOOLEAN:
+      case BREAK:
+      case BYTE:
+      case CHAR:
+      case CONTINUE:
+      case DO:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case FOR:
+      case IF:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case RETURN:
+      case SHORT:
+      case SUPER:
+      case SWITCH:
+      case SYNCHRONIZED:
+      case THIS:
+      case THROW:
+      case TRUE:
+      case TRY:
+      case VOID:
+      case WHILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case LBRACE:
+      case SEMICOLON:
+      case INCR:
+      case DECR:{
+        ret = Statement();
+        break;
+        }
+      default:
+        jj_la1[125] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public VariableDeclarationExpr VariableDeclarationExpression() {ModifierHolder modifier;
+        Type type;
+        List<VariableDeclarator> variables = new LinkedList<VariableDeclarator>();
+        VariableDeclarator var;
+    modifier = Modifiers();
+    type = Type();
+    var = VariableDeclarator();
+variables.add(var);
+    label_43:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[126] = jj_gen;
+        break label_43;
+      }
+      jj_consume_token(COMMA);
+      var = VariableDeclarator();
+variables.add(var);
+    }
+Position begin=modifier.begin.orIfInvalid(type.getBegin());
+        Pair<Type, List<ArrayBracketPair>> typeListPair = unwrapArrayTypes(type);
+        return new VariableDeclarationExpr(range(begin, tokenEnd()), modifier.modifiers, modifier.annotations, typeListPair.a, variables, typeListPair.b);
+  }
+
+  final public EmptyStmt EmptyStatement() {
+    jj_consume_token(SEMICOLON);
+return new EmptyStmt(tokenRange());
+  }
+
+  final public Statement LambdaBody() {Expression expr;
+  Statement n = null;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:{
+      expr = Expression();
+n = new ExpressionStmt(range(expr.getBegin(), tokenEnd()), expr);
+      break;
+      }
+    case LBRACE:{
+      n = Block();
+      break;
+      }
+    default:
+      jj_la1[127] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return n;
+  }
+
+  final public ExpressionStmt StatementExpression() {Expression expr;
+        AssignExpr.Operator op;
+        Expression value;
+        RangedList<Type<?>> typeArgs = new RangedList<Type<?>>(null);
+        Statement lambdaBody;
+    if (jj_2_36(2)) {
+      expr = PreIncrementExpression();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case DECR:{
+        expr = PreDecrementExpression();
+        break;
+        }
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:{
+        expr = PrimaryExpression();
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case ASSIGN:
+        case INCR:
+        case DECR:
+        case PLUSASSIGN:
+        case MINUSASSIGN:
+        case STARASSIGN:
+        case SLASHASSIGN:
+        case ANDASSIGN:
+        case ORASSIGN:
+        case XORASSIGN:
+        case REMASSIGN:
+        case LSHIFTASSIGN:
+        case RSIGNEDSHIFTASSIGN:
+        case RUNSIGNEDSHIFTASSIGN:
+        case ARROW:
+        case DOUBLECOLON:{
+          switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+          case INCR:{
+            jj_consume_token(INCR);
+expr = new UnaryExpr(range(expr.getBegin(), tokenEnd()), expr, UnaryExpr.Operator.posIncrement);
+            break;
+            }
+          case DECR:{
+            jj_consume_token(DECR);
+expr = new UnaryExpr(range(expr.getBegin(), tokenEnd()), expr, UnaryExpr.Operator.posDecrement);
+            break;
+            }
+          case ASSIGN:
+          case PLUSASSIGN:
+          case MINUSASSIGN:
+          case STARASSIGN:
+          case SLASHASSIGN:
+          case ANDASSIGN:
+          case ORASSIGN:
+          case XORASSIGN:
+          case REMASSIGN:
+          case LSHIFTASSIGN:
+          case RSIGNEDSHIFTASSIGN:
+          case RUNSIGNEDSHIFTASSIGN:{
+            op = AssignmentOperator();
+            value = Expression();
+expr = new AssignExpr(range(expr.getBegin(), tokenEnd()), expr, value, op);
+            break;
+            }
+          case DOUBLECOLON:{
+            jj_consume_token(DOUBLECOLON);
+            switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+            case LT:{
+              typeArgs = TypeArguments();
+              break;
+              }
+            default:
+              jj_la1[128] = jj_gen;
+              ;
+            }
+            switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+            case IDENTIFIER:{
+              jj_consume_token(IDENTIFIER);
+              break;
+              }
+            case NEW:{
+              jj_consume_token(NEW);
+              break;
+              }
+            default:
+              jj_la1[129] = jj_gen;
+              jj_consume_token(-1);
+              throw new ParseException();
+            }
+expr = new MethodReferenceExpr(range(expr.getBegin(), tokenEnd()), expr, typeArgs.list, token.image);
+            break;
+            }
+          case ARROW:{
+            jj_consume_token(ARROW);
+            lambdaBody = LambdaBody();
+expr = generateLambda(expr, lambdaBody);
+            break;
+            }
+          default:
+            jj_la1[130] = jj_gen;
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+          break;
+          }
+        default:
+          jj_la1[131] = jj_gen;
+          ;
+        }
+        break;
+        }
+      default:
+        jj_la1[132] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    jj_consume_token(SEMICOLON);
+return new ExpressionStmt(range(expr.getBegin(), tokenEnd()), expr);
+  }
+
+  final public SwitchStmt SwitchStatement() {Expression selector;
+        SwitchEntryStmt entry;
+        List<SwitchEntryStmt> entries = null;
+        Position begin;
+    jj_consume_token(SWITCH);
+begin=tokenBegin();
+    jj_consume_token(LPAREN);
+    selector = Expression();
+    jj_consume_token(RPAREN);
+    jj_consume_token(LBRACE);
+    label_44:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case CASE:
+      case _DEFAULT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[133] = jj_gen;
+        break label_44;
+      }
+      entry = SwitchEntry();
+entries = add(entries, entry);
+    }
+    jj_consume_token(RBRACE);
+return new SwitchStmt(range(begin, tokenEnd()), selector, entries);
+  }
+
+  final public SwitchEntryStmt SwitchEntry() {Expression label = null;
+        List<Statement> stmts;
+        Position begin;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case CASE:{
+      jj_consume_token(CASE);
+begin=tokenBegin();
+      label = Expression();
+      break;
+      }
+    case _DEFAULT:{
+      jj_consume_token(_DEFAULT);
+begin=tokenBegin();
+      break;
+      }
+    default:
+      jj_la1[134] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(COLON);
+    stmts = Statements();
+return new SwitchEntryStmt(range(begin, tokenEnd()),label, stmts);
+  }
+
+  final public IfStmt IfStatement() {Expression condition;
+        Statement thenStmt;
+        Statement elseStmt = null;
+        Position begin;
+    Comment thenCmmt = null;
+    Comment elseCmmt = null;
+    jj_consume_token(IF);
+begin=tokenBegin();
+    jj_consume_token(LPAREN);
+    condition = Expression();
+    jj_consume_token(RPAREN);
+
+    thenStmt = Statement();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case ELSE:{
+      jj_consume_token(ELSE);
+
+      elseStmt = Statement();
+      break;
+      }
+    default:
+      jj_la1[135] = jj_gen;
+      ;
+    }
+IfStmt tmp = new IfStmt(range(begin, tokenEnd()),condition, thenStmt, elseStmt);
+
+      // TODO comment is always null
+      thenStmt.setComment(thenCmmt);
+      if (elseStmt != null)
+          // TODO comment is always null
+          elseStmt.setComment(elseCmmt);
+      return tmp;
+  }
+
+  final public WhileStmt WhileStatement() {Expression condition;
+        Statement body;
+        Position begin;
+    jj_consume_token(WHILE);
+begin=tokenBegin();
+    jj_consume_token(LPAREN);
+    condition = Expression();
+    jj_consume_token(RPAREN);
+    body = Statement();
+return new WhileStmt(range(begin, tokenEnd()),condition, body);
+  }
+
+  final public DoStmt DoStatement() {Expression condition;
+        Statement body;
+        Position begin;
+    jj_consume_token(DO);
+begin=tokenBegin();
+    body = Statement();
+    jj_consume_token(WHILE);
+    jj_consume_token(LPAREN);
+    condition = Expression();
+    jj_consume_token(RPAREN);
+    jj_consume_token(SEMICOLON);
+return new DoStmt(range(begin, tokenEnd()),body, condition);
+  }
+
+  final public Statement ForStatement() {VariableDeclarationExpr varExpr = null;
+        Expression expr = null;
+        List<Expression> init = null;
+        List<Expression> update = null;
+        Statement body;
+        Position begin;
+    jj_consume_token(FOR);
+begin=tokenBegin();
+    jj_consume_token(LPAREN);
+    if (jj_2_37(2147483647)) {
+      varExpr = VariableDeclarationExpression();
+      jj_consume_token(COLON);
+      expr = Expression();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NATIVE:
+      case NEW:
+      case NULL:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SUPER:
+      case SYNCHRONIZED:
+      case THIS:
+      case TRANSIENT:
+      case TRUE:
+      case VOID:
+      case VOLATILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case SEMICOLON:
+      case AT:
+      case BANG:
+      case TILDE:
+      case INCR:
+      case DECR:
+      case PLUS:
+      case MINUS:{
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case ABSTRACT:
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FINAL:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NATIVE:
+        case NEW:
+        case NULL:
+        case PRIVATE:
+        case PROTECTED:
+        case PUBLIC:
+        case SHORT:
+        case STATIC:
+        case STRICTFP:
+        case SUPER:
+        case SYNCHRONIZED:
+        case THIS:
+        case TRANSIENT:
+        case TRUE:
+        case VOID:
+        case VOLATILE:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:
+        case AT:
+        case BANG:
+        case TILDE:
+        case INCR:
+        case DECR:
+        case PLUS:
+        case MINUS:{
+          init = ForInit();
+          break;
+          }
+        default:
+          jj_la1[136] = jj_gen;
+          ;
+        }
+        jj_consume_token(SEMICOLON);
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NEW:
+        case NULL:
+        case SHORT:
+        case SUPER:
+        case THIS:
+        case TRUE:
+        case VOID:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:
+        case BANG:
+        case TILDE:
+        case INCR:
+        case DECR:
+        case PLUS:
+        case MINUS:{
+          expr = Expression();
+          break;
+          }
+        default:
+          jj_la1[137] = jj_gen;
+          ;
+        }
+        jj_consume_token(SEMICOLON);
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NEW:
+        case NULL:
+        case SHORT:
+        case SUPER:
+        case THIS:
+        case TRUE:
+        case VOID:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:
+        case BANG:
+        case TILDE:
+        case INCR:
+        case DECR:
+        case PLUS:
+        case MINUS:{
+          update = ForUpdate();
+          break;
+          }
+        default:
+          jj_la1[138] = jj_gen;
+          ;
+        }
+        break;
+        }
+      default:
+        jj_la1[139] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    jj_consume_token(RPAREN);
+    body = Statement();
+if (varExpr != null) {
+                return new ForeachStmt(range(begin, tokenEnd()),varExpr, expr, body);
+        }
+        return new ForStmt(range(begin, tokenEnd()),init, expr, update, body);
+  }
+
+  final public List<Expression> ForInit() {List<Expression> ret;
+        Expression expr;
+    if (jj_2_38(2147483647)) {
+      expr = VariableDeclarationExpression();
+ret = new LinkedList<Expression>(); ret.add(expr);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case BANG:
+      case TILDE:
+      case INCR:
+      case DECR:
+      case PLUS:
+      case MINUS:{
+        ret = ExpressionList();
+        break;
+        }
+      default:
+        jj_la1[140] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public List<Expression> ExpressionList() {List<Expression> ret = new LinkedList<Expression>();
+        Expression expr;
+    expr = Expression();
+ret.add(expr);
+    label_45:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[141] = jj_gen;
+        break label_45;
+      }
+      jj_consume_token(COMMA);
+      expr = Expression();
+ret.add(expr);
+    }
+return ret;
+  }
+
+  final public List<Expression> ForUpdate() {List<Expression> ret;
+    ret = ExpressionList();
+return ret;
+  }
+
+  final public BreakStmt BreakStatement() {String id = null;
+        Position begin;
+    jj_consume_token(BREAK);
+begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case IDENTIFIER:{
+      jj_consume_token(IDENTIFIER);
+id = token.image;
+      break;
+      }
+    default:
+      jj_la1[142] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+return new BreakStmt(range(begin, tokenEnd()),id);
+  }
+
+  final public ContinueStmt ContinueStatement() {String id = null;
+        Position begin;
+    jj_consume_token(CONTINUE);
+begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case IDENTIFIER:{
+      jj_consume_token(IDENTIFIER);
+id = token.image;
+      break;
+      }
+    default:
+      jj_la1[143] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+return new ContinueStmt(range(begin, tokenEnd()),id);
+  }
+
+  final public ReturnStmt ReturnStatement() {Expression expr = null;
+        Position begin;
+    jj_consume_token(RETURN);
+begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:{
+      expr = Expression();
+      break;
+      }
+    default:
+      jj_la1[144] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+return new ReturnStmt(range(begin, tokenEnd()),expr);
+  }
+
+  final public ThrowStmt ThrowStatement() {Expression expr;
+        Position begin;
+    jj_consume_token(THROW);
+begin=tokenBegin();
+    expr = Expression();
+    jj_consume_token(SEMICOLON);
+return new ThrowStmt(range(begin, tokenEnd()),expr);
+  }
+
+  final public SynchronizedStmt SynchronizedStatement() {Expression expr;
+        BlockStmt block;
+        Position begin;
+    jj_consume_token(SYNCHRONIZED);
+begin=tokenBegin();
+    jj_consume_token(LPAREN);
+    expr = Expression();
+    jj_consume_token(RPAREN);
+    block = Block();
+return new SynchronizedStmt(range(begin, tokenEnd()),expr, block);
+  }
+
+  final public TryStmt TryStatement() {List<VariableDeclarationExpr> resources = null;
+        BlockStmt tryBlock;
+        BlockStmt finallyBlock = null;
+        List<CatchClause> catchs = null;
+        BlockStmt catchBlock;
+        ModifierHolder exceptModifier;
+        ReferenceType exceptionType;
+        List<ReferenceType> exceptionTypes = new LinkedList<ReferenceType>();
+        VariableDeclaratorId exceptId;
+        Position begin;
+        Position catchBegin;
+        Type type;
+    jj_consume_token(TRY);
+begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case LPAREN:{
+      resources = ResourceSpecification();
+      break;
+      }
+    default:
+      jj_la1[145] = jj_gen;
+      ;
+    }
+    tryBlock = Block();
+    label_46:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case CATCH:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[146] = jj_gen;
+        break label_46;
+      }
+      jj_consume_token(CATCH);
+catchBegin=tokenBegin();
+      jj_consume_token(LPAREN);
+      exceptModifier = Modifiers();
+      exceptionType = ReferenceType();
+exceptionTypes.add(exceptionType);
+      label_47:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case BIT_OR:{
+          ;
+          break;
+          }
+        default:
+          jj_la1[147] = jj_gen;
+          break label_47;
+        }
+        jj_consume_token(BIT_OR);
+        exceptionType = ReferenceTypeWithAnnotations();
+exceptionTypes.add(exceptionType);
+      }
+      exceptId = VariableDeclaratorId();
+      jj_consume_token(RPAREN);
+      catchBlock = Block();
+if (exceptionTypes.size() > 1) {
+                                type = new UnionType(exceptionTypes);
+                           } else {
+                                type = (Type)exceptionTypes.get(0);
+                           }
+                           catchs = add(catchs, new CatchClause(range(catchBegin, tokenEnd()), exceptModifier.modifiers, exceptModifier.annotations, type, exceptId, catchBlock));
+                           exceptionTypes = new LinkedList<ReferenceType>();
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case FINALLY:{
+      jj_consume_token(FINALLY);
+      finallyBlock = Block();
+      break;
+      }
+    default:
+      jj_la1[148] = jj_gen;
+      ;
+    }
+if (finallyBlock==null && catchs==null && resources==null) {
+      addProblem("Try has no finally, no catch, and no resources");
+    }
+    return new TryStmt(range(begin, tokenEnd()), resources, tryBlock, catchs, finallyBlock);
+  }
+
+  final public List<VariableDeclarationExpr> ResourceSpecification() {List<VariableDeclarationExpr> variables;
+    jj_consume_token(LPAREN);
+    variables = Resources();
+    if (jj_2_39(2)) {
+      jj_consume_token(SEMICOLON);
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+return variables;
+  }
+
+  final public List<VariableDeclarationExpr> Resources() {List<VariableDeclarationExpr> variables = new LinkedList<VariableDeclarationExpr>();
+        VariableDeclarationExpr var;
+    /*this is a bit more lenient than we need to be, eg allowing access modifiers like private*/
+      var = VariableDeclarationExpression();
+variables.add(var);
+    label_48:
+    while (true) {
+      if (jj_2_40(2)) {
+        ;
+      } else {
+        break label_48;
+      }
+      jj_consume_token(SEMICOLON);
+      var = VariableDeclarationExpression();
+variables.add(var);
+    }
+return variables;
+  }
+
+/* We use productions to match >>>, >> and > so that we can keep the
+ * type declaration syntax with generics clean
+ */
+  final public 
+void RUNSIGNEDSHIFT() {
+    if (getToken(1).kind == GT &&
+                    ((GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT) {
+
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(GT);
+    jj_consume_token(GT);
+    jj_consume_token(GT);
+  }
+
+  final public void RSIGNEDSHIFT() {
+    if (getToken(1).kind == GT &&
+                    ((GTToken)getToken(1)).realKind == RSIGNEDSHIFT) {
+
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(GT);
+    jj_consume_token(GT);
+  }
+
+/* Annotation syntax follows. */
+  final public 
+List<AnnotationExpr> Annotations() {List<AnnotationExpr> annotations = null;
+        AnnotationExpr annotation;
+    label_49:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case AT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[149] = jj_gen;
+        break label_49;
+      }
+      annotation = Annotation();
+annotations = add(annotations, annotation);
+    }
+return annotations;
+  }
+
+  final public AnnotationExpr Annotation() {AnnotationExpr ret;
+    if (jj_2_41(2147483647)) {
+      ret = NormalAnnotation();
+    } else if (jj_2_42(2147483647)) {
+      ret = SingleMemberAnnotation();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case AT:{
+        ret = MarkerAnnotation();
+        break;
+        }
+      default:
+        jj_la1[150] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+return ret;
+  }
+
+  final public NormalAnnotationExpr NormalAnnotation() {NameExpr name;
+        List<MemberValuePair> pairs = null;
+        Position begin;
+    jj_consume_token(AT);
+begin=tokenBegin();
+    name = Name();
+    jj_consume_token(LPAREN);
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case IDENTIFIER:{
+      pairs = MemberValuePairs();
+      break;
+      }
+    default:
+      jj_la1[151] = jj_gen;
+      ;
+    }
+    jj_consume_token(RPAREN);
+return new NormalAnnotationExpr(range(begin, tokenEnd()),name, pairs);
+  }
+
+  final public MarkerAnnotationExpr MarkerAnnotation() {NameExpr name;
+        Position begin;
+    jj_consume_token(AT);
+begin=tokenBegin();
+    name = Name();
+return new MarkerAnnotationExpr(range(begin, tokenEnd()),name);
+  }
+
+  final public SingleMemberAnnotationExpr SingleMemberAnnotation() {NameExpr name;
+        Expression memberVal;
+        Position begin;
+    jj_consume_token(AT);
+begin=tokenBegin();
+    name = Name();
+    jj_consume_token(LPAREN);
+    memberVal = MemberValue();
+    jj_consume_token(RPAREN);
+return new SingleMemberAnnotationExpr(range(begin, tokenEnd()),name, memberVal);
+  }
+
+  final public List<MemberValuePair> MemberValuePairs() {List<MemberValuePair> ret = new LinkedList<MemberValuePair>();
+        MemberValuePair pair;
+    pair = MemberValuePair();
+ret.add(pair);
+    label_50:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case COMMA:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[152] = jj_gen;
+        break label_50;
+      }
+      jj_consume_token(COMMA);
+      pair = MemberValuePair();
+ret.add(pair);
+    }
+return ret;
+  }
+
+  final public MemberValuePair MemberValuePair() {String name;
+        Expression value;
+        Position begin;
+    jj_consume_token(IDENTIFIER);
+name = token.image; begin=tokenBegin();
+    jj_consume_token(ASSIGN);
+    value = MemberValue();
+return new MemberValuePair(range(begin, tokenEnd()),name, value);
+  }
+
+  final public Expression MemberValue() {Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case AT:{
+      ret = Annotation();
+      break;
+      }
+    case LBRACE:{
+      ret = MemberValueArrayInitializer();
+      break;
+      }
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:{
+      ret = ConditionalExpression();
+      break;
+      }
+    default:
+      jj_la1[153] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public Expression MemberValueArrayInitializer() {List<Expression> ret = new LinkedList<Expression>();
+        Expression member;
+        Position begin;
+    jj_consume_token(LBRACE);
+begin=tokenBegin();
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case LBRACE:
+    case AT:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:{
+      member = MemberValue();
+ret.add(member);
+      label_51:
+      while (true) {
+        if (jj_2_43(2)) {
+          ;
+        } else {
+          break label_51;
+        }
+        jj_consume_token(COMMA);
+        member = MemberValue();
+ret.add(member);
+      }
+      break;
+      }
+    default:
+      jj_la1[154] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case COMMA:{
+      jj_consume_token(COMMA);
+      break;
+      }
+    default:
+      jj_la1[155] = jj_gen;
+      ;
+    }
+    jj_consume_token(RBRACE);
+return new ArrayInitializerExpr(range(begin, tokenEnd()),ret);
+  }
+
+/* Annotation Types. */
+  final public 
+AnnotationDeclaration AnnotationTypeDeclaration(ModifierHolder modifier) {NameExpr name;
+        List<BodyDeclaration<?>> members;
+        Position begin = modifier.begin;
+    jj_consume_token(AT);
+begin=begin.orIfInvalid(tokenBegin());
+    jj_consume_token(INTERFACE);
+    name = Name();
+    members = AnnotationTypeBody();
+AnnotationDeclaration tmp = new AnnotationDeclaration(range(begin, tokenEnd()), modifier.modifiers, modifier.annotations, null, members);
+      tmp.setNameExpr(name);
+      return tmp;
+  }
+
+  final public List<BodyDeclaration<?>> AnnotationTypeBody() {List<BodyDeclaration<?>> ret = null;
+        BodyDeclaration member;
+    jj_consume_token(LBRACE);
+    label_52:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case DOUBLE:
+      case ENUM:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOLATILE:
+      case IDENTIFIER:
+      case SEMICOLON:
+      case AT:{
+        ;
+        break;
+        }
+      default:
+        jj_la1[156] = jj_gen;
+        break label_52;
+      }
+      member = AnnotationBodyDeclaration();
+ret = add(ret, member);
+    }
+    jj_consume_token(RBRACE);
+return ret;
+  }
+
+  final public BodyDeclaration<?> AnnotationBodyDeclaration() {ModifierHolder modifier;
+   BodyDeclaration ret;
+
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case SEMICOLON:{
+      jj_consume_token(SEMICOLON);
+ret = new EmptyTypeDeclaration(tokenRange());
+      break;
+      }
+    case ABSTRACT:
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case CLASS:
+    case DOUBLE:
+    case ENUM:
+    case FINAL:
+    case FLOAT:
+    case INT:
+    case INTERFACE:
+    case LONG:
+    case NATIVE:
+    case PRIVATE:
+    case PROTECTED:
+    case PUBLIC:
+    case SHORT:
+    case STATIC:
+    case STRICTFP:
+    case SYNCHRONIZED:
+    case TRANSIENT:
+    case VOLATILE:
+    case IDENTIFIER:
+    case AT:{
+      modifier = Modifiers();
+      if (jj_2_44(2147483647)) {
+        ret = AnnotationTypeMemberDeclaration(modifier);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+        case CLASS:
+        case INTERFACE:{
+          ret = ClassOrInterfaceDeclaration(modifier);
+          break;
+          }
+        case ENUM:{
+          ret = EnumDeclaration(modifier);
+          break;
+          }
+        case AT:{
+          ret = AnnotationTypeDeclaration(modifier);
+          break;
+          }
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case SHORT:
+        case IDENTIFIER:{
+          ret = FieldDeclaration(modifier);
+          break;
+          }
+        default:
+          jj_la1[157] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      break;
+      }
+    default:
+      jj_la1[158] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+return ret;
+  }
+
+  final public AnnotationMemberDeclaration AnnotationTypeMemberDeclaration(ModifierHolder modifier) {Type type;
+        String name;
+        Expression defaultVal = null;
+    type = Type();
+    jj_consume_token(IDENTIFIER);
+name = token.image;
+    jj_consume_token(LPAREN);
+    jj_consume_token(RPAREN);
+    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {
+    case _DEFAULT:{
+      defaultVal = DefaultValue();
+      break;
+      }
+    default:
+      jj_la1[159] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+Position begin = modifier.begin.orIfInvalid(tokenBegin());
+    return new AnnotationMemberDeclaration(range(begin, tokenEnd()), modifier.modifiers, modifier.annotations, type, name, defaultVal);
+  }
+
+  final public Expression DefaultValue() {Expression ret;
+    jj_consume_token(_DEFAULT);
+    ret = MemberValue();
+return ret;
+  }
+
+  private boolean jj_2_1(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_1(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(0, xla); }
+  }
+
+  private boolean jj_2_2(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_2(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(1, xla); }
+  }
+
+  private boolean jj_2_3(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_3(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(2, xla); }
+  }
+
+  private boolean jj_2_4(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_4(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(3, xla); }
+  }
+
+  private boolean jj_2_5(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_5(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(4, xla); }
+  }
+
+  private boolean jj_2_6(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_6(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(5, xla); }
+  }
+
+  private boolean jj_2_7(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_7(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(6, xla); }
+  }
+
+  private boolean jj_2_8(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_8(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(7, xla); }
+  }
+
+  private boolean jj_2_9(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_9(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(8, xla); }
+  }
+
+  private boolean jj_2_10(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_10(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(9, xla); }
+  }
+
+  private boolean jj_2_11(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_11(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(10, xla); }
+  }
+
+  private boolean jj_2_12(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_12(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(11, xla); }
+  }
+
+  private boolean jj_2_13(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_13(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(12, xla); }
+  }
+
+  private boolean jj_2_14(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_14(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(13, xla); }
+  }
+
+  private boolean jj_2_15(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_15(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(14, xla); }
+  }
+
+  private boolean jj_2_16(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_16(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(15, xla); }
+  }
+
+  private boolean jj_2_17(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_17(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(16, xla); }
+  }
+
+  private boolean jj_2_18(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_18(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(17, xla); }
+  }
+
+  private boolean jj_2_19(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_19(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(18, xla); }
+  }
+
+  private boolean jj_2_20(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_20(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(19, xla); }
+  }
+
+  private boolean jj_2_21(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_21(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(20, xla); }
+  }
+
+  private boolean jj_2_22(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_22(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(21, xla); }
+  }
+
+  private boolean jj_2_23(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_23(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(22, xla); }
+  }
+
+  private boolean jj_2_24(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_24(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(23, xla); }
+  }
+
+  private boolean jj_2_25(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_25(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(24, xla); }
+  }
+
+  private boolean jj_2_26(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_26(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(25, xla); }
+  }
+
+  private boolean jj_2_27(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_27(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(26, xla); }
+  }
+
+  private boolean jj_2_28(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_28(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(27, xla); }
+  }
+
+  private boolean jj_2_29(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_29(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(28, xla); }
+  }
+
+  private boolean jj_2_30(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_30(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(29, xla); }
+  }
+
+  private boolean jj_2_31(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_31(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(30, xla); }
+  }
+
+  private boolean jj_2_32(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_32(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(31, xla); }
+  }
+
+  private boolean jj_2_33(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_33(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(32, xla); }
+  }
+
+  private boolean jj_2_34(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_34(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(33, xla); }
+  }
+
+  private boolean jj_2_35(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_35(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(34, xla); }
+  }
+
+  private boolean jj_2_36(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_36(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(35, xla); }
+  }
+
+  private boolean jj_2_37(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_37(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(36, xla); }
+  }
+
+  private boolean jj_2_38(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_38(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(37, xla); }
+  }
+
+  private boolean jj_2_39(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_39(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(38, xla); }
+  }
+
+  private boolean jj_2_40(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_40(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(39, xla); }
+  }
+
+  private boolean jj_2_41(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_41(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(40, xla); }
+  }
+
+  private boolean jj_2_42(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_42(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(41, xla); }
+  }
+
+  private boolean jj_2_43(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_43(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(42, xla); }
+  }
+
+  private boolean jj_2_44(int xla)
+ {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_44(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(43, xla); }
+  }
+
+  private boolean jj_3_38()
+ {
+    if (jj_3R_95()) return true;
+    if (jj_3R_68()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_341()
+ {
+    if (jj_3R_345()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_373()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_385()
+ {
+    if (jj_scan_token(ELSE)) return true;
+    if (jj_3R_277()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_377()
+ {
+    if (jj_3R_93()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_427()
+ {
+    if (jj_3R_80()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_429()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_159()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_78()) return true;
+    if (jj_3R_158()) return true;
+    return false;
+  }
+
+  private boolean jj_3_21()
+ {
+    if (jj_3R_83()) return true;
+    return false;
+  }
+
+  private boolean jj_3_20()
+ {
+    if (jj_3R_82()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_426()
+ {
+    if (jj_3R_427()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_81()
+ {
+    if (jj_scan_token(LSHIFT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_402()
+ {
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_103()
+ {
+    if (jj_scan_token(LT)) return true;
+    if (jj_3R_78()) return true;
+    if (jj_3R_158()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_159()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3_19()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_81()) {
+    jj_scanpos = xsp;
+    if (jj_3_20()) {
+    jj_scanpos = xsp;
+    if (jj_3_21()) return true;
+    }
+    }
+    if (jj_3R_341()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_425()
+ {
+    if (jj_3R_96()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_342()
+ {
+    if (jj_scan_token(INSTANCEOF)) return true;
+    if (jj_3R_68()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_339()
+ {
+    if (jj_3R_341()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_19()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_419()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_425()) {
+    jj_scanpos = xsp;
+    if (jj_3R_426()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_364()
+ {
+    if (jj_scan_token(GE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_363()
+ {
+    if (jj_scan_token(LE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_362()
+ {
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_361()
+ {
+    if (jj_scan_token(LT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_376()
+ {
+    if (jj_3R_163()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_346()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_361()) {
+    jj_scanpos = xsp;
+    if (jj_3R_362()) {
+    jj_scanpos = xsp;
+    if (jj_3R_363()) {
+    jj_scanpos = xsp;
+    if (jj_3R_364()) return true;
+    }
+    }
+    }
+    if (jj_3R_339()) return true;
+    return false;
+  }
+
+  private boolean jj_3_37()
+ {
+    if (jj_3R_96()) return true;
+    if (jj_scan_token(COLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_102()
+ {
+    if (jj_3R_101()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_367()
+ {
+    if (jj_3R_183()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_66()
+ {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_102()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(IDENTIFIER)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_376()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_377()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_401()
+ {
+    if (jj_3R_419()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_387()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_401()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_402()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_403()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_337()
+ {
+    if (jj_3R_339()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_346()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_386()
+ {
+    if (jj_3R_96()) return true;
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_352()
+ {
+    if (jj_scan_token(SEMICOLON)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_367()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_338()
+ {
+    if (jj_scan_token(BIT_AND)) return true;
+    if (jj_3R_314()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_325()
+ {
+    if (jj_scan_token(FOR)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_386()) {
+    jj_scanpos = xsp;
+    if (jj_3R_387()) return true;
+    }
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_277()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_332()
+ {
+    if (jj_3R_337()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_342()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_351()
+ {
+    if (jj_3R_66()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_3()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_344()
+ {
+    if (jj_scan_token(NE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_343()
+ {
+    if (jj_scan_token(EQ)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_340()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_343()) {
+    jj_scanpos = xsp;
+    if (jj_3R_344()) return true;
+    }
+    if (jj_3R_332()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_333()
+ {
+    if (jj_scan_token(XOR)) return true;
+    if (jj_3R_285()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_324()
+ {
+    if (jj_scan_token(DO)) return true;
+    if (jj_3R_277()) return true;
+    if (jj_scan_token(WHILE)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_350()
+ {
+    if (jj_3R_366()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_315()
+ {
+    if (jj_scan_token(BIT_OR)) return true;
+    if (jj_3R_265()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_314()
+ {
+    if (jj_3R_332()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_340()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_271()
+ {
+    if (jj_scan_token(ENUM)) return true;
+    if (jj_3R_98()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_350()) jj_scanpos = xsp;
+    if (jj_scan_token(LBRACE)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_351()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(113)) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_352()) jj_scanpos = xsp;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_323()
+ {
+    if (jj_scan_token(WHILE)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_277()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_286()
+ {
+    if (jj_scan_token(SC_AND)) return true;
+    if (jj_3R_237()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_285()
+ {
+    if (jj_3R_314()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_338()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_267()
+ {
+    if (jj_scan_token(SC_OR)) return true;
+    if (jj_3R_207()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_375()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_251()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_366()
+ {
+    if (jj_scan_token(IMPLEMENTS)) return true;
+    if (jj_3R_251()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_375()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_265()
+ {
+    if (jj_3R_285()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_333()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_322()
+ {
+    if (jj_scan_token(IF)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_277()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_385()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_237()
+ {
+    if (jj_3R_265()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_315()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_374()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_251()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_365()
+ {
+    if (jj_scan_token(EXTENDS)) return true;
+    if (jj_3R_251()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_374()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_207()
+ {
+    if (jj_3R_237()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_286()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_418()
+ {
+    if (jj_scan_token(_DEFAULT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_417()
+ {
+    if (jj_scan_token(CASE)) return true;
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_289()
+ {
+    if (jj_scan_token(INTERFACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_349()
+ {
+    if (jj_3R_366()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_176()
+ {
+    if (jj_3R_207()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_267()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_348()
+ {
+    if (jj_3R_365()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_400()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_417()) {
+    jj_scanpos = xsp;
+    if (jj_3R_418()) return true;
+    }
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_160()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_347()
+ {
+    if (jj_3R_103()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_270()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(45)) {
+    jj_scanpos = xsp;
+    if (jj_3R_289()) return true;
+    }
+    if (jj_3R_98()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_347()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_348()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_349()) jj_scanpos = xsp;
+    if (jj_3R_93()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_150()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_149()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_241()
+ {
+    if (jj_scan_token(HOOK)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_129()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_384()
+ {
+    if (jj_3R_400()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_129()
+ {
+    if (jj_3R_176()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_241()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_321()
+ {
+    if (jj_scan_token(SWITCH)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_384()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_128()
+ {
+    if (jj_scan_token(ORASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_424()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_127()
+ {
+    if (jj_scan_token(XORASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_126()
+ {
+    if (jj_scan_token(ANDASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_125()
+ {
+    if (jj_scan_token(RUNSIGNEDSHIFTASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_124()
+ {
+    if (jj_scan_token(RSIGNEDSHIFTASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_123()
+ {
+    if (jj_scan_token(LSHIFTASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_416()
+ {
+    if (jj_scan_token(ARROW)) return true;
+    if (jj_3R_268()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_122()
+ {
+    if (jj_scan_token(MINUSASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_121()
+ {
+    if (jj_scan_token(PLUSASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_415()
+ {
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_424()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(103)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(68)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_120()
+ {
+    if (jj_scan_token(REMASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_414()
+ {
+    if (jj_3R_79()) return true;
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_119()
+ {
+    if (jj_scan_token(SLASHASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_118()
+ {
+    if (jj_scan_token(STARASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_413()
+ {
+    if (jj_scan_token(DECR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_117()
+ {
+    if (jj_scan_token(ASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_412()
+ {
+    if (jj_scan_token(INCR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_399()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_412()) {
+    jj_scanpos = xsp;
+    if (jj_3R_413()) {
+    jj_scanpos = xsp;
+    if (jj_3R_414()) {
+    jj_scanpos = xsp;
+    if (jj_3R_415()) {
+    jj_scanpos = xsp;
+    if (jj_3R_416()) return true;
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_79()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_117()) {
+    jj_scanpos = xsp;
+    if (jj_3R_118()) {
+    jj_scanpos = xsp;
+    if (jj_3R_119()) {
+    jj_scanpos = xsp;
+    if (jj_3R_120()) {
+    jj_scanpos = xsp;
+    if (jj_3R_121()) {
+    jj_scanpos = xsp;
+    if (jj_3R_122()) {
+    jj_scanpos = xsp;
+    if (jj_3R_123()) {
+    jj_scanpos = xsp;
+    if (jj_3R_124()) {
+    jj_scanpos = xsp;
+    if (jj_3R_125()) {
+    jj_scanpos = xsp;
+    if (jj_3R_126()) {
+    jj_scanpos = xsp;
+    if (jj_3R_127()) {
+    jj_scanpos = xsp;
+    if (jj_3R_128()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_336()
+ {
+    if (jj_3R_266()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_399()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_335()
+ {
+    if (jj_3R_216()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_269()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3_36()
+ {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_243()
+ {
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_269()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(103)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(68)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_320()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_36()) {
+    jj_scanpos = xsp;
+    if (jj_3R_335()) {
+    jj_scanpos = xsp;
+    if (jj_3R_336()) return true;
+    }
+    }
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_65()
+ {
+    if (jj_3R_101()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_64()
+ {
+    if (jj_scan_token(STRICTFP)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_63()
+ {
+    if (jj_scan_token(VOLATILE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_62()
+ {
+    if (jj_scan_token(TRANSIENT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_61()
+ {
+    if (jj_scan_token(NATIVE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_60()
+ {
+    if (jj_scan_token(SYNCHRONIZED)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_288()
+ {
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_59()
+ {
+    if (jj_scan_token(ABSTRACT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_58()
+ {
+    if (jj_scan_token(FINAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3_18()
+ {
+    if (jj_3R_79()) return true;
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_242()
+ {
+    if (jj_scan_token(ARROW)) return true;
+    if (jj_3R_268()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_57()
+ {
+    if (jj_scan_token(PRIVATE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_56()
+ {
+    if (jj_scan_token(PROTECTED)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_213()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_18()) {
+    jj_scanpos = xsp;
+    if (jj_3R_242()) {
+    jj_scanpos = xsp;
+    if (jj_3R_243()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_287()
+ {
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_55()
+ {
+    if (jj_scan_token(STATIC)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_54()
+ {
+    if (jj_scan_token(PUBLIC)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_80()
+ {
+    if (jj_3R_129()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_213()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3_2()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_54()) {
+    jj_scanpos = xsp;
+    if (jj_3R_55()) {
+    jj_scanpos = xsp;
+    if (jj_3R_56()) {
+    jj_scanpos = xsp;
+    if (jj_3R_57()) {
+    jj_scanpos = xsp;
+    if (jj_3R_58()) {
+    jj_scanpos = xsp;
+    if (jj_3R_59()) {
+    jj_scanpos = xsp;
+    if (jj_3R_60()) {
+    jj_scanpos = xsp;
+    if (jj_3R_61()) {
+    jj_scanpos = xsp;
+    if (jj_3R_62()) {
+    jj_scanpos = xsp;
+    if (jj_3R_63()) {
+    jj_scanpos = xsp;
+    if (jj_3R_64()) {
+    jj_scanpos = xsp;
+    if (jj_3R_65()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_268()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_287()) {
+    jj_scanpos = xsp;
+    if (jj_3R_288()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_95()
+ {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_2()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_319()
+ {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3_35()
+ {
+    if (jj_3R_96()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_96()
+ {
+    if (jj_3R_95()) return true;
+    if (jj_3R_68()) return true;
+    if (jj_3R_149()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_150()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_202()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3_34()
+ {
+    if (jj_3R_95()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(45)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(65)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_255()
+ {
+    if (jj_3R_277()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_383()
+ {
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3_17()
+ {
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_254()
+ {
+    if (jj_3R_96()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_98()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_17()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_53()
+ {
+    if (jj_3R_78()) return true;
+    if (jj_scan_token(PACKAGE)) return true;
+    if (jj_3R_98()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_253()
+ {
+    if (jj_3R_95()) return true;
+    if (jj_3R_270()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_147()
+ {
+    if (jj_3R_68()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_146()
+ {
+    if (jj_scan_token(VOID)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_220()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_253()) {
+    jj_scanpos = xsp;
+    if (jj_3R_254()) {
+    jj_scanpos = xsp;
+    if (jj_3R_255()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3_1()
+ {
+    if (jj_3R_53()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_91()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_146()) {
+    jj_scanpos = xsp;
+    if (jj_3R_147()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_140()
+ {
+    if (jj_scan_token(DOUBLE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_106()
+ {
+    if (jj_scan_token(LBRACE)) return true;
+    if (jj_3R_160()) return true;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_139()
+ {
+    if (jj_scan_token(FLOAT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_138()
+ {
+    if (jj_scan_token(LONG)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_137()
+ {
+    if (jj_scan_token(INT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_136()
+ {
+    if (jj_scan_token(SHORT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_135()
+ {
+    if (jj_scan_token(BYTE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_94()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_277()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_134()
+ {
+    if (jj_scan_token(CHAR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_133()
+ {
+    if (jj_scan_token(BOOLEAN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_313()
+ {
+    if (jj_scan_token(SUPER)) return true;
+    if (jj_3R_78()) return true;
+    if (jj_3R_75()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_87()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_133()) {
+    jj_scanpos = xsp;
+    if (jj_3R_134()) {
+    jj_scanpos = xsp;
+    if (jj_3R_135()) {
+    jj_scanpos = xsp;
+    if (jj_3R_136()) {
+    jj_scanpos = xsp;
+    if (jj_3R_137()) {
+    jj_scanpos = xsp;
+    if (jj_3R_138()) {
+    jj_scanpos = xsp;
+    if (jj_3R_139()) {
+    jj_scanpos = xsp;
+    if (jj_3R_140()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_204()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_175()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_312()
+ {
+    if (jj_scan_token(EXTENDS)) return true;
+    if (jj_3R_78()) return true;
+    if (jj_3R_75()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_284()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_312()) {
+    jj_scanpos = xsp;
+    if (jj_3R_313()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_318()
+ {
+    if (jj_scan_token(ASSERT)) return true;
+    if (jj_3R_80()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_383()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_308()
+ {
+    if (jj_3R_331()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_307()
+ {
+    if (jj_3R_330()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_306()
+ {
+    if (jj_3R_329()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_305()
+ {
+    if (jj_3R_328()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_304()
+ {
+    if (jj_3R_327()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_303()
+ {
+    if (jj_3R_326()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_236()
+ {
+    if (jj_scan_token(HOOK)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_284()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_302()
+ {
+    if (jj_3R_325()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_301()
+ {
+    if (jj_3R_324()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_300()
+ {
+    if (jj_3R_323()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_299()
+ {
+    if (jj_3R_322()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_298()
+ {
+    if (jj_3R_321()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_297()
+ {
+    if (jj_3R_320()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_206()
+ {
+    if (jj_3R_236()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_296()
+ {
+    if (jj_3R_319()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_205()
+ {
+    if (jj_3R_75()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_295()
+ {
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_294()
+ {
+    if (jj_3R_318()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_175()
+ {
+    if (jj_3R_78()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_205()) {
+    jj_scanpos = xsp;
+    if (jj_3R_206()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3_33()
+ {
+    if (jj_3R_94()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_115()
+ {
+    if (jj_3R_175()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_204()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_277()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_33()) {
+    jj_scanpos = xsp;
+    if (jj_3R_294()) {
+    jj_scanpos = xsp;
+    if (jj_3R_295()) {
+    jj_scanpos = xsp;
+    if (jj_3R_296()) {
+    jj_scanpos = xsp;
+    if (jj_3R_297()) {
+    jj_scanpos = xsp;
+    if (jj_3R_298()) {
+    jj_scanpos = xsp;
+    if (jj_3R_299()) {
+    jj_scanpos = xsp;
+    if (jj_3R_300()) {
+    jj_scanpos = xsp;
+    if (jj_3R_301()) {
+    jj_scanpos = xsp;
+    if (jj_3R_302()) {
+    jj_scanpos = xsp;
+    if (jj_3R_303()) {
+    jj_scanpos = xsp;
+    if (jj_3R_304()) {
+    jj_scanpos = xsp;
+    if (jj_3R_305()) {
+    jj_scanpos = xsp;
+    if (jj_3R_306()) {
+    jj_scanpos = xsp;
+    if (jj_3R_307()) {
+    jj_scanpos = xsp;
+    if (jj_3R_308()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_77()
+ {
+    if (jj_scan_token(LT)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_115()) jj_scanpos = xsp;
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3_16()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3_32()
+ {
+    if (jj_3R_93()) return true;
+    return false;
+  }
+
+  private boolean jj_3_15()
+ {
+    if (jj_scan_token(DOT)) return true;
+    if (jj_3R_78()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_16()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_311()
+ {
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_283()
+ {
+    if (jj_3R_161()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_282()
+ {
+    if (jj_3R_78()) return true;
+    if (jj_scan_token(LBRACKET)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_311()) jj_scanpos = xsp;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_261()
+ {
+    Token xsp;
+    if (jj_3R_282()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_282()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3R_283()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3_14()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_174()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_14()) jj_scanpos = xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_15()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_256()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_264()
+ {
+    if (jj_3R_163()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_32()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_263()
+ {
+    if (jj_3R_261()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_262()
+ {
+    if (jj_3R_77()) return true;
+    if (jj_3R_78()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_235()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_262()) jj_scanpos = xsp;
+    if (jj_3R_251()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_263()) {
+    jj_scanpos = xsp;
+    if (jj_3R_264()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_234()
+ {
+    if (jj_3R_87()) return true;
+    if (jj_3R_261()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_251()
+ {
+    if (jj_3R_78()) return true;
+    if (jj_3R_174()) return true;
+    return false;
+  }
+
+  private boolean jj_3_13()
+ {
+    if (jj_3R_76()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_428()
+ {
+    if (jj_3R_430()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_200()
+ {
+    if (jj_scan_token(NEW)) return true;
+    if (jj_3R_78()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_234()) {
+    jj_scanpos = xsp;
+    if (jj_3R_235()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3_12()
+ {
+    if (jj_3R_76()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_355()
+ {
+    if (jj_scan_token(THROWS)) return true;
+    if (jj_3R_370()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_371()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_76()
+ {
+    if (jj_3R_78()) return true;
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_221()
+ {
+    if (jj_3R_80()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_256()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_195()
+ {
+    if (jj_3R_221()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_114()
+ {
+    if (jj_3R_174()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_13()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_163()
+ {
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_195()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_113()
+ {
+    if (jj_3R_87()) return true;
+    Token xsp;
+    if (jj_3_12()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_12()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_75()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_113()) {
+    jj_scanpos = xsp;
+    if (jj_3R_114()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_258()
+ {
+    if (jj_scan_token(NULL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_279()
+ {
+    if (jj_scan_token(FALSE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_278()
+ {
+    if (jj_scan_token(TRUE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_104()
+ {
+    if (jj_3R_87()) return true;
+    return false;
+  }
+
+  private boolean jj_3_11()
+ {
+    if (jj_3R_75()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_68()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_11()) {
+    jj_scanpos = xsp;
+    if (jj_3R_104()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_257()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_278()) {
+    jj_scanpos = xsp;
+    if (jj_3R_279()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_430()
+ {
+    if (jj_scan_token(_DEFAULT)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_228()
+ {
+    if (jj_3R_258()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_227()
+ {
+    if (jj_3R_257()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_226()
+ {
+    if (jj_scan_token(STRING_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_105()
+ {
+    if (jj_scan_token(STATIC)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_225()
+ {
+    if (jj_scan_token(CHARACTER_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_423()
+ {
+    if (jj_3R_68()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_428()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_70()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_105()) jj_scanpos = xsp;
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_224()
+ {
+    if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_194()
+ {
+    if (jj_3R_220()) return true;
+    return false;
+  }
+
+  private boolean jj_3_44()
+ {
+    if (jj_3R_68()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_411()
+ {
+    if (jj_3R_274()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_160()
+ {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_194()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_410()
+ {
+    if (jj_3R_272()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_223()
+ {
+    if (jj_scan_token(LONG_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3_9()
+ {
+    if (jj_3R_73()) return true;
+    if (jj_scan_token(DOT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_409()
+ {
+    if (jj_3R_271()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_408()
+ {
+    if (jj_3R_270()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_222()
+ {
+    if (jj_scan_token(INTEGER_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_407()
+ {
+    if (jj_3R_423()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_74()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_165()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3_10()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_74()) jj_scanpos = xsp;
+    if (jj_scan_token(THIS)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_164()
+ {
+    if (jj_3R_73()) return true;
+    if (jj_scan_token(DOT)) return true;
+    return false;
+  }
+
+  private boolean jj_3_43()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_92()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_196()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_222()) {
+    jj_scanpos = xsp;
+    if (jj_3R_223()) {
+    jj_scanpos = xsp;
+    if (jj_3R_224()) {
+    jj_scanpos = xsp;
+    if (jj_3R_225()) {
+    jj_scanpos = xsp;
+    if (jj_3R_226()) {
+    jj_scanpos = xsp;
+    if (jj_3R_227()) {
+    jj_scanpos = xsp;
+    if (jj_3R_228()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_394()
+ {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_110()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_164()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_165()) jj_scanpos = xsp;
+    if (jj_scan_token(SUPER)) return true;
+    if (jj_3R_163()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_143()
+ {
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3_31()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_92()) jj_scanpos = xsp;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_395()
+ {
+    if (jj_3R_95()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_407()) {
+    jj_scanpos = xsp;
+    if (jj_3R_408()) {
+    jj_scanpos = xsp;
+    if (jj_3R_409()) {
+    jj_scanpos = xsp;
+    if (jj_3R_410()) {
+    jj_scanpos = xsp;
+    if (jj_3R_411()) return true;
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_162()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_109()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_162()) jj_scanpos = xsp;
+    if (jj_scan_token(THIS)) return true;
+    if (jj_3R_163()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_212()
+ {
+    if (jj_3R_163()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_378()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_394()) {
+    jj_scanpos = xsp;
+    if (jj_3R_395()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_211()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_181()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_211()) jj_scanpos = xsp;
+    if (jj_3R_202()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_212()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_368()
+ {
+    if (jj_3R_378()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_180()
+ {
+    if (jj_3R_200()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_72()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_109()) {
+    jj_scanpos = xsp;
+    if (jj_3R_110()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_179()
+ {
+    if (jj_scan_token(THIS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_353()
+ {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_368()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_259()
+ {
+    if (jj_3R_280()) return true;
+    return false;
+  }
+
+  private boolean jj_3_8()
+ {
+    if (jj_3R_72()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_144()
+ {
+    if (jj_scan_token(ELLIPSIS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_142()
+ {
+    if (jj_scan_token(DOT)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_179()) {
+    jj_scanpos = xsp;
+    if (jj_3R_180()) {
+    jj_scanpos = xsp;
+    if (jj_3R_181()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_309()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_90()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_89()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_142()) {
+    jj_scanpos = xsp;
+    if (jj_3R_143()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_356()
+ {
+    if (jj_3R_72()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_272()
+ {
+    if (jj_scan_token(AT)) return true;
+    if (jj_scan_token(INTERFACE)) return true;
+    if (jj_3R_98()) return true;
+    if (jj_3R_353()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_371()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_370()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_317()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_316()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_290()
+ {
+    if (jj_3R_103()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_141()
+ {
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(SUPER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_273()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_290()) jj_scanpos = xsp;
+    if (jj_3R_202()) return true;
+    if (jj_3R_354()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_355()) jj_scanpos = xsp;
+    if (jj_scan_token(LBRACE)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_356()) jj_scanpos = xsp;
+    if (jj_3R_160()) return true;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_334()
+ {
+    if (jj_3R_100()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_43()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3_30()
+ {
+    if (jj_3R_89()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_201()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_379()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_90()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_88()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_30()) {
+    jj_scanpos = xsp;
+    if (jj_3R_141()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_189()
+ {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_334()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(113)) jj_scanpos = xsp;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_203()
+ {
+    if (jj_3R_163()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_154()
+ {
+    if (jj_3R_129()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_153()
+ {
+    if (jj_3R_189()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_173()
+ {
+    if (jj_3R_202()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_203()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_152()
+ {
+    if (jj_3R_101()) return true;
+    return false;
+  }
+
+  private boolean jj_3_29()
+ {
+    if (jj_3R_91()) return true;
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3_28()
+ {
+    if (jj_3R_91()) return true;
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(CLASS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_90()
+ {
+    if (jj_3R_95()) return true;
+    if (jj_3R_68()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_144()) jj_scanpos = xsp;
+    if (jj_3R_145()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_100()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_152()) {
+    jj_scanpos = xsp;
+    if (jj_3R_153()) {
+    jj_scanpos = xsp;
+    if (jj_3R_154()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3_7()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_71()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_260()
+ {
+    if (jj_3R_281()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_172()
+ {
+    if (jj_3R_91()) return true;
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_201()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(103)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(68)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_276()
+ {
+    if (jj_3R_293()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_171()
+ {
+    if (jj_3R_91()) return true;
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(CLASS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_316()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(ASSIGN)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_310()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_145()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_170()
+ {
+    if (jj_3R_200()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_281()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_145()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_310()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3_27()
+ {
+    if (jj_3R_90()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_293()
+ {
+    if (jj_3R_316()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_317()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_358()
+ {
+    if (jj_3R_76()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_233()
+ {
+    if (jj_3R_80()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_260()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_280()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_90()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_309()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_232()
+ {
+    if (jj_3R_90()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_259()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_199()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_232()) {
+    jj_scanpos = xsp;
+    if (jj_3R_233()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_231()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_369()
+ {
+    if (jj_3R_90()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_379()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_191()
+ {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_98()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_99()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(ASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_169()
+ {
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_199()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_198()
+ {
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_231()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(103)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(68)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_354()
+ {
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_369()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_192()
+ {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_98()) return true;
+    return false;
+  }
+
+  private boolean jj_3_42()
+ {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_98()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3_41()
+ {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_98()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_99()) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(107)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_230()
+ {
+    if (jj_3R_163()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_190()
+ {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_98()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_276()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_370()
+ {
+    if (jj_3R_78()) return true;
+    if (jj_3R_75()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_197()
+ {
+    if (jj_scan_token(DOT)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_229()) jj_scanpos = xsp;
+    if (jj_3R_202()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_230()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_229()
+ {
+    if (jj_3R_77()) return true;
+    return false;
+  }
+
+  private boolean jj_3_40()
+ {
+    if (jj_scan_token(SEMICOLON)) return true;
+    if (jj_3R_96()) return true;
+    return false;
+  }
+
+  private boolean jj_3_26()
+ {
+    if (jj_3R_89()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_157()
+ {
+    if (jj_3R_192()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_182()
+ {
+    if (jj_3R_76()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_168()
+ {
+    if (jj_scan_token(SUPER)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_197()) {
+    jj_scanpos = xsp;
+    if (jj_3R_198()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_156()
+ {
+    if (jj_3R_191()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_167()
+ {
+    if (jj_scan_token(THIS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_155()
+ {
+    if (jj_3R_190()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_166()
+ {
+    if (jj_3R_196()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_292()
+ {
+    if (jj_3R_71()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_7()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_372()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_370()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_360()
+ {
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_112()
+ {
+    if (jj_3R_89()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_359()
+ {
+    if (jj_scan_token(THROWS)) return true;
+    if (jj_3R_370()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_372()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_291()
+ {
+    if (jj_3R_103()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_111()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_166()) {
+    jj_scanpos = xsp;
+    if (jj_3R_167()) {
+    jj_scanpos = xsp;
+    if (jj_3R_168()) {
+    jj_scanpos = xsp;
+    if (jj_3R_169()) {
+    jj_scanpos = xsp;
+    if (jj_3R_170()) {
+    jj_scanpos = xsp;
+    if (jj_3R_171()) {
+    jj_scanpos = xsp;
+    if (jj_3R_172()) {
+    jj_scanpos = xsp;
+    if (jj_3R_173()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_101()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_155()) {
+    jj_scanpos = xsp;
+    if (jj_3R_156()) {
+    jj_scanpos = xsp;
+    if (jj_3R_157()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_275()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_291()) jj_scanpos = xsp;
+    if (jj_3R_91()) return true;
+    if (jj_3R_98()) return true;
+    if (jj_3R_354()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_358()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3R_359()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_360()) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(112)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3_25()
+ {
+    if (jj_3R_88()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_116()
+ {
+    if (jj_3R_101()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_78()
+ {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_116()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_130()
+ {
+    return false;
+  }
+
+  private boolean jj_3R_73()
+ {
+    if (jj_3R_111()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_112()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_131()
+ {
+    return false;
+  }
+
+  private boolean jj_3R_161()
+ {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_292()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(113)) jj_scanpos = xsp;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_82()
+ {
+    jj_lookingAhead = true;
+    jj_semLA = getToken(1).kind == GT &&
+                ((GTToken)getToken(1)).realKind == RSIGNEDSHIFT;
+    jj_lookingAhead = false;
+    if (!jj_semLA || jj_3R_130()) return true;
+    if (jj_scan_token(GT)) return true;
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_108()
+ {
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_107()
+ {
+    if (jj_3R_161()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_184()
+ {
+    if (jj_scan_token(ASSIGN)) return true;
+    if (jj_3R_71()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_266()
+ {
+    if (jj_3R_111()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_25()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_83()
+ {
+    jj_lookingAhead = true;
+    jj_semLA = getToken(1).kind == GT &&
+                ((GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT;
+    jj_lookingAhead = false;
+    if (!jj_semLA || jj_3R_131()) return true;
+    if (jj_scan_token(GT)) return true;
+    if (jj_scan_token(GT)) return true;
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_71()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_107()) {
+    jj_scanpos = xsp;
+    if (jj_3R_108()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_177()
+ {
+    if (jj_scan_token(BIT_AND)) return true;
+    if (jj_3R_75()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_132()
+ {
+    if (jj_3R_75()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_177()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_178()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_421()
+ {
+    if (jj_3R_96()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_40()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_145()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_182()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3_24()
+ {
+    if (jj_3R_87()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_84()
+ {
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_78()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_24()) {
+    jj_scanpos = xsp;
+    if (jj_3R_132()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3_39()
+ {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_149()
+ {
+    if (jj_3R_145()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_184()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_404()
+ {
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_421()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_39()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_406()
+ {
+    if (jj_scan_token(FINALLY)) return true;
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_393()
+ {
+    if (jj_scan_token(FINALLY)) return true;
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_422()
+ {
+    if (jj_scan_token(BIT_OR)) return true;
+    if (jj_3R_370()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_69()
+ {
+    if (jj_3R_76()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_86()
+ {
+    if (jj_scan_token(DECR)) return true;
+    return false;
+  }
+
+  private boolean jj_3_23()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_85()) {
+    jj_scanpos = xsp;
+    if (jj_3R_86()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_85()
+ {
+    if (jj_scan_token(INCR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_357()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_149()) return true;
+    return false;
+  }
+
+  private boolean jj_3_22()
+ {
+    if (jj_3R_84()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_405()
+ {
+    if (jj_scan_token(CATCH)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_95()) return true;
+    if (jj_3R_75()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_422()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_145()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_274()
+ {
+    if (jj_3R_68()) return true;
+    if (jj_3R_149()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_357()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_240()
+ {
+    if (jj_3R_266()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_23()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_215()
+ {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_209()
+ {
+    if (jj_3R_84()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_210()
+ {
+    if (jj_3R_240()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_239()
+ {
+    if (jj_scan_token(BANG)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_238()
+ {
+    if (jj_scan_token(TILDE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_208()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_238()) {
+    jj_scanpos = xsp;
+    if (jj_3R_239()) return true;
+    }
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3_5()
+ {
+    if (jj_3R_68()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_69()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_scan_token(113)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(116)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(112)) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_392()
+ {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_405()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3R_406()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_67()
+ {
+    if (jj_3R_103()) return true;
+    return false;
+  }
+
+  private boolean jj_3_4()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_67()) jj_scanpos = xsp;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_178()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_208()) {
+    jj_scanpos = xsp;
+    if (jj_3R_209()) {
+    jj_scanpos = xsp;
+    if (jj_3R_210()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_250()
+ {
+    if (jj_3R_275()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_391()
+ {
+    if (jj_3R_404()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_331()
+ {
+    if (jj_scan_token(TRY)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_391()) jj_scanpos = xsp;
+    if (jj_3R_106()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_392()) {
+    jj_scanpos = xsp;
+    if (jj_3R_393()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_244()
+ {
+    if (jj_scan_token(_DEFAULT)) return true;
+    if (jj_3R_95()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_249()
+ {
+    if (jj_3R_274()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_248()
+ {
+    if (jj_3R_273()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_247()
+ {
+    if (jj_3R_272()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_216()
+ {
+    if (jj_scan_token(DECR)) return true;
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_246()
+ {
+    if (jj_3R_271()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_245()
+ {
+    if (jj_3R_270()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_390()
+ {
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_193()
+ {
+    if (jj_3R_219()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_97()
+ {
+    if (jj_scan_token(INCR)) return true;
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_188()
+ {
+    if (jj_3R_178()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_389()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_330()
+ {
+    if (jj_scan_token(SYNCHRONIZED)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_106()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_214()
+ {
+    if (jj_3R_95()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_244()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_245()) {
+    jj_scanpos = xsp;
+    if (jj_3R_246()) {
+    jj_scanpos = xsp;
+    if (jj_3R_247()) {
+    jj_scanpos = xsp;
+    if (jj_3R_248()) {
+    jj_scanpos = xsp;
+    if (jj_3R_249()) {
+    jj_scanpos = xsp;
+    if (jj_3R_250()) return true;
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3_6()
+ {
+    if (jj_3R_70()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_388()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_218()
+ {
+    if (jj_scan_token(MINUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_217()
+ {
+    if (jj_scan_token(PLUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_329()
+ {
+    if (jj_scan_token(THROW)) return true;
+    if (jj_3R_80()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_187()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_217()) {
+    jj_scanpos = xsp;
+    if (jj_3R_218()) return true;
+    }
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_186()
+ {
+    if (jj_3R_216()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_185()
+ {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_183()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_6()) {
+    jj_scanpos = xsp;
+    if (jj_3R_214()) {
+    jj_scanpos = xsp;
+    if (jj_3R_215()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_429()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_80()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_328()
+ {
+    if (jj_scan_token(RETURN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_390()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_148()
+ {
+    if (jj_3R_183()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_151()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_185()) {
+    jj_scanpos = xsp;
+    if (jj_3R_186()) {
+    jj_scanpos = xsp;
+    if (jj_3R_187()) {
+    jj_scanpos = xsp;
+    if (jj_3R_188()) return true;
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_398()
+ {
+    if (jj_scan_token(REM)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_397()
+ {
+    if (jj_scan_token(SLASH)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_327()
+ {
+    if (jj_scan_token(CONTINUE)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_389()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_93()
+ {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_148()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_396()
+ {
+    if (jj_scan_token(STAR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_380()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_396()) {
+    jj_scanpos = xsp;
+    if (jj_3R_397()) {
+    jj_scanpos = xsp;
+    if (jj_3R_398()) return true;
+    }
+    }
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_403()
+ {
+    if (jj_3R_420()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_252()
+ {
+    if (jj_scan_token(BIT_AND)) return true;
+    if (jj_3R_251()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_326()
+ {
+    if (jj_scan_token(BREAK)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_388()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_219()
+ {
+    if (jj_scan_token(EXTENDS)) return true;
+    if (jj_3R_251()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_252()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_345()
+ {
+    if (jj_3R_151()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_380()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_382()
+ {
+    if (jj_scan_token(MINUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_381()
+ {
+    if (jj_scan_token(PLUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3_3()
+ {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_66()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_373()
+ {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_381()) {
+    jj_scanpos = xsp;
+    if (jj_3R_382()) return true;
+    }
+    if (jj_3R_345()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_158()
+ {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_193()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_420()
+ {
+    if (jj_3R_427()) return true;
+    return false;
+  }
+
+  /** Generated Token Manager. */
+  public ASTParserTokenManager token_source;
+  JavaCharStream jj_input_stream;
+  /** Current token. */
+  public Token token;
+  /** Next token. */
+  public Token jj_nt;
+  private int jj_ntk;
+  private Token jj_scanpos, jj_lastpos;
+  private int jj_la;
+  /** Whether we are looking ahead. */
+  private boolean jj_lookingAhead = false;
+  private boolean jj_semLA;
+  private int jj_gen;
+  final private int[] jj_la1 = new int[160];
+  static private int[] jj_la1_0;
+  static private int[] jj_la1_1;
+  static private int[] jj_la1_2;
+  static private int[] jj_la1_3;
+  static private int[] jj_la1_4;
+  static {
+      jj_la1_init_0();
+      jj_la1_init_1();
+      jj_la1_init_2();
+      jj_la1_init_3();
+      jj_la1_init_4();
+   }
+   private static void jj_la1_init_0() {
+      jj_la1_0 = new int[] {0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+   }
+   private static void jj_la1_init_1() {
+      jj_la1_1 = new int[] {0x40000000,0x40000000,0x902020,0x0,0x0,0x0,0x800020,0x102000,0x902020,0x2000,0x0,0x200000,0x20000000,0x0,0x0,0x20000000,0x0,0x0,0x29532a0,0x0,0x0,0x0,0x0,0x0,0x200000,0x0,0x29532a0,0x10000,0x102000,0x2041280,0x29532a0,0x0,0x0,0x0,0x2441280,0x2441280,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x28412a0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2441280,0x16c6b3e0,0x0,0x2041280,0x2041280,0x2041280,0x0,0x2041280,0x2041280,0x200000,0x200000,0x2041280,0x2041280,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2441280,0x0,0x0,0x2441280,0x0,0x0,0x2041280,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2441280,0x2c412a0,0x0,0x0,0x0,0x400000,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x400000,0x2441280,0x0,0x0,0x0,0x2041280,0x2441280,0x0,0x0,0x164693c0,0x0,0x164693c0,0x0,0x2441280,0x0,0x0,0x0,0x0,0x2441280,0x10400,0x10400,0x80000,0x2c412a0,0x2441280,0x2441280,0x2c412a0,0x2441280,0x0,0x0,0x0,0x2441280,0x0,0x800,0x0,0x1000000,0x0,0x0,0x0,0x0,0x2441280,0x2441280,0x0,0x29432a0,0x2143280,0x29432a0,0x10000,};
+   }
+   private static void jj_la1_init_2() {
+      jj_la1_2 = new int[] {0x0,0x0,0x111338a,0x0,0x1000,0x0,0x1113388,0x2,0x111338a,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1913b8f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1913b8f,0x0,0x2,0x800805,0x1913b8f,0x0,0x0,0x0,0xca24835,0xca24835,0x0,0x0,0x0,0x0,0x80000,0x0,0x0,0x1113b8d,0x0,0x0,0x0,0x0,0x0,0x80000,0x0,0x0,0xca24835,0xff7ffbf,0x1000,0x805,0x805,0x805,0x0,0x805,0x805,0x4000,0x4000,0x805,0x800805,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xca24835,0x0,0x0,0xca24835,0x0,0x0,0x805,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0xca24835,0xdb37bbd,0x0,0x10,0x0,0xc224030,0x0,0x0,0x0,0x0,0x20010,0x0,0xc200020,0x200000,0xca24835,0x0,0x0,0x0,0x805,0xca24835,0x0,0x0,0xee7cc35,0x0,0xee7cc35,0x0,0xca24835,0x0,0x10,0x0,0x0,0xca24835,0x0,0x0,0x0,0xdb37bbd,0xca24835,0xca24835,0xdb37bbd,0xca24835,0x0,0x0,0x0,0xca24835,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xca24835,0xca24835,0x0,0x1113b8f,0x807,0x1113b8f,0x0,};
+   }
+   private static void jj_la1_init_3() {
+      jj_la1_3 = new int[] {0x10000,0x10000,0x90000,0x0,0x0,0x40000,0x80000,0x80000,0x90000,0x0,0x200000,0x0,0x0,0x20000,0x20000,0x0,0x80080,0x20000,0x291080,0x10000,0x80000,0x400,0x1000,0x20000,0x0,0x0,0x291080,0x0,0x80000,0x200080,0x290080,0x20000,0x100000,0x84000,0xc014e1,0xc014e1,0x20000,0x200000,0x84000,0x20000,0x0,0x11000,0x20000,0x80080,0x20000,0x20000,0x0,0x200000,0x20000,0x0,0x200000,0x200000,0x2004e1,0x914e1,0x0,0x0,0x80,0x80,0x20000,0x1080080,0x1000080,0x0,0x0,0x0,0x80,0x200000,0x80,0x0,0x100000,0x100000,0x1000000,0x40000000,0x80000000,0x0,0x0,0x0,0x24000000,0x24000000,0x0,0x18200000,0x18200000,0x0,0x0,0x0,0x0,0x0,0x0,0xc004e1,0xc00000,0xc00000,0x4e1,0x0,0x0,0x80,0x200000,0x400,0x200000,0x80,0x40000,0x20000,0x20000,0xc004e1,0xc804e1,0x200000,0x80,0x400,0x461,0x80,0x40000,0x200000,0x400,0x0,0x44000,0x61,0x0,0xc004e1,0x20000,0x200000,0x84400,0x280080,0xc004e1,0x84000,0x1000,0x114e1,0x2000000,0x114e1,0x20000,0xc014e1,0x200000,0x80,0x100000,0x100000,0x4e1,0x0,0x0,0x0,0xc804e1,0xc004e1,0xc004e1,0xc904e1,0xc004e1,0x20000,0x80,0x80,0xc004e1,0x400,0x0,0x0,0x0,0x80000,0x80000,0x80,0x20000,0xc814e1,0xc814e1,0x20000,0x90080,0x80080,0x90080,0x0,};
+   }
+   private static void jj_la1_init_4() {
+      jj_la1_4 = new int[] {0x0,0x0,0x0,0x10000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400000,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1800000,0x1bff800,0x3ff800,0x0,0x0,0x0,0x80,0x100,0x40,0x0,0x0,0x0,0x8000000,0x8000000,0x400,0xc,0xc,0x230,0x230,0xc,0xf,0x0,0x0,0x0,0x3,0x40,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0xf,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x0,0x0,0x0,0x0,0xf,0x0,0x0,0x3,0x0,0x3,0x0,0xf,0x0,0x0,0x1bff803,0x1bff803,0x2,0x0,0x0,0x0,0xf,0xf,0xf,0xf,0xf,0x0,0x0,0x0,0xf,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0xf,0xf,0x0,0x0,0x0,0x0,0x0,};
+   }
+  final private JJCalls[] jj_2_rtns = new JJCalls[44];
+  private boolean jj_rescan = false;
+  private int jj_gc = 0;
+
+  /** Constructor. */
+  public ASTParser(Provider stream) {
+    jj_input_stream = new JavaCharStream(stream, 1, 1);
+    token_source = new ASTParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 160; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Constructor. */
+  public ASTParser(String dsl) throws ParseException, TokenMgrException {
+      this(new StringProvider(dsl));
+  }
+
+  public void ReInit(String s) {
+     ReInit(new StringProvider(s));
+  }
+  /** Reinitialise. */
+  public void ReInit(Provider stream) {
+	if (jj_input_stream == null) {
+      jj_input_stream = new JavaCharStream(stream, 1, 1);
+   } else {
+      jj_input_stream.ReInit(stream, 1, 1);
+   }
+   if (token_source == null) {
+      token_source = new ASTParserTokenManager(jj_input_stream);
+   }
+
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 160; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Constructor with generated Token Manager. */
+  public ASTParser(ASTParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 160; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+  public void ReInit(ASTParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 160; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  private Token jj_consume_token(int kind) {
+    Token oldToken;
+    if ((oldToken = token).next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      if (++jj_gc > 100) {
+        jj_gc = 0;
+        for (int i = 0; i < jj_2_rtns.length; i++) {
+          JJCalls c = jj_2_rtns[i];
+          while (c != null) {
+            if (c.gen < jj_gen) c.first = null;
+            c = c.next;
+          }
+        }
+      }
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  @SuppressWarnings("serial")
+  static private final class LookaheadSuccess extends java.lang.RuntimeException { }
+  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
+  private boolean jj_scan_token(int kind) {
+    if (jj_scanpos == jj_lastpos) {
+      jj_la--;
+      if (jj_scanpos.next == null) {
+        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+      } else {
+        jj_lastpos = jj_scanpos = jj_scanpos.next;
+      }
+    } else {
+      jj_scanpos = jj_scanpos.next;
+    }
+    if (jj_rescan) {
+      int i = 0; Token tok = token;
+      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+      if (tok != null) jj_add_error_token(kind, i);
+    }
+    if (jj_scanpos.kind != kind) return true;
+    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
+    return false;
+  }
+
+
+/** Get the next Token. */
+  final public Token getNextToken() {
+    if (token.next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
+  }
+
+/** Get the specific Token. */
+  final public Token getToken(int index) {
+    Token t = jj_lookingAhead ? jj_scanpos : token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) t = t.next;
+      else t = t.next = token_source.getNextToken();
+    }
+    return t;
+  }
+
+  private int jj_ntk_f() {
+    if ((jj_nt=token.next) == null)
+      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+    else
+      return (jj_ntk = jj_nt.kind);
+  }
+
+  private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
+  private int[] jj_expentry;
+  private int jj_kind = -1;
+  private int[] jj_lasttokens = new int[100];
+  private int jj_endpos;
+
+  private void jj_add_error_token(int kind, int pos) {
+    if (pos >= 100) {
+       return;
+    }
+
+    if (pos == jj_endpos + 1) {
+      jj_lasttokens[jj_endpos++] = kind;
+    } else if (jj_endpos != 0) {
+      jj_expentry = new int[jj_endpos];
+
+      for (int i = 0; i < jj_endpos; i++) {
+        jj_expentry[i] = jj_lasttokens[i];
+      }
+
+      for (int[] oldentry : jj_expentries) {
+        if (oldentry.length == jj_expentry.length) {
+          boolean isMatched = true;
+
+          for (int i = 0; i < jj_expentry.length; i++) {
+            if (oldentry[i] != jj_expentry[i]) {
+              isMatched = false;
+              break;
+            }
+
+          }
+          if (isMatched) {
+            jj_expentries.add(jj_expentry);
+            break;
+          }
+        }
+      }
+
+      if (pos != 0) {
+        jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+      }
+    }
+  }
+
+  /** Generate ParseException. */
+  public ParseException generateParseException() {
+    jj_expentries.clear();
+    boolean[] la1tokens = new boolean[157];
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 160; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
+          }
+          if ((jj_la1_1[i] & (1<<j)) != 0) {
+            la1tokens[32+j] = true;
+          }
+          if ((jj_la1_2[i] & (1<<j)) != 0) {
+            la1tokens[64+j] = true;
+          }
+          if ((jj_la1_3[i] & (1<<j)) != 0) {
+            la1tokens[96+j] = true;
+          }
+          if ((jj_la1_4[i] & (1<<j)) != 0) {
+            la1tokens[128+j] = true;
+          }
+        }
+      }
+    }
+    for (int i = 0; i < 157; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.add(jj_expentry);
+      }
+    }
+    jj_endpos = 0;
+    jj_rescan_token();
+    jj_add_error_token(0, 0);
+    int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = jj_expentries.get(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage, token_source == null ? null : ASTParserTokenManager.lexStateNames[token_source.curLexState]);
+  }
+
+  /** Enable tracing. */
+  final public void enable_tracing() {
+  }
+
+  /** Disable tracing. */
+  final public void disable_tracing() {
+  }
+
+  private void jj_rescan_token() {
+    jj_rescan = true;
+    for (int i = 0; i < 44; i++) {
+      try {
+        JJCalls p = jj_2_rtns[i];
+
+        do {
+          if (p.gen > jj_gen) {
+            jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+            switch (i) {
+              case 0: jj_3_1(); break;
+              case 1: jj_3_2(); break;
+              case 2: jj_3_3(); break;
+              case 3: jj_3_4(); break;
+              case 4: jj_3_5(); break;
+              case 5: jj_3_6(); break;
+              case 6: jj_3_7(); break;
+              case 7: jj_3_8(); break;
+              case 8: jj_3_9(); break;
+              case 9: jj_3_10(); break;
+              case 10: jj_3_11(); break;
+              case 11: jj_3_12(); break;
+              case 12: jj_3_13(); break;
+              case 13: jj_3_14(); break;
+              case 14: jj_3_15(); break;
+              case 15: jj_3_16(); break;
+              case 16: jj_3_17(); break;
+              case 17: jj_3_18(); break;
+              case 18: jj_3_19(); break;
+              case 19: jj_3_20(); break;
+              case 20: jj_3_21(); break;
+              case 21: jj_3_22(); break;
+              case 22: jj_3_23(); break;
+              case 23: jj_3_24(); break;
+              case 24: jj_3_25(); break;
+              case 25: jj_3_26(); break;
+              case 26: jj_3_27(); break;
+              case 27: jj_3_28(); break;
+              case 28: jj_3_29(); break;
+              case 29: jj_3_30(); break;
+              case 30: jj_3_31(); break;
+              case 31: jj_3_32(); break;
+              case 32: jj_3_33(); break;
+              case 33: jj_3_34(); break;
+              case 34: jj_3_35(); break;
+              case 35: jj_3_36(); break;
+              case 36: jj_3_37(); break;
+              case 37: jj_3_38(); break;
+              case 38: jj_3_39(); break;
+              case 39: jj_3_40(); break;
+              case 40: jj_3_41(); break;
+              case 41: jj_3_42(); break;
+              case 42: jj_3_43(); break;
+              case 43: jj_3_44(); break;
+            }
+          }
+          p = p.next;
+        } while (p != null);
+
+        } catch(LookaheadSuccess ls) { }
+    }
+    jj_rescan = false;
+  }
+
+  private void jj_save(int index, int xla) {
+    JJCalls p = jj_2_rtns[index];
+    while (p.gen > jj_gen) {
+      if (p.next == null) { p = p.next = new JJCalls(); break; }
+      p = p.next;
+    }
+
+    p.gen = jj_gen + xla - jj_la; 
+    p.first = token;
+    p.arg = xla;
+  }
+
+  static final class JJCalls {
+    int gen;
+    Token first;
+    int arg;
+    JJCalls next;
+  }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParserConstants.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParserConstants.java
new file mode 100644
index 0000000..b256848
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParserConstants.java
@@ -0,0 +1,438 @@
+/* Generated By:JavaCC: Do not edit this line. ASTParserConstants.java */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+
+/**
+ * Token literal values and constants.
+ * Generated by org.javacc.parser.OtherFilesGen#start()
+ */
+public interface ASTParserConstants {
+
+  /** End of File. */
+  int EOF = 0;
+  /** RegularExpression Id. */
+  int SINGLE_LINE_COMMENT = 31;
+  /** RegularExpression Id. */
+  int JAVA_DOC_COMMENT = 34;
+  /** RegularExpression Id. */
+  int MULTI_LINE_COMMENT = 35;
+  /** RegularExpression Id. */
+  int ABSTRACT = 37;
+  /** RegularExpression Id. */
+  int ASSERT = 38;
+  /** RegularExpression Id. */
+  int BOOLEAN = 39;
+  /** RegularExpression Id. */
+  int BREAK = 40;
+  /** RegularExpression Id. */
+  int BYTE = 41;
+  /** RegularExpression Id. */
+  int CASE = 42;
+  /** RegularExpression Id. */
+  int CATCH = 43;
+  /** RegularExpression Id. */
+  int CHAR = 44;
+  /** RegularExpression Id. */
+  int CLASS = 45;
+  /** RegularExpression Id. */
+  int CONST = 46;
+  /** RegularExpression Id. */
+  int CONTINUE = 47;
+  /** RegularExpression Id. */
+  int _DEFAULT = 48;
+  /** RegularExpression Id. */
+  int DO = 49;
+  /** RegularExpression Id. */
+  int DOUBLE = 50;
+  /** RegularExpression Id. */
+  int ELSE = 51;
+  /** RegularExpression Id. */
+  int ENUM = 52;
+  /** RegularExpression Id. */
+  int EXTENDS = 53;
+  /** RegularExpression Id. */
+  int FALSE = 54;
+  /** RegularExpression Id. */
+  int FINAL = 55;
+  /** RegularExpression Id. */
+  int FINALLY = 56;
+  /** RegularExpression Id. */
+  int FLOAT = 57;
+  /** RegularExpression Id. */
+  int FOR = 58;
+  /** RegularExpression Id. */
+  int GOTO = 59;
+  /** RegularExpression Id. */
+  int IF = 60;
+  /** RegularExpression Id. */
+  int IMPLEMENTS = 61;
+  /** RegularExpression Id. */
+  int IMPORT = 62;
+  /** RegularExpression Id. */
+  int INSTANCEOF = 63;
+  /** RegularExpression Id. */
+  int INT = 64;
+  /** RegularExpression Id. */
+  int INTERFACE = 65;
+  /** RegularExpression Id. */
+  int LONG = 66;
+  /** RegularExpression Id. */
+  int NATIVE = 67;
+  /** RegularExpression Id. */
+  int NEW = 68;
+  /** RegularExpression Id. */
+  int NULL = 69;
+  /** RegularExpression Id. */
+  int PACKAGE = 70;
+  /** RegularExpression Id. */
+  int PRIVATE = 71;
+  /** RegularExpression Id. */
+  int PROTECTED = 72;
+  /** RegularExpression Id. */
+  int PUBLIC = 73;
+  /** RegularExpression Id. */
+  int RETURN = 74;
+  /** RegularExpression Id. */
+  int SHORT = 75;
+  /** RegularExpression Id. */
+  int STATIC = 76;
+  /** RegularExpression Id. */
+  int STRICTFP = 77;
+  /** RegularExpression Id. */
+  int SUPER = 78;
+  /** RegularExpression Id. */
+  int SWITCH = 79;
+  /** RegularExpression Id. */
+  int SYNCHRONIZED = 80;
+  /** RegularExpression Id. */
+  int THIS = 81;
+  /** RegularExpression Id. */
+  int THROW = 82;
+  /** RegularExpression Id. */
+  int THROWS = 83;
+  /** RegularExpression Id. */
+  int TRANSIENT = 84;
+  /** RegularExpression Id. */
+  int TRUE = 85;
+  /** RegularExpression Id. */
+  int TRY = 86;
+  /** RegularExpression Id. */
+  int VOID = 87;
+  /** RegularExpression Id. */
+  int VOLATILE = 88;
+  /** RegularExpression Id. */
+  int WHILE = 89;
+  /** RegularExpression Id. */
+  int LONG_LITERAL = 90;
+  /** RegularExpression Id. */
+  int INTEGER_LITERAL = 91;
+  /** RegularExpression Id. */
+  int DECIMAL_LITERAL = 92;
+  /** RegularExpression Id. */
+  int HEX_LITERAL = 93;
+  /** RegularExpression Id. */
+  int OCTAL_LITERAL = 94;
+  /** RegularExpression Id. */
+  int BINARY_LITERAL = 95;
+  /** RegularExpression Id. */
+  int FLOATING_POINT_LITERAL = 96;
+  /** RegularExpression Id. */
+  int DECIMAL_FLOATING_POINT_LITERAL = 97;
+  /** RegularExpression Id. */
+  int DECIMAL_EXPONENT = 98;
+  /** RegularExpression Id. */
+  int HEXADECIMAL_FLOATING_POINT_LITERAL = 99;
+  /** RegularExpression Id. */
+  int HEXADECIMAL_EXPONENT = 100;
+  /** RegularExpression Id. */
+  int CHARACTER_LITERAL = 101;
+  /** RegularExpression Id. */
+  int STRING_LITERAL = 102;
+  /** RegularExpression Id. */
+  int IDENTIFIER = 103;
+  /** RegularExpression Id. */
+  int LETTER = 104;
+  /** RegularExpression Id. */
+  int PART_LETTER = 105;
+  /** RegularExpression Id. */
+  int LPAREN = 106;
+  /** RegularExpression Id. */
+  int RPAREN = 107;
+  /** RegularExpression Id. */
+  int LBRACE = 108;
+  /** RegularExpression Id. */
+  int RBRACE = 109;
+  /** RegularExpression Id. */
+  int LBRACKET = 110;
+  /** RegularExpression Id. */
+  int RBRACKET = 111;
+  /** RegularExpression Id. */
+  int SEMICOLON = 112;
+  /** RegularExpression Id. */
+  int COMMA = 113;
+  /** RegularExpression Id. */
+  int DOT = 114;
+  /** RegularExpression Id. */
+  int AT = 115;
+  /** RegularExpression Id. */
+  int ASSIGN = 116;
+  /** RegularExpression Id. */
+  int LT = 117;
+  /** RegularExpression Id. */
+  int BANG = 118;
+  /** RegularExpression Id. */
+  int TILDE = 119;
+  /** RegularExpression Id. */
+  int HOOK = 120;
+  /** RegularExpression Id. */
+  int COLON = 121;
+  /** RegularExpression Id. */
+  int EQ = 122;
+  /** RegularExpression Id. */
+  int LE = 123;
+  /** RegularExpression Id. */
+  int GE = 124;
+  /** RegularExpression Id. */
+  int NE = 125;
+  /** RegularExpression Id. */
+  int SC_OR = 126;
+  /** RegularExpression Id. */
+  int SC_AND = 127;
+  /** RegularExpression Id. */
+  int INCR = 128;
+  /** RegularExpression Id. */
+  int DECR = 129;
+  /** RegularExpression Id. */
+  int PLUS = 130;
+  /** RegularExpression Id. */
+  int MINUS = 131;
+  /** RegularExpression Id. */
+  int STAR = 132;
+  /** RegularExpression Id. */
+  int SLASH = 133;
+  /** RegularExpression Id. */
+  int BIT_AND = 134;
+  /** RegularExpression Id. */
+  int BIT_OR = 135;
+  /** RegularExpression Id. */
+  int XOR = 136;
+  /** RegularExpression Id. */
+  int REM = 137;
+  /** RegularExpression Id. */
+  int LSHIFT = 138;
+  /** RegularExpression Id. */
+  int PLUSASSIGN = 139;
+  /** RegularExpression Id. */
+  int MINUSASSIGN = 140;
+  /** RegularExpression Id. */
+  int STARASSIGN = 141;
+  /** RegularExpression Id. */
+  int SLASHASSIGN = 142;
+  /** RegularExpression Id. */
+  int ANDASSIGN = 143;
+  /** RegularExpression Id. */
+  int ORASSIGN = 144;
+  /** RegularExpression Id. */
+  int XORASSIGN = 145;
+  /** RegularExpression Id. */
+  int REMASSIGN = 146;
+  /** RegularExpression Id. */
+  int LSHIFTASSIGN = 147;
+  /** RegularExpression Id. */
+  int RSIGNEDSHIFTASSIGN = 148;
+  /** RegularExpression Id. */
+  int RUNSIGNEDSHIFTASSIGN = 149;
+  /** RegularExpression Id. */
+  int ELLIPSIS = 150;
+  /** RegularExpression Id. */
+  int ARROW = 151;
+  /** RegularExpression Id. */
+  int DOUBLECOLON = 152;
+  /** RegularExpression Id. */
+  int RUNSIGNEDSHIFT = 153;
+  /** RegularExpression Id. */
+  int RSIGNEDSHIFT = 154;
+  /** RegularExpression Id. */
+  int GT = 155;
+
+  /** Lexical state. */
+  int DEFAULT = 0;
+  /** Lexical state. */
+  int IN_JAVA_DOC_COMMENT = 1;
+  /** Lexical state. */
+  int IN_MULTI_LINE_COMMENT = 2;
+
+  /** Literal token values. */
+  String[] tokenImage = {
+    "<EOF>",
+    "\" \"",
+    "\"\\t\"",
+    "\"\\n\"",
+    "\"\\r\"",
+    "\"\\f\"",
+    "\"\\u0085\"",
+    "\"\\u00a0\"",
+    "\"\\u1680\"",
+    "\"\\u180e\"",
+    "\"\\u2000\"",
+    "\"\\u2001\"",
+    "\"\\u2002\"",
+    "\"\\u2003\"",
+    "\"\\u2004\"",
+    "\"\\u2005\"",
+    "\"\\u2006\"",
+    "\"\\u2007\"",
+    "\"\\u2008\"",
+    "\"\\u2009\"",
+    "\"\\u200a\"",
+    "\"\\u200b\"",
+    "\"\\u200c\"",
+    "\"\\u200d\"",
+    "\"\\u2028\"",
+    "\"\\u2029\"",
+    "\"\\u202f\"",
+    "\"\\u205f\"",
+    "\"\\u2060\"",
+    "\"\\u3000\"",
+    "\"\\ufeff\"",
+    "<SINGLE_LINE_COMMENT>",
+    "<token of kind 32>",
+    "\"/*\"",
+    "\"*/\"",
+    "\"*/\"",
+    "<token of kind 36>",
+    "\"abstract\"",
+    "\"assert\"",
+    "\"boolean\"",
+    "\"break\"",
+    "\"byte\"",
+    "\"case\"",
+    "\"catch\"",
+    "\"char\"",
+    "\"class\"",
+    "\"const\"",
+    "\"continue\"",
+    "\"default\"",
+    "\"do\"",
+    "\"double\"",
+    "\"else\"",
+    "\"enum\"",
+    "\"extends\"",
+    "\"false\"",
+    "\"final\"",
+    "\"finally\"",
+    "\"float\"",
+    "\"for\"",
+    "\"goto\"",
+    "\"if\"",
+    "\"implements\"",
+    "\"import\"",
+    "\"instanceof\"",
+    "\"int\"",
+    "\"interface\"",
+    "\"long\"",
+    "\"native\"",
+    "\"new\"",
+    "\"null\"",
+    "\"package\"",
+    "\"private\"",
+    "\"protected\"",
+    "\"public\"",
+    "\"return\"",
+    "\"short\"",
+    "\"static\"",
+    "\"strictfp\"",
+    "\"super\"",
+    "\"switch\"",
+    "\"synchronized\"",
+    "\"this\"",
+    "\"throw\"",
+    "\"throws\"",
+    "\"transient\"",
+    "\"true\"",
+    "\"try\"",
+    "\"void\"",
+    "\"volatile\"",
+    "\"while\"",
+    "<LONG_LITERAL>",
+    "<INTEGER_LITERAL>",
+    "<DECIMAL_LITERAL>",
+    "<HEX_LITERAL>",
+    "<OCTAL_LITERAL>",
+    "<BINARY_LITERAL>",
+    "<FLOATING_POINT_LITERAL>",
+    "<DECIMAL_FLOATING_POINT_LITERAL>",
+    "<DECIMAL_EXPONENT>",
+    "<HEXADECIMAL_FLOATING_POINT_LITERAL>",
+    "<HEXADECIMAL_EXPONENT>",
+    "<CHARACTER_LITERAL>",
+    "<STRING_LITERAL>",
+    "<IDENTIFIER>",
+    "<LETTER>",
+    "<PART_LETTER>",
+    "\"(\"",
+    "\")\"",
+    "\"{\"",
+    "\"}\"",
+    "\"[\"",
+    "\"]\"",
+    "\";\"",
+    "\",\"",
+    "\".\"",
+    "\"@\"",
+    "\"=\"",
+    "\"<\"",
+    "\"!\"",
+    "\"~\"",
+    "\"?\"",
+    "\":\"",
+    "\"==\"",
+    "\"<=\"",
+    "\">=\"",
+    "\"!=\"",
+    "\"||\"",
+    "\"&&\"",
+    "\"++\"",
+    "\"--\"",
+    "\"+\"",
+    "\"-\"",
+    "\"*\"",
+    "\"/\"",
+    "\"&\"",
+    "\"|\"",
+    "\"^\"",
+    "\"%\"",
+    "\"<<\"",
+    "\"+=\"",
+    "\"-=\"",
+    "\"*=\"",
+    "\"/=\"",
+    "\"&=\"",
+    "\"|=\"",
+    "\"^=\"",
+    "\"%=\"",
+    "\"<<=\"",
+    "\">>=\"",
+    "\">>>=\"",
+    "\"...\"",
+    "\"->\"",
+    "\"::\"",
+    "\">>>\"",
+    "\">>\"",
+    "\">\"",
+    "\"\\u001a\"",
+  };
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParserTokenManager.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParserTokenManager.java
new file mode 100644
index 0000000..fe6c0c6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ASTParserTokenManager.java
@@ -0,0 +1,2643 @@
+/* ASTParserTokenManager.java */
+/* Generated By:JavaCC: Do not edit this line. ASTParserTokenManager.java */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+import java.io.*;
+import java.util.*;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.utils.*;
+import static com.github.javaparser.ASTParser.*;
+import static com.github.javaparser.Range.*;
+import static com.github.javaparser.Position.*;
+import static com.github.javaparser.ast.type.ArrayType.*;
+
+/** Token Manager. */
+@SuppressWarnings("unused")public class ASTParserTokenManager implements ASTParserConstants {
+    private List<Token> tokens = new ArrayList<Token>();
+    private CommentsCollection commentsCollection = new CommentsCollection();
+
+    List<Token> getTokens() {
+        return tokens;
+    }
+
+    CommentsCollection getCommentsCollection() {
+        return commentsCollection;
+    }
+
+    private void CommonTokenAction(Token token) {
+        tokens.add(token);
+
+        while (token.specialToken != null) {
+            token = token.specialToken;
+            String commentText = token.image;
+            if (commentText.startsWith("/**")) {
+                JavadocComment comment = new JavadocComment(tokenRange(token), commentText.substring(3, commentText.length() - 2));
+                commentsCollection.addComment(comment);
+            } else if (commentText.startsWith("/*")) {
+                BlockComment comment = new BlockComment(tokenRange(token), commentText.substring(2, commentText.length() - 2));
+                commentsCollection.addComment(comment);
+            } else if (commentText.startsWith("//")) {
+                // line comments have their end of line character(s) included, and we don't want that.
+                Range range = tokenRange(token);
+                while (commentText.endsWith("\r") || commentText.endsWith("\n")) {
+                    commentText = commentText.substring(0, commentText.length() - 1);
+                }
+                range = range.withEnd(pos(range.begin.line, range.begin.column + commentText.length()));
+                LineComment comment = new LineComment(tokenRange(token), commentText.substring(2));
+                commentsCollection.addComment(comment);
+            } else {
+                throw new AssertionError("Didn't expect to get here. Please file a bug report. [" + commentText + "]");
+            }
+        }
+    }
+
+  /** Debug output. */
+  public  java.io.PrintStream debugStream = System.out;
+  /** Set debug output. */
+  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1, long active2){
+   switch (pos)
+   {
+      case 0:
+         if ((active0 & 0xffffffe000000000L) != 0L || (active1 & 0x3ffffffL) != 0L)
+         {
+            jjmatchedKind = 103;
+            return 43;
+         }
+         if ((active0 & 0x200000000L) != 0L || (active2 & 0x4020L) != 0L)
+            return 45;
+         if ((active1 & 0x4000000000000L) != 0L || (active2 & 0x400000L) != 0L)
+            return 1;
+         return -1;
+      case 1:
+         if ((active0 & 0xeff9ffe000000000L) != 0L || (active1 & 0x3ffffffL) != 0L)
+         {
+            if (jjmatchedPos != 1)
+            {
+               jjmatchedKind = 103;
+               jjmatchedPos = 1;
+            }
+            return 43;
+         }
+         if ((active0 & 0x1006000000000000L) != 0L)
+            return 43;
+         if ((active0 & 0x200000000L) != 0L)
+            return 50;
+         return -1;
+      case 2:
+         if ((active0 & 0x400000000000000L) != 0L || (active1 & 0x400013L) != 0L)
+            return 43;
+         if ((active0 & 0xebfdffe000000000L) != 0L || (active1 & 0x3bfffecL) != 0L)
+         {
+            if (jjmatchedPos != 2)
+            {
+               jjmatchedKind = 103;
+               jjmatchedPos = 2;
+            }
+            return 43;
+         }
+         return -1;
+      case 3:
+         if ((active0 & 0xe3e5e9e000000000L) != 0L || (active1 & 0x31dffcaL) != 0L)
+         {
+            jjmatchedKind = 103;
+            jjmatchedPos = 3;
+            return 43;
+         }
+         if ((active0 & 0x818160000000000L) != 0L || (active1 & 0xa20024L) != 0L)
+            return 43;
+         return -1;
+      case 4:
+         if ((active0 & 0xe02580e000000000L) != 0L || (active1 & 0x111b7caL) != 0L)
+         {
+            if (jjmatchedPos != 4)
+            {
+               jjmatchedKind = 103;
+               jjmatchedPos = 4;
+            }
+            return 43;
+         }
+         if ((active0 & 0x3c0690000000000L) != 0L || (active1 & 0x20c4800L) != 0L)
+            return 43;
+         return -1;
+      case 5:
+         if ((active0 & 0x4004004000000000L) != 0L || (active1 & 0x89608L) != 0L)
+            return 43;
+         if ((active0 & 0xa12180a000000000L) != 0L || (active1 & 0x11121c2L) != 0L)
+         {
+            jjmatchedKind = 103;
+            jjmatchedPos = 5;
+            return 43;
+         }
+         return -1;
+      case 6:
+         if ((active0 & 0x121008000000000L) != 0L || (active1 & 0xc0L) != 0L)
+            return 43;
+         if ((active0 & 0xa000802000000000L) != 0L || (active1 & 0x1112102L) != 0L)
+         {
+            jjmatchedKind = 103;
+            jjmatchedPos = 6;
+            return 43;
+         }
+         return -1;
+      case 7:
+         if ((active0 & 0xa000000000000000L) != 0L || (active1 & 0x110102L) != 0L)
+         {
+            jjmatchedKind = 103;
+            jjmatchedPos = 7;
+            return 43;
+         }
+         if ((active0 & 0x802000000000L) != 0L || (active1 & 0x1002000L) != 0L)
+            return 43;
+         return -1;
+      case 8:
+         if ((active1 & 0x100102L) != 0L)
+            return 43;
+         if ((active0 & 0xa000000000000000L) != 0L || (active1 & 0x10000L) != 0L)
+         {
+            jjmatchedKind = 103;
+            jjmatchedPos = 8;
+            return 43;
+         }
+         return -1;
+      case 9:
+         if ((active0 & 0xa000000000000000L) != 0L)
+            return 43;
+         if ((active1 & 0x10000L) != 0L)
+         {
+            jjmatchedKind = 103;
+            jjmatchedPos = 9;
+            return 43;
+         }
+         return -1;
+      case 10:
+         if ((active1 & 0x10000L) != 0L)
+         {
+            jjmatchedKind = 103;
+            jjmatchedPos = 10;
+            return 43;
+         }
+         return -1;
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_0(int pos, long active0, long active1, long active2){
+   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1, active2), pos + 1);
+}
+private int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private int jjMoveStringLiteralDfa0_0(){
+   switch(curChar)
+   {
+      case 26:
+         return jjStopAtPos(0, 156);
+      case 33:
+         jjmatchedKind = 118;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000000000000L, 0x0L);
+      case 37:
+         jjmatchedKind = 137;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x0L, 0x40000L);
+      case 38:
+         jjmatchedKind = 134;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x8000000000000000L, 0x8000L);
+      case 40:
+         return jjStopAtPos(0, 106);
+      case 41:
+         return jjStopAtPos(0, 107);
+      case 42:
+         jjmatchedKind = 132;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x0L, 0x2000L);
+      case 43:
+         jjmatchedKind = 130;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x0L, 0x801L);
+      case 44:
+         return jjStopAtPos(0, 113);
+      case 45:
+         jjmatchedKind = 131;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x0L, 0x801002L);
+      case 46:
+         jjmatchedKind = 114;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x0L, 0x400000L);
+      case 47:
+         jjmatchedKind = 133;
+         return jjMoveStringLiteralDfa1_0(0x200000000L, 0x0L, 0x4000L);
+      case 58:
+         jjmatchedKind = 121;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x0L, 0x1000000L);
+      case 59:
+         return jjStopAtPos(0, 112);
+      case 60:
+         jjmatchedKind = 117;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x800000000000000L, 0x80400L);
+      case 61:
+         jjmatchedKind = 116;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x400000000000000L, 0x0L);
+      case 62:
+         jjmatchedKind = 155;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x1000000000000000L, 0x6300000L);
+      case 63:
+         return jjStopAtPos(0, 120);
+      case 64:
+         return jjStopAtPos(0, 115);
+      case 91:
+         return jjStopAtPos(0, 110);
+      case 93:
+         return jjStopAtPos(0, 111);
+      case 94:
+         jjmatchedKind = 136;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x0L, 0x20000L);
+      case 97:
+         return jjMoveStringLiteralDfa1_0(0x6000000000L, 0x0L, 0x0L);
+      case 98:
+         return jjMoveStringLiteralDfa1_0(0x38000000000L, 0x0L, 0x0L);
+      case 99:
+         return jjMoveStringLiteralDfa1_0(0xfc0000000000L, 0x0L, 0x0L);
+      case 100:
+         return jjMoveStringLiteralDfa1_0(0x7000000000000L, 0x0L, 0x0L);
+      case 101:
+         return jjMoveStringLiteralDfa1_0(0x38000000000000L, 0x0L, 0x0L);
+      case 102:
+         return jjMoveStringLiteralDfa1_0(0x7c0000000000000L, 0x0L, 0x0L);
+      case 103:
+         return jjMoveStringLiteralDfa1_0(0x800000000000000L, 0x0L, 0x0L);
+      case 105:
+         return jjMoveStringLiteralDfa1_0(0xf000000000000000L, 0x3L, 0x0L);
+      case 108:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x4L, 0x0L);
+      case 110:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x38L, 0x0L);
+      case 112:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x3c0L, 0x0L);
+      case 114:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x400L, 0x0L);
+      case 115:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x1f800L, 0x0L);
+      case 116:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x7e0000L, 0x0L);
+      case 118:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x1800000L, 0x0L);
+      case 119:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000L, 0x0L);
+      case 123:
+         return jjStopAtPos(0, 108);
+      case 124:
+         jjmatchedKind = 135;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x4000000000000000L, 0x10000L);
+      case 125:
+         return jjStopAtPos(0, 109);
+      case 126:
+         return jjStopAtPos(0, 119);
+      case 133:
+         return jjStopAtPos(0, 6);
+      case 160:
+         return jjStopAtPos(0, 7);
+      case 5760:
+         return jjStopAtPos(0, 8);
+      case 6158:
+         return jjStopAtPos(0, 9);
+      case 8192:
+         return jjStopAtPos(0, 10);
+      case 8193:
+         return jjStopAtPos(0, 11);
+      case 8194:
+         return jjStopAtPos(0, 12);
+      case 8195:
+         return jjStopAtPos(0, 13);
+      case 8196:
+         return jjStopAtPos(0, 14);
+      case 8197:
+         return jjStopAtPos(0, 15);
+      case 8198:
+         return jjStopAtPos(0, 16);
+      case 8199:
+         return jjStopAtPos(0, 17);
+      case 8200:
+         return jjStopAtPos(0, 18);
+      case 8201:
+         return jjStopAtPos(0, 19);
+      case 8202:
+         return jjStopAtPos(0, 20);
+      case 8203:
+         return jjStopAtPos(0, 21);
+      case 8204:
+         return jjStopAtPos(0, 22);
+      case 8205:
+         return jjStopAtPos(0, 23);
+      case 8232:
+         return jjStopAtPos(0, 24);
+      case 8233:
+         return jjStopAtPos(0, 25);
+      case 8239:
+         return jjStopAtPos(0, 26);
+      case 8287:
+         return jjStopAtPos(0, 27);
+      case 8288:
+         return jjStopAtPos(0, 28);
+      case 12288:
+         return jjStopAtPos(0, 29);
+      case 65279:
+         return jjStopAtPos(0, 30);
+      default :
+         return jjMoveNfa_0(0, 0);
+   }
+}
+private int jjMoveStringLiteralDfa1_0(long active0, long active1, long active2){
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(0, active0, active1, active2);
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 38:
+         if ((active1 & 0x8000000000000000L) != 0L)
+            return jjStopAtPos(1, 127);
+         break;
+      case 42:
+         if ((active0 & 0x200000000L) != 0L)
+            return jjStartNfaWithStates_0(1, 33, 50);
+         break;
+      case 43:
+         if ((active2 & 0x1L) != 0L)
+            return jjStopAtPos(1, 128);
+         break;
+      case 45:
+         if ((active2 & 0x2L) != 0L)
+            return jjStopAtPos(1, 129);
+         break;
+      case 46:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0L, active2, 0x400000L);
+      case 58:
+         if ((active2 & 0x1000000L) != 0L)
+            return jjStopAtPos(1, 152);
+         break;
+      case 60:
+         if ((active2 & 0x400L) != 0L)
+         {
+            jjmatchedKind = 138;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0L, active2, 0x80000L);
+      case 61:
+         if ((active1 & 0x400000000000000L) != 0L)
+            return jjStopAtPos(1, 122);
+         else if ((active1 & 0x800000000000000L) != 0L)
+            return jjStopAtPos(1, 123);
+         else if ((active1 & 0x1000000000000000L) != 0L)
+            return jjStopAtPos(1, 124);
+         else if ((active1 & 0x2000000000000000L) != 0L)
+            return jjStopAtPos(1, 125);
+         else if ((active2 & 0x800L) != 0L)
+            return jjStopAtPos(1, 139);
+         else if ((active2 & 0x1000L) != 0L)
+            return jjStopAtPos(1, 140);
+         else if ((active2 & 0x2000L) != 0L)
+            return jjStopAtPos(1, 141);
+         else if ((active2 & 0x4000L) != 0L)
+            return jjStopAtPos(1, 142);
+         else if ((active2 & 0x8000L) != 0L)
+            return jjStopAtPos(1, 143);
+         else if ((active2 & 0x10000L) != 0L)
+            return jjStopAtPos(1, 144);
+         else if ((active2 & 0x20000L) != 0L)
+            return jjStopAtPos(1, 145);
+         else if ((active2 & 0x40000L) != 0L)
+            return jjStopAtPos(1, 146);
+         break;
+      case 62:
+         if ((active2 & 0x800000L) != 0L)
+            return jjStopAtPos(1, 151);
+         else if ((active2 & 0x4000000L) != 0L)
+         {
+            jjmatchedKind = 154;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0L, active2, 0x2300000L);
+      case 97:
+         return jjMoveStringLiteralDfa2_0(active0, 0x400c0000000000L, active1, 0x48L, active2, 0L);
+      case 98:
+         return jjMoveStringLiteralDfa2_0(active0, 0x2000000000L, active1, 0L, active2, 0L);
+      case 101:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1000000000000L, active1, 0x410L, active2, 0L);
+      case 102:
+         if ((active0 & 0x1000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(1, 60, 43);
+         break;
+      case 104:
+         return jjMoveStringLiteralDfa2_0(active0, 0x100000000000L, active1, 0x20e0800L, active2, 0L);
+      case 105:
+         return jjMoveStringLiteralDfa2_0(active0, 0x180000000000000L, active1, 0L, active2, 0L);
+      case 108:
+         return jjMoveStringLiteralDfa2_0(active0, 0x208200000000000L, active1, 0L, active2, 0L);
+      case 109:
+         return jjMoveStringLiteralDfa2_0(active0, 0x6000000000000000L, active1, 0L, active2, 0L);
+      case 110:
+         return jjMoveStringLiteralDfa2_0(active0, 0x8010000000000000L, active1, 0x3L, active2, 0L);
+      case 111:
+         if ((active0 & 0x2000000000000L) != 0L)
+         {
+            jjmatchedKind = 49;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0xc04c08000000000L, active1, 0x1800004L, active2, 0L);
+      case 114:
+         return jjMoveStringLiteralDfa2_0(active0, 0x10000000000L, active1, 0x700180L, active2, 0L);
+      case 115:
+         return jjMoveStringLiteralDfa2_0(active0, 0x4000000000L, active1, 0L, active2, 0L);
+      case 116:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x3000L, active2, 0L);
+      case 117:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x4220L, active2, 0L);
+      case 119:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x8000L, active2, 0L);
+      case 120:
+         return jjMoveStringLiteralDfa2_0(active0, 0x20000000000000L, active1, 0L, active2, 0L);
+      case 121:
+         return jjMoveStringLiteralDfa2_0(active0, 0x20000000000L, active1, 0x10000L, active2, 0L);
+      case 124:
+         if ((active1 & 0x4000000000000000L) != 0L)
+            return jjStopAtPos(1, 126);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(0, active0, active1, active2);
+}
+private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1, long old2, long active2){
+   if (((active0 &= old0) | (active1 &= old1) | (active2 &= old2)) == 0L)
+      return jjStartNfa_0(0, old0, old1, old2);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(1, active0, active1, active2);
+      return 2;
+   }
+   switch(curChar)
+   {
+      case 46:
+         if ((active2 & 0x400000L) != 0L)
+            return jjStopAtPos(2, 150);
+         break;
+      case 61:
+         if ((active2 & 0x80000L) != 0L)
+            return jjStopAtPos(2, 147);
+         else if ((active2 & 0x100000L) != 0L)
+            return jjStopAtPos(2, 148);
+         break;
+      case 62:
+         if ((active2 & 0x2000000L) != 0L)
+         {
+            jjmatchedKind = 153;
+            jjmatchedPos = 2;
+         }
+         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0L, active2, 0x200000L);
+      case 97:
+         return jjMoveStringLiteralDfa3_0(active0, 0x300000000000L, active1, 0x101000L, active2, 0L);
+      case 98:
+         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x200L, active2, 0L);
+      case 99:
+         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x40L, active2, 0L);
+      case 101:
+         return jjMoveStringLiteralDfa3_0(active0, 0x10000000000L, active1, 0L, active2, 0L);
+      case 102:
+         return jjMoveStringLiteralDfa3_0(active0, 0x1000000000000L, active1, 0L, active2, 0L);
+      case 105:
+         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x2828080L, active2, 0L);
+      case 108:
+         return jjMoveStringLiteralDfa3_0(active0, 0x40000000000000L, active1, 0x1000020L, active2, 0L);
+      case 110:
+         return jjMoveStringLiteralDfa3_0(active0, 0x180c00000000000L, active1, 0x10004L, active2, 0L);
+      case 111:
+         return jjMoveStringLiteralDfa3_0(active0, 0x200008000000000L, active1, 0x900L, active2, 0L);
+      case 112:
+         return jjMoveStringLiteralDfa3_0(active0, 0x6000000000000000L, active1, 0x4000L, active2, 0L);
+      case 114:
+         if ((active0 & 0x400000000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 58, 43);
+         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0xc2000L, active2, 0L);
+      case 115:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8008046000000000L, active1, 0L, active2, 0L);
+      case 116:
+         if ((active1 & 0x1L) != 0L)
+         {
+            jjmatchedKind = 64;
+            jjmatchedPos = 2;
+         }
+         return jjMoveStringLiteralDfa3_0(active0, 0x8200a0000000000L, active1, 0x40aL, active2, 0L);
+      case 117:
+         return jjMoveStringLiteralDfa3_0(active0, 0x14000000000000L, active1, 0x200000L, active2, 0L);
+      case 119:
+         if ((active1 & 0x10L) != 0L)
+            return jjStartNfaWithStates_0(2, 68, 43);
+         break;
+      case 121:
+         if ((active1 & 0x400000L) != 0L)
+            return jjStartNfaWithStates_0(2, 86, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(1, active0, active1, active2);
+}
+private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1, long old2, long active2){
+   if (((active0 &= old0) | (active1 &= old1) | (active2 &= old2)) == 0L)
+      return jjStartNfa_0(1, old0, old1, old2);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(2, active0, active1, active2);
+      return 3;
+   }
+   switch(curChar)
+   {
+      case 61:
+         if ((active2 & 0x200000L) != 0L)
+            return jjStopAtPos(3, 149);
+         break;
+      case 97:
+         return jjMoveStringLiteralDfa4_0(active0, 0x381010000000000L, active1, 0x1000000L, active2, 0L);
+      case 98:
+         return jjMoveStringLiteralDfa4_0(active0, 0x4000000000000L, active1, 0L, active2, 0L);
+      case 99:
+         return jjMoveStringLiteralDfa4_0(active0, 0x80000000000L, active1, 0x10000L, active2, 0L);
+      case 100:
+         if ((active1 & 0x800000L) != 0L)
+            return jjStartNfaWithStates_0(3, 87, 43);
+         break;
+      case 101:
+         if ((active0 & 0x20000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 41, 43);
+         else if ((active0 & 0x40000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 42, 43);
+         else if ((active0 & 0x8000000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 51, 43);
+         else if ((active1 & 0x200000L) != 0L)
+            return jjStartNfaWithStates_0(3, 85, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x20004000000000L, active1, 0x4002L, active2, 0L);
+      case 103:
+         if ((active1 & 0x4L) != 0L)
+            return jjStartNfaWithStates_0(3, 66, 43);
+         break;
+      case 105:
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x2008L, active2, 0L);
+      case 107:
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x40L, active2, 0L);
+      case 108:
+         if ((active1 & 0x20L) != 0L)
+            return jjStartNfaWithStates_0(3, 69, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x2000008000000000L, active1, 0x2000200L, active2, 0L);
+      case 109:
+         if ((active0 & 0x10000000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 52, 43);
+         break;
+      case 110:
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x100000L, active2, 0L);
+      case 111:
+         if ((active0 & 0x800000000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 59, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x4000000000000000L, active1, 0xc0000L, active2, 0L);
+      case 114:
+         if ((active0 & 0x100000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 44, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x800L, active2, 0L);
+      case 115:
+         if ((active1 & 0x20000L) != 0L)
+            return jjStartNfaWithStates_0(3, 81, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x40600000000000L, active1, 0L, active2, 0L);
+      case 116:
+         return jjMoveStringLiteralDfa4_0(active0, 0x8000802000000000L, active1, 0x9100L, active2, 0L);
+      case 117:
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x400L, active2, 0L);
+      case 118:
+         return jjMoveStringLiteralDfa4_0(active0, 0L, active1, 0x80L, active2, 0L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(2, active0, active1, active2);
+}
+private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1, long old2, long active2){
+   if (((active0 &= old0) | (active1 &= old1) | (active2 &= old2)) == 0L)
+      return jjStartNfa_0(2, old0, old1, old2);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(3, active0, active1, 0L);
+      return 4;
+   }
+   switch(curChar)
+   {
+      case 97:
+         return jjMoveStringLiteralDfa5_0(active0, 0x8000000000000000L, active1, 0xc0L);
+      case 99:
+         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0xa000L);
+      case 101:
+         if ((active0 & 0x40000000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 54, 43);
+         else if ((active1 & 0x2000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 89, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0x2000008000000000L, active1, 0x100L);
+      case 104:
+         if ((active0 & 0x80000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 43, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x10000L);
+      case 105:
+         return jjMoveStringLiteralDfa5_0(active0, 0x800000000000L, active1, 0x1200L);
+      case 107:
+         if ((active0 & 0x10000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 40, 43);
+         break;
+      case 108:
+         if ((active0 & 0x80000000000000L) != 0L)
+         {
+            jjmatchedKind = 55;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x104000000000000L, active1, 0L);
+      case 110:
+         return jjMoveStringLiteralDfa5_0(active0, 0x20000000000000L, active1, 0L);
+      case 114:
+         if ((active1 & 0x4000L) != 0L)
+            return jjStartNfaWithStates_0(4, 78, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0x4000006000000000L, active1, 0x402L);
+      case 115:
+         if ((active0 & 0x200000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 45, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x100000L);
+      case 116:
+         if ((active0 & 0x400000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 46, 43);
+         else if ((active0 & 0x200000000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 57, 43);
+         else if ((active1 & 0x800L) != 0L)
+            return jjStartNfaWithStates_0(4, 75, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x1000000L);
+      case 117:
+         return jjMoveStringLiteralDfa5_0(active0, 0x1000000000000L, active1, 0L);
+      case 118:
+         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x8L);
+      case 119:
+         if ((active1 & 0x40000L) != 0L)
+         {
+            jjmatchedKind = 82;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0L, active1, 0x80000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(3, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1){
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(3, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(4, active0, active1, 0L);
+      return 5;
+   }
+   switch(curChar)
+   {
+      case 97:
+         return jjMoveStringLiteralDfa6_0(active0, 0xa000000000L, active1, 0L);
+      case 99:
+         if ((active1 & 0x200L) != 0L)
+            return jjStartNfaWithStates_0(5, 73, 43);
+         else if ((active1 & 0x1000L) != 0L)
+            return jjStartNfaWithStates_0(5, 76, 43);
+         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x100L);
+      case 100:
+         return jjMoveStringLiteralDfa6_0(active0, 0x20000000000000L, active1, 0L);
+      case 101:
+         if ((active0 & 0x4000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 50, 43);
+         else if ((active1 & 0x8L) != 0L)
+            return jjStartNfaWithStates_0(5, 67, 43);
+         break;
+      case 102:
+         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x2L);
+      case 103:
+         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x40L);
+      case 104:
+         if ((active1 & 0x8000L) != 0L)
+            return jjStartNfaWithStates_0(5, 79, 43);
+         break;
+      case 105:
+         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x1100000L);
+      case 108:
+         return jjMoveStringLiteralDfa6_0(active0, 0x101000000000000L, active1, 0L);
+      case 109:
+         return jjMoveStringLiteralDfa6_0(active0, 0x2000000000000000L, active1, 0L);
+      case 110:
+         if ((active1 & 0x400L) != 0L)
+            return jjStartNfaWithStates_0(5, 74, 43);
+         return jjMoveStringLiteralDfa6_0(active0, 0x8000800000000000L, active1, 0L);
+      case 114:
+         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x10000L);
+      case 115:
+         if ((active1 & 0x80000L) != 0L)
+            return jjStartNfaWithStates_0(5, 83, 43);
+         break;
+      case 116:
+         if ((active0 & 0x4000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 38, 43);
+         else if ((active0 & 0x4000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 62, 43);
+         return jjMoveStringLiteralDfa6_0(active0, 0L, active1, 0x2080L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(4, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa6_0(long old0, long active0, long old1, long active1){
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(4, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(5, active0, active1, 0L);
+      return 6;
+   }
+   switch(curChar)
+   {
+      case 97:
+         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x2L);
+      case 99:
+         return jjMoveStringLiteralDfa7_0(active0, 0x8000002000000000L, active1, 0L);
+      case 101:
+         if ((active1 & 0x40L) != 0L)
+            return jjStartNfaWithStates_0(6, 70, 43);
+         else if ((active1 & 0x80L) != 0L)
+            return jjStartNfaWithStates_0(6, 71, 43);
+         return jjMoveStringLiteralDfa7_0(active0, 0x2000000000000000L, active1, 0x100000L);
+      case 102:
+         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x2000L);
+      case 108:
+         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x1000000L);
+      case 110:
+         if ((active0 & 0x8000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 39, 43);
+         break;
+      case 111:
+         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x10000L);
+      case 115:
+         if ((active0 & 0x20000000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 53, 43);
+         break;
+      case 116:
+         if ((active0 & 0x1000000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 48, 43);
+         return jjMoveStringLiteralDfa7_0(active0, 0L, active1, 0x100L);
+      case 117:
+         return jjMoveStringLiteralDfa7_0(active0, 0x800000000000L, active1, 0L);
+      case 121:
+         if ((active0 & 0x100000000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 56, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(5, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa7_0(long old0, long active0, long old1, long active1){
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(5, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(6, active0, active1, 0L);
+      return 7;
+   }
+   switch(curChar)
+   {
+      case 99:
+         return jjMoveStringLiteralDfa8_0(active0, 0L, active1, 0x2L);
+      case 101:
+         if ((active0 & 0x800000000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 47, 43);
+         else if ((active1 & 0x1000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 88, 43);
+         return jjMoveStringLiteralDfa8_0(active0, 0x8000000000000000L, active1, 0x100L);
+      case 110:
+         return jjMoveStringLiteralDfa8_0(active0, 0x2000000000000000L, active1, 0x110000L);
+      case 112:
+         if ((active1 & 0x2000L) != 0L)
+            return jjStartNfaWithStates_0(7, 77, 43);
+         break;
+      case 116:
+         if ((active0 & 0x2000000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 37, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(6, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa8_0(long old0, long active0, long old1, long active1){
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(6, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(7, active0, active1, 0L);
+      return 8;
+   }
+   switch(curChar)
+   {
+      case 100:
+         if ((active1 & 0x100L) != 0L)
+            return jjStartNfaWithStates_0(8, 72, 43);
+         break;
+      case 101:
+         if ((active1 & 0x2L) != 0L)
+            return jjStartNfaWithStates_0(8, 65, 43);
+         break;
+      case 105:
+         return jjMoveStringLiteralDfa9_0(active0, 0L, active1, 0x10000L);
+      case 111:
+         return jjMoveStringLiteralDfa9_0(active0, 0x8000000000000000L, active1, 0L);
+      case 116:
+         if ((active1 & 0x100000L) != 0L)
+            return jjStartNfaWithStates_0(8, 84, 43);
+         return jjMoveStringLiteralDfa9_0(active0, 0x2000000000000000L, active1, 0L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(7, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa9_0(long old0, long active0, long old1, long active1){
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(7, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(8, active0, active1, 0L);
+      return 9;
+   }
+   switch(curChar)
+   {
+      case 102:
+         if ((active0 & 0x8000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(9, 63, 43);
+         break;
+      case 115:
+         if ((active0 & 0x2000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(9, 61, 43);
+         break;
+      case 122:
+         return jjMoveStringLiteralDfa10_0(active0, 0L, active1, 0x10000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(8, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa10_0(long old0, long active0, long old1, long active1){
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(8, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(9, 0L, active1, 0L);
+      return 10;
+   }
+   switch(curChar)
+   {
+      case 101:
+         return jjMoveStringLiteralDfa11_0(active1, 0x10000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(9, 0L, active1, 0L);
+}
+private int jjMoveStringLiteralDfa11_0(long old1, long active1){
+   if (((active1 &= old1)) == 0L)
+      return jjStartNfa_0(9, 0L, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(10, 0L, active1, 0L);
+      return 11;
+   }
+   switch(curChar)
+   {
+      case 100:
+         if ((active1 & 0x10000L) != 0L)
+            return jjStartNfaWithStates_0(11, 80, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(10, 0L, active1, 0L);
+}
+private int jjStartNfaWithStates_0(int pos, int kind, int state)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) { return pos + 1; }
+   return jjMoveNfa_0(state, pos + 1);
+}
+static final long[] jjbitVec0 = {
+   0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec2 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec3 = {
+   0xfff0000000200002L, 0xffffffffffffdfffL, 0xfffff00f7fffffffL, 0x12000000007fffffL
+};
+static final long[] jjbitVec4 = {
+   0x0L, 0x0L, 0x420043c00000000L, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec5 = {
+   0x7fffffffffffffL, 0xffffffffffff0000L, 0xffffffffffffffffL, 0x401f0003ffc3L
+};
+static final long[] jjbitVec6 = {
+   0x0L, 0x400000000000000L, 0xfffffffbffffd740L, 0xfbfffffffff7fffL
+};
+static final long[] jjbitVec7 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffffffc03L, 0x33fffffffff7fffL
+};
+static final long[] jjbitVec8 = {
+   0xfffe00000000ffffL, 0xfffffffe027fffffL, 0xffL, 0x707ffffff0000L
+};
+static final long[] jjbitVec9 = {
+   0x7fffffe00000000L, 0xfffec000000007ffL, 0xffffffffffffffffL, 0x9c00c060002fffffL
+};
+static final long[] jjbitVec10 = {
+   0xfffffffd0000L, 0xe000L, 0x2003fffffffffL, 0x0L
+};
+static final long[] jjbitVec11 = {
+   0x23fffffffffffff0L, 0x3ff010000L, 0x23c5fdfffff99fe0L, 0xf0003b0000000L
+};
+static final long[] jjbitVec12 = {
+   0x36dfdfffff987e0L, 0x1c00005e000000L, 0x23edfdfffffbbfe0L, 0x2000300010000L
+};
+static final long[] jjbitVec13 = {
+   0x23edfdfffff99fe0L, 0x20003b0000000L, 0x3bfc718d63dc7e8L, 0x200000000000000L
+};
+static final long[] jjbitVec14 = {
+   0x3effdfffffddfe0L, 0x300000000L, 0x23effdfffffddfe0L, 0x340000000L
+};
+static final long[] jjbitVec15 = {
+   0x3fffdfffffddfe0L, 0x300000000L, 0x2ffbfffffc7fffe0L, 0x7fL
+};
+static final long[] jjbitVec16 = {
+   0x800dfffffffffffeL, 0x7fL, 0x200decaefef02596L, 0x3000005fL
+};
+static final long[] jjbitVec17 = {
+   0x1L, 0x7fffffffeffL, 0xf00L, 0x0L
+};
+static final long[] jjbitVec18 = {
+   0x6fbffffffffL, 0x3f0000L, 0xffffffff00000000L, 0x1ffffffffff003fL
+};
+static final long[] jjbitVec19 = {
+   0xffffffffffffffffL, 0xffffffff83ffffffL, 0xffffff07ffffffffL, 0x3ffffffffffffffL
+};
+static final long[] jjbitVec20 = {
+   0xffffffffffffff7fL, 0xffffffff3d7f3d7fL, 0x7f3d7fffffff3d7fL, 0xffff7fffff7f7f3dL
+};
+static final long[] jjbitVec21 = {
+   0xffffffff7f3d7fffL, 0x7ffff7fL, 0xffffffff00000000L, 0x1fffffffffffffL
+};
+static final long[] jjbitVec22 = {
+   0xffffffffffffffffL, 0x7f9fffffffffffL, 0xffffffff07fffffeL, 0x1c7ffffffffffL
+};
+static final long[] jjbitVec23 = {
+   0x3ffff0003dfffL, 0x1dfff0003ffffL, 0xfffffffffffffL, 0x18800000L
+};
+static final long[] jjbitVec24 = {
+   0xffffffff00000000L, 0xffffffffffffffL, 0x1ffffffffffL, 0x0L
+};
+static final long[] jjbitVec25 = {
+   0x1fffffffL, 0x1f3fffffff0000L, 0x0L, 0x0L
+};
+static final long[] jjbitVec26 = {
+   0xffffffffffffffffL, 0xfffffffffffL, 0x0L, 0x0L
+};
+static final long[] jjbitVec27 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffff0fffffffL, 0x3ffffffffffffffL
+};
+static final long[] jjbitVec28 = {
+   0xffffffff3f3fffffL, 0x3fffffffaaff3f3fL, 0x5fdfffffffffffffL, 0x1fdc1fff0fcf1fdcL
+};
+static final long[] jjbitVec29 = {
+   0x8000000000000000L, 0x8002000000100001L, 0x3ffff00000000L, 0x0L
+};
+static final long[] jjbitVec30 = {
+   0xe3fbbd503e2ffc84L, 0xffffffff000003e0L, 0xfL, 0x0L
+};
+static final long[] jjbitVec31 = {
+   0x1f3e03fe000000e0L, 0xfffffffffffffffeL, 0xfffffffee07fffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec32 = {
+   0xfffe1fffffffffe0L, 0xffffffffffffffffL, 0xffffff00007fffL, 0xffff000000000000L
+};
+static final long[] jjbitVec33 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffffffL, 0x0L
+};
+static final long[] jjbitVec34 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffL, 0x0L
+};
+static final long[] jjbitVec35 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0x1fffL, 0x0L
+};
+static final long[] jjbitVec36 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffL, 0x0L
+};
+static final long[] jjbitVec37 = {
+   0x6L, 0x0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec38 = {
+   0xffff3fffffffffffL, 0x7ffffffffffL, 0x0L, 0x0L
+};
+static final long[] jjbitVec39 = {
+   0x5f7ffdffa0f8007fL, 0xffffffffffffffdbL, 0x3ffffffffffffL, 0xfffffffffff80000L
+};
+static final long[] jjbitVec40 = {
+   0x3fffffffffffffffL, 0xffffffffffff0000L, 0xfffffffffffcffffL, 0x1fff0000000000ffL
+};
+static final long[] jjbitVec41 = {
+   0x18000000000000L, 0xffdf02000000e000L, 0xffffffffffffffffL, 0x1fffffffffffffffL
+};
+static final long[] jjbitVec42 = {
+   0x87fffffe00000010L, 0xffffffe007fffffeL, 0x7fffffffffffffffL, 0x631cfcfcfcL
+};
+static final long[] jjbitVec43 = {
+   0x0L, 0x0L, 0x420243cffffffffL, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec44 = {
+   0xffffffffffffffffL, 0x400ffffe0ffffffL, 0xfffffffbffffd740L, 0xfbfffffffff7fffL
+};
+static final long[] jjbitVec45 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffffffc7bL, 0x33fffffffff7fffL
+};
+static final long[] jjbitVec46 = {
+   0xfffe00000000ffffL, 0xfffffffe027fffffL, 0xbbfffffbfffe00ffL, 0x707ffffff0016L
+};
+static final long[] jjbitVec47 = {
+   0x7fffffe003f000fL, 0xffffc3ff01ffffffL, 0xffffffffffffffffL, 0x9ffffdffbfefffffL
+};
+static final long[] jjbitVec48 = {
+   0xffffffffffff8000L, 0xe7ffL, 0x3ffffffffffffL, 0x0L
+};
+static final long[] jjbitVec49 = {
+   0xf3fffffffffffffeL, 0xffcfff1f3fffL, 0xf3c5fdfffff99feeL, 0xfffcfb080399fL
+};
+static final long[] jjbitVec50 = {
+   0xd36dfdfffff987eeL, 0x1fffc05e003987L, 0xf3edfdfffffbbfeeL, 0x2ffcf00013bbfL
+};
+static final long[] jjbitVec51 = {
+   0xf3edfdfffff99feeL, 0x2ffc3b0c0398fL, 0xc3bfc718d63dc7ecL, 0x200ff8000803dc7L
+};
+static final long[] jjbitVec52 = {
+   0xc3effdfffffddfeeL, 0xffc300603ddfL, 0xf3effdfffffddfecL, 0xffc340603ddfL
+};
+static final long[] jjbitVec53 = {
+   0xc3fffdfffffddfecL, 0xffc300803dcfL, 0x2ffbfffffc7fffecL, 0xc0000ff5f847fL
+};
+static final long[] jjbitVec54 = {
+   0x87fffffffffffffeL, 0x3ff7fffL, 0x3bffecaefef02596L, 0x33ff3f5fL
+};
+static final long[] jjbitVec55 = {
+   0xc2a003ff03000001L, 0xfffe07fffffffeffL, 0x1ffffffffeff0fdfL, 0x40L
+};
+static final long[] jjbitVec56 = {
+   0x3c7f6fbffffffffL, 0x3ff03ffL, 0xffffffff00000000L, 0x1ffffffffff003fL
+};
+static final long[] jjbitVec57 = {
+   0xffffffff7f3d7fffL, 0x3fe0007ffff7fL, 0xffffffff00000000L, 0x1fffffffffffffL
+};
+static final long[] jjbitVec58 = {
+   0x1fffff001fdfffL, 0xddfff000fffffL, 0xffffffffffffffffL, 0x3ff388fffffL
+};
+static final long[] jjbitVec59 = {
+   0xffffffff03ff3800L, 0xffffffffffffffL, 0x3ffffffffffL, 0x0L
+};
+static final long[] jjbitVec60 = {
+   0xfff0fff1fffffffL, 0x1f3fffffffffc0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec61 = {
+   0x80007c000000f000L, 0x8002fc0f00100001L, 0x3ffff00000000L, 0x7e21fff0000L
+};
+static final long[] jjbitVec62 = {
+   0x1f3efffe000000e0L, 0xfffffffffffffffeL, 0xfffffffee67fffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec63 = {
+   0x10000000000006L, 0x0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec64 = {
+   0x3L, 0x0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec65 = {
+   0x0L, 0x800000000000000L, 0x0L, 0x0L
+};
+static final long[] jjbitVec66 = {
+   0x5f7ffdffe0f8007fL, 0xffffffffffffffdbL, 0x3ffffffffffffL, 0xfffffffffff80000L
+};
+static final long[] jjbitVec67 = {
+   0x18000f0000ffffL, 0xffdf02000000e000L, 0xffffffffffffffffL, 0x9fffffffffffffffL
+};
+static final long[] jjbitVec68 = {
+   0x87fffffe03ff0010L, 0xffffffe007fffffeL, 0x7fffffffffffffffL, 0xe0000631cfcfcfcL
+};
+private int jjMoveNfa_0(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 130;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 45:
+                  if (curChar == 42)
+                     jjstateSet[jjnewStateCnt++] = 50;
+                  else if (curChar == 47)
+                  {
+                     if (kind > 31)
+                        kind = 31;
+                     { jjCheckNAddStates(0, 2); }
+                  }
+                  break;
+               case 0:
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 91)
+                        kind = 91;
+                     { jjCheckNAddStates(3, 17); }
+                  }
+                  else if (curChar == 47)
+                     { jjAddStates(18, 19); }
+                  else if (curChar == 36)
+                  {
+                     if (kind > 103)
+                        kind = 103;
+                     { jjCheckNAdd(43); }
+                  }
+                  else if (curChar == 34)
+                     { jjCheckNAddStates(20, 23); }
+                  else if (curChar == 39)
+                     { jjAddStates(24, 26); }
+                  else if (curChar == 46)
+                     { jjCheckNAdd(1); }
+                  if (curChar == 48)
+                     { jjAddStates(27, 34); }
+                  break;
+               case 1:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(35, 38); }
+                  break;
+               case 2:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(2, 3); }
+                  break;
+               case 3:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(39, 41); }
+                  break;
+               case 5:
+                  if ((0x280000000000L & l) != 0L)
+                     { jjCheckNAdd(6); }
+                  break;
+               case 6:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(42, 44); }
+                  break;
+               case 7:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(7, 8); }
+                  break;
+               case 8:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddTwoStates(6, 9); }
+                  break;
+               case 10:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(45, 48); }
+                  break;
+               case 11:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(49, 53); }
+                  break;
+               case 12:
+                  if (curChar == 39)
+                     { jjAddStates(24, 26); }
+                  break;
+               case 13:
+                  if ((0xffffff7fffffdbffL & l) != 0L)
+                     { jjCheckNAdd(14); }
+                  break;
+               case 14:
+                  if (curChar == 39 && kind > 101)
+                     kind = 101;
+                  break;
+               case 16:
+                  if ((0x8400000000L & l) != 0L)
+                     { jjCheckNAdd(14); }
+                  break;
+               case 17:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(18, 14); }
+                  break;
+               case 18:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAdd(14); }
+                  break;
+               case 19:
+                  if ((0xf000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 20;
+                  break;
+               case 20:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAdd(18); }
+                  break;
+               case 22:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 23;
+                  break;
+               case 23:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 24;
+                  break;
+               case 24:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 25;
+                  break;
+               case 25:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAdd(14); }
+                  break;
+               case 27:
+                  if (curChar == 34)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 28:
+                  if ((0xfffffffbffffdbffL & l) != 0L)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 30:
+                  if ((0x8400000000L & l) != 0L)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 32:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 33;
+                  break;
+               case 33:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 34;
+                  break;
+               case 34:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 35;
+                  break;
+               case 35:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 37:
+                  if (curChar == 34 && kind > 102)
+                     kind = 102;
+                  break;
+               case 38:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(54, 58); }
+                  break;
+               case 39:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 40:
+                  if ((0xf000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 41;
+                  break;
+               case 41:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAdd(39); }
+                  break;
+               case 42:
+                  if (curChar != 36)
+                     break;
+                  if (kind > 103)
+                     kind = 103;
+                  { jjCheckNAdd(43); }
+                  break;
+               case 43:
+                  if ((0x3ff00100fffc1ffL & l) == 0L)
+                     break;
+                  if (kind > 103)
+                     kind = 103;
+                  { jjCheckNAdd(43); }
+                  break;
+               case 44:
+                  if (curChar == 47)
+                     { jjAddStates(18, 19); }
+                  break;
+               case 46:
+                  if ((0xffffffffffffdbffL & l) == 0L)
+                     break;
+                  if (kind > 31)
+                     kind = 31;
+                  { jjCheckNAddStates(0, 2); }
+                  break;
+               case 47:
+                  if ((0x2400L & l) != 0L && kind > 31)
+                     kind = 31;
+                  break;
+               case 48:
+                  if (curChar == 10 && kind > 31)
+                     kind = 31;
+                  break;
+               case 49:
+                  if (curChar == 13)
+                     jjstateSet[jjnewStateCnt++] = 48;
+                  break;
+               case 50:
+                  if (curChar == 42)
+                     jjstateSet[jjnewStateCnt++] = 51;
+                  break;
+               case 51:
+                  if ((0xffff7fffffffffffL & l) != 0L && kind > 32)
+                     kind = 32;
+                  break;
+               case 52:
+                  if (curChar == 42)
+                     jjstateSet[jjnewStateCnt++] = 50;
+                  break;
+               case 53:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 91)
+                     kind = 91;
+                  { jjCheckNAddStates(3, 17); }
+                  break;
+               case 54:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(54, 55); }
+                  break;
+               case 55:
+               case 98:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAdd(56); }
+                  break;
+               case 57:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(57, 58); }
+                  break;
+               case 58:
+               case 109:
+                  if ((0x3ff000000000000L & l) != 0L && kind > 91)
+                     kind = 91;
+                  break;
+               case 59:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(59, 60); }
+                  break;
+               case 60:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(59, 61); }
+                  break;
+               case 61:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(62, 65); }
+                  break;
+               case 63:
+                  if ((0x280000000000L & l) != 0L)
+                     { jjCheckNAdd(64); }
+                  break;
+               case 64:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(66, 68); }
+                  break;
+               case 65:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(65, 66); }
+                  break;
+               case 66:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(64, 9); }
+                  break;
+               case 67:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(69, 72); }
+                  break;
+               case 68:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(73, 77); }
+                  break;
+               case 69:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(69, 70); }
+                  break;
+               case 70:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(71, 72); }
+                  break;
+               case 71:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(78, 80); }
+                  break;
+               case 73:
+                  if ((0x280000000000L & l) != 0L)
+                     { jjCheckNAdd(74); }
+                  break;
+               case 74:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(81, 83); }
+                  break;
+               case 75:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(75, 76); }
+                  break;
+               case 76:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddTwoStates(74, 9); }
+                  break;
+               case 77:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(84, 87); }
+                  break;
+               case 78:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(88, 91); }
+                  break;
+               case 79:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(79, 80); }
+                  break;
+               case 80:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(81, 82); }
+                  break;
+               case 81:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(92, 94); }
+                  break;
+               case 82:
+                  if (curChar != 46)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(95, 97); }
+                  break;
+               case 83:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(98, 101); }
+                  break;
+               case 84:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(84, 85); }
+                  break;
+               case 85:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(95, 97); }
+                  break;
+               case 87:
+                  if ((0x280000000000L & l) != 0L)
+                     { jjCheckNAdd(88); }
+                  break;
+               case 88:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(102, 104); }
+                  break;
+               case 89:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(89, 90); }
+                  break;
+               case 90:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddTwoStates(88, 9); }
+                  break;
+               case 91:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(105, 108); }
+                  break;
+               case 92:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddStates(109, 113); }
+                  break;
+               case 93:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(114, 117); }
+                  break;
+               case 94:
+                  if (curChar == 48)
+                     { jjAddStates(27, 34); }
+                  break;
+               case 96:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(118, 120); }
+                  break;
+               case 97:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(97, 98); }
+                  break;
+               case 99:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(121, 123); }
+                  break;
+               case 100:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(100, 101); }
+                  break;
+               case 101:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAdd(56); }
+                  break;
+               case 103:
+                  if ((0x3000000000000L & l) != 0L)
+                     { jjCheckNAddStates(124, 126); }
+                  break;
+               case 104:
+                  if ((0x3000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(104, 105); }
+                  break;
+               case 105:
+                  if ((0x3000000000000L & l) != 0L)
+                     { jjCheckNAdd(56); }
+                  break;
+               case 107:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 91)
+                     kind = 91;
+                  { jjCheckNAddTwoStates(108, 109); }
+                  break;
+               case 108:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(108, 109); }
+                  break;
+               case 110:
+                  if ((0xff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 91)
+                     kind = 91;
+                  { jjCheckNAddTwoStates(111, 112); }
+                  break;
+               case 111:
+                  if ((0xff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(111, 112); }
+                  break;
+               case 112:
+                  if ((0xff000000000000L & l) != 0L && kind > 91)
+                     kind = 91;
+                  break;
+               case 114:
+                  if ((0x3000000000000L & l) == 0L)
+                     break;
+                  if (kind > 91)
+                     kind = 91;
+                  { jjCheckNAddTwoStates(115, 116); }
+                  break;
+               case 115:
+                  if ((0x3000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(115, 116); }
+                  break;
+               case 116:
+                  if ((0x3000000000000L & l) != 0L && kind > 91)
+                     kind = 91;
+                  break;
+               case 118:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjAddStates(127, 128); }
+                  break;
+               case 119:
+                  if (curChar == 46)
+                     { jjCheckNAdd(120); }
+                  break;
+               case 120:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(120, 121); }
+                  break;
+               case 122:
+                  if ((0x280000000000L & l) != 0L)
+                     { jjCheckNAdd(123); }
+                  break;
+               case 123:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddTwoStates(123, 9); }
+                  break;
+               case 125:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     { jjCheckNAddStates(129, 131); }
+                  break;
+               case 126:
+                  if (curChar == 46)
+                     { jjCheckNAdd(127); }
+                  break;
+               case 128:
+                  if ((0x280000000000L & l) != 0L)
+                     { jjCheckNAdd(129); }
+                  break;
+               case 129:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 96)
+                     kind = 96;
+                  { jjCheckNAddTwoStates(129, 9); }
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 103)
+                     kind = 103;
+                  { jjCheckNAdd(43); }
+                  break;
+               case 2:
+                  if (curChar == 95)
+                     { jjAddStates(132, 133); }
+                  break;
+               case 4:
+                  if ((0x2000000020L & l) != 0L)
+                     { jjAddStates(134, 135); }
+                  break;
+               case 7:
+                  if (curChar == 95)
+                     { jjAddStates(136, 137); }
+                  break;
+               case 9:
+                  if ((0x5000000050L & l) != 0L && kind > 96)
+                     kind = 96;
+                  break;
+               case 13:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     { jjCheckNAdd(14); }
+                  break;
+               case 15:
+                  if (curChar == 92)
+                     { jjAddStates(138, 140); }
+                  break;
+               case 16:
+                  if ((0x14404410000000L & l) != 0L)
+                     { jjCheckNAdd(14); }
+                  break;
+               case 21:
+                  if (curChar == 117)
+                     jjstateSet[jjnewStateCnt++] = 22;
+                  break;
+               case 22:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 23;
+                  break;
+               case 23:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 24;
+                  break;
+               case 24:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 25;
+                  break;
+               case 25:
+                  if ((0x7e0000007eL & l) != 0L)
+                     { jjCheckNAdd(14); }
+                  break;
+               case 26:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 21;
+                  break;
+               case 28:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 29:
+                  if (curChar == 92)
+                     { jjAddStates(141, 143); }
+                  break;
+               case 30:
+                  if ((0x14404410000000L & l) != 0L)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 31:
+                  if (curChar == 117)
+                     jjstateSet[jjnewStateCnt++] = 32;
+                  break;
+               case 32:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 33;
+                  break;
+               case 33:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 34;
+                  break;
+               case 34:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 35;
+                  break;
+               case 35:
+                  if ((0x7e0000007eL & l) != 0L)
+                     { jjCheckNAddStates(20, 23); }
+                  break;
+               case 36:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 31;
+                  break;
+               case 43:
+                  if ((0x87fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 103)
+                     kind = 103;
+                  { jjCheckNAdd(43); }
+                  break;
+               case 46:
+                  if (kind > 31)
+                     kind = 31;
+                  { jjAddStates(0, 2); }
+                  break;
+               case 51:
+                  if (kind > 32)
+                     kind = 32;
+                  break;
+               case 54:
+                  if (curChar == 95)
+                     { jjAddStates(144, 145); }
+                  break;
+               case 56:
+                  if ((0x100000001000L & l) != 0L && kind > 90)
+                     kind = 90;
+                  break;
+               case 57:
+                  if (curChar == 95)
+                     { jjAddStates(146, 147); }
+                  break;
+               case 59:
+                  if (curChar == 95)
+                     { jjAddStates(148, 149); }
+                  break;
+               case 62:
+                  if ((0x2000000020L & l) != 0L)
+                     { jjAddStates(150, 151); }
+                  break;
+               case 65:
+                  if (curChar == 95)
+                     { jjAddStates(152, 153); }
+                  break;
+               case 69:
+                  if (curChar == 95)
+                     { jjAddStates(154, 155); }
+                  break;
+               case 72:
+                  if ((0x2000000020L & l) != 0L)
+                     { jjAddStates(156, 157); }
+                  break;
+               case 75:
+                  if (curChar == 95)
+                     { jjAddStates(158, 159); }
+                  break;
+               case 79:
+                  if (curChar == 95)
+                     { jjAddStates(160, 161); }
+                  break;
+               case 84:
+                  if (curChar == 95)
+                     { jjAddStates(162, 163); }
+                  break;
+               case 86:
+                  if ((0x2000000020L & l) != 0L)
+                     { jjAddStates(164, 165); }
+                  break;
+               case 89:
+                  if (curChar == 95)
+                     { jjAddStates(166, 167); }
+                  break;
+               case 95:
+                  if ((0x100000001000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 96;
+                  break;
+               case 96:
+                  if ((0x7e0000007eL & l) != 0L)
+                     { jjCheckNAddStates(118, 120); }
+                  break;
+               case 97:
+                  if ((0x7e8000007eL & l) != 0L)
+                     { jjCheckNAddTwoStates(97, 98); }
+                  break;
+               case 98:
+                  if ((0x7e0000007eL & l) != 0L)
+                     { jjCheckNAdd(56); }
+                  break;
+               case 100:
+                  if (curChar == 95)
+                     { jjAddStates(168, 169); }
+                  break;
+               case 102:
+                  if ((0x400000004L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 103;
+                  break;
+               case 104:
+                  if (curChar == 95)
+                     { jjAddStates(170, 171); }
+                  break;
+               case 106:
+                  if ((0x100000001000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 107;
+                  break;
+               case 107:
+                  if ((0x7e0000007eL & l) == 0L)
+                     break;
+                  if (kind > 91)
+                     kind = 91;
+                  { jjCheckNAddTwoStates(108, 109); }
+                  break;
+               case 108:
+                  if ((0x7e8000007eL & l) != 0L)
+                     { jjCheckNAddTwoStates(108, 109); }
+                  break;
+               case 109:
+                  if ((0x7e0000007eL & l) != 0L && kind > 91)
+                     kind = 91;
+                  break;
+               case 111:
+                  if (curChar == 95)
+                     { jjAddStates(172, 173); }
+                  break;
+               case 113:
+                  if ((0x400000004L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 114;
+                  break;
+               case 115:
+                  if (curChar == 95)
+                     { jjAddStates(174, 175); }
+                  break;
+               case 117:
+                  if ((0x100000001000000L & l) != 0L)
+                     { jjCheckNAddTwoStates(118, 119); }
+                  break;
+               case 118:
+                  if ((0x7e0000007eL & l) != 0L)
+                     { jjCheckNAddTwoStates(118, 119); }
+                  break;
+               case 120:
+                  if ((0x7e0000007eL & l) != 0L)
+                     { jjAddStates(176, 177); }
+                  break;
+               case 121:
+                  if ((0x1000000010000L & l) != 0L)
+                     { jjAddStates(178, 179); }
+                  break;
+               case 124:
+                  if ((0x100000001000000L & l) != 0L)
+                     { jjCheckNAdd(125); }
+                  break;
+               case 125:
+                  if ((0x7e0000007eL & l) != 0L)
+                     { jjCheckNAddStates(129, 131); }
+                  break;
+               case 127:
+                  if ((0x1000000010000L & l) != 0L)
+                     { jjAddStates(180, 181); }
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 103)
+                     kind = 103;
+                  { jjCheckNAdd(43); }
+                  break;
+               case 13:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjstateSet[jjnewStateCnt++] = 14;
+                  break;
+               case 28:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     { jjAddStates(20, 23); }
+                  break;
+               case 43:
+                  if (!jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 103)
+                     kind = 103;
+                  { jjCheckNAdd(43); }
+                  break;
+               case 46:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 31)
+                     kind = 31;
+                  { jjAddStates(0, 2); }
+                  break;
+               case 51:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 32)
+                     kind = 32;
+                  break;
+               default : if (i1 == 0 || l1 == 0 || i2 == 0 ||  l2 == 0) break; else break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 130 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private int jjMoveStringLiteralDfa0_2(){
+   switch(curChar)
+   {
+      case 42:
+         return jjMoveStringLiteralDfa1_2(0x800000000L);
+      default :
+         return 1;
+   }
+}
+private int jjMoveStringLiteralDfa1_2(long active0){
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 47:
+         if ((active0 & 0x800000000L) != 0L)
+            return jjStopAtPos(1, 35);
+         break;
+      default :
+         return 2;
+   }
+   return 2;
+}
+private int jjMoveStringLiteralDfa0_1(){
+   switch(curChar)
+   {
+      case 42:
+         return jjMoveStringLiteralDfa1_1(0x400000000L);
+      default :
+         return 1;
+   }
+}
+private int jjMoveStringLiteralDfa1_1(long active0){
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 47:
+         if ((active0 & 0x400000000L) != 0L)
+            return jjStopAtPos(1, 34);
+         break;
+      default :
+         return 2;
+   }
+   return 2;
+}
+static final int[] jjnextStates = {
+   46, 47, 49, 54, 55, 56, 57, 58, 59, 62, 9, 69, 72, 79, 82, 93, 
+   78, 68, 45, 52, 28, 29, 36, 37, 13, 15, 26, 95, 99, 102, 106, 110, 
+   113, 117, 124, 2, 4, 9, 11, 1, 4, 9, 7, 9, 10, 6, 7, 9, 
+   10, 1, 2, 4, 9, 11, 28, 29, 39, 36, 37, 61, 62, 9, 59, 62, 
+   9, 68, 65, 9, 67, 64, 65, 9, 67, 61, 59, 62, 9, 68, 69, 72, 
+   78, 75, 9, 77, 74, 75, 9, 77, 71, 69, 72, 78, 79, 82, 93, 83, 
+   86, 9, 84, 86, 9, 92, 89, 9, 91, 88, 89, 9, 91, 83, 84, 86, 
+   9, 92, 81, 79, 82, 93, 97, 98, 56, 100, 101, 56, 104, 105, 56, 118, 
+   119, 125, 126, 127, 2, 3, 5, 6, 7, 8, 16, 17, 19, 30, 38, 40, 
+   54, 55, 57, 58, 59, 60, 63, 64, 65, 66, 69, 70, 73, 74, 75, 76, 
+   79, 80, 84, 85, 87, 88, 89, 90, 100, 101, 104, 105, 111, 112, 115, 116, 
+   120, 121, 122, 123, 128, 129, 
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec2[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec0[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec4[i2] & l2) != 0L);
+      case 2:
+         return ((jjbitVec5[i2] & l2) != 0L);
+      case 3:
+         return ((jjbitVec6[i2] & l2) != 0L);
+      case 4:
+         return ((jjbitVec7[i2] & l2) != 0L);
+      case 5:
+         return ((jjbitVec8[i2] & l2) != 0L);
+      case 6:
+         return ((jjbitVec9[i2] & l2) != 0L);
+      case 7:
+         return ((jjbitVec10[i2] & l2) != 0L);
+      case 9:
+         return ((jjbitVec11[i2] & l2) != 0L);
+      case 10:
+         return ((jjbitVec12[i2] & l2) != 0L);
+      case 11:
+         return ((jjbitVec13[i2] & l2) != 0L);
+      case 12:
+         return ((jjbitVec14[i2] & l2) != 0L);
+      case 13:
+         return ((jjbitVec15[i2] & l2) != 0L);
+      case 14:
+         return ((jjbitVec16[i2] & l2) != 0L);
+      case 15:
+         return ((jjbitVec17[i2] & l2) != 0L);
+      case 16:
+         return ((jjbitVec18[i2] & l2) != 0L);
+      case 17:
+         return ((jjbitVec19[i2] & l2) != 0L);
+      case 18:
+         return ((jjbitVec20[i2] & l2) != 0L);
+      case 19:
+         return ((jjbitVec21[i2] & l2) != 0L);
+      case 20:
+         return ((jjbitVec0[i2] & l2) != 0L);
+      case 22:
+         return ((jjbitVec22[i2] & l2) != 0L);
+      case 23:
+         return ((jjbitVec23[i2] & l2) != 0L);
+      case 24:
+         return ((jjbitVec24[i2] & l2) != 0L);
+      case 25:
+         return ((jjbitVec25[i2] & l2) != 0L);
+      case 29:
+         return ((jjbitVec26[i2] & l2) != 0L);
+      case 30:
+         return ((jjbitVec27[i2] & l2) != 0L);
+      case 31:
+         return ((jjbitVec28[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec29[i2] & l2) != 0L);
+      case 33:
+         return ((jjbitVec30[i2] & l2) != 0L);
+      case 48:
+         return ((jjbitVec31[i2] & l2) != 0L);
+      case 49:
+         return ((jjbitVec32[i2] & l2) != 0L);
+      case 77:
+         return ((jjbitVec33[i2] & l2) != 0L);
+      case 159:
+         return ((jjbitVec34[i2] & l2) != 0L);
+      case 164:
+         return ((jjbitVec35[i2] & l2) != 0L);
+      case 215:
+         return ((jjbitVec36[i2] & l2) != 0L);
+      case 216:
+         return ((jjbitVec37[i2] & l2) != 0L);
+      case 250:
+         return ((jjbitVec38[i2] & l2) != 0L);
+      case 251:
+         return ((jjbitVec39[i2] & l2) != 0L);
+      case 253:
+         return ((jjbitVec40[i2] & l2) != 0L);
+      case 254:
+         return ((jjbitVec41[i2] & l2) != 0L);
+      case 255:
+         return ((jjbitVec42[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec3[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+private static final boolean jjCanMove_2(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec43[i2] & l2) != 0L);
+      case 2:
+         return ((jjbitVec5[i2] & l2) != 0L);
+      case 3:
+         return ((jjbitVec44[i2] & l2) != 0L);
+      case 4:
+         return ((jjbitVec45[i2] & l2) != 0L);
+      case 5:
+         return ((jjbitVec46[i2] & l2) != 0L);
+      case 6:
+         return ((jjbitVec47[i2] & l2) != 0L);
+      case 7:
+         return ((jjbitVec48[i2] & l2) != 0L);
+      case 9:
+         return ((jjbitVec49[i2] & l2) != 0L);
+      case 10:
+         return ((jjbitVec50[i2] & l2) != 0L);
+      case 11:
+         return ((jjbitVec51[i2] & l2) != 0L);
+      case 12:
+         return ((jjbitVec52[i2] & l2) != 0L);
+      case 13:
+         return ((jjbitVec53[i2] & l2) != 0L);
+      case 14:
+         return ((jjbitVec54[i2] & l2) != 0L);
+      case 15:
+         return ((jjbitVec55[i2] & l2) != 0L);
+      case 16:
+         return ((jjbitVec56[i2] & l2) != 0L);
+      case 17:
+         return ((jjbitVec19[i2] & l2) != 0L);
+      case 18:
+         return ((jjbitVec20[i2] & l2) != 0L);
+      case 19:
+         return ((jjbitVec57[i2] & l2) != 0L);
+      case 20:
+         return ((jjbitVec0[i2] & l2) != 0L);
+      case 22:
+         return ((jjbitVec22[i2] & l2) != 0L);
+      case 23:
+         return ((jjbitVec58[i2] & l2) != 0L);
+      case 24:
+         return ((jjbitVec59[i2] & l2) != 0L);
+      case 25:
+         return ((jjbitVec60[i2] & l2) != 0L);
+      case 29:
+         return ((jjbitVec26[i2] & l2) != 0L);
+      case 30:
+         return ((jjbitVec27[i2] & l2) != 0L);
+      case 31:
+         return ((jjbitVec28[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec61[i2] & l2) != 0L);
+      case 33:
+         return ((jjbitVec30[i2] & l2) != 0L);
+      case 48:
+         return ((jjbitVec62[i2] & l2) != 0L);
+      case 49:
+         return ((jjbitVec32[i2] & l2) != 0L);
+      case 77:
+         return ((jjbitVec33[i2] & l2) != 0L);
+      case 159:
+         return ((jjbitVec34[i2] & l2) != 0L);
+      case 164:
+         return ((jjbitVec35[i2] & l2) != 0L);
+      case 215:
+         return ((jjbitVec36[i2] & l2) != 0L);
+      case 216:
+         return ((jjbitVec63[i2] & l2) != 0L);
+      case 220:
+         return ((jjbitVec64[i2] & l2) != 0L);
+      case 221:
+         return ((jjbitVec65[i2] & l2) != 0L);
+      case 250:
+         return ((jjbitVec38[i2] & l2) != 0L);
+      case 251:
+         return ((jjbitVec66[i2] & l2) != 0L);
+      case 253:
+         return ((jjbitVec40[i2] & l2) != 0L);
+      case 254:
+         return ((jjbitVec67[i2] & l2) != 0L);
+      case 255:
+         return ((jjbitVec68[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec3[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+
+/** Token literal values. */
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, null, null, null, null, 
+null, null, null, null, null, null, null, null, null, null, null, null, null, null, 
+null, null, null, null, null, null, null, null, null, null, 
+"\141\142\163\164\162\141\143\164", "\141\163\163\145\162\164", "\142\157\157\154\145\141\156", 
+"\142\162\145\141\153", "\142\171\164\145", "\143\141\163\145", "\143\141\164\143\150", 
+"\143\150\141\162", "\143\154\141\163\163", "\143\157\156\163\164", 
+"\143\157\156\164\151\156\165\145", "\144\145\146\141\165\154\164", "\144\157", "\144\157\165\142\154\145", 
+"\145\154\163\145", "\145\156\165\155", "\145\170\164\145\156\144\163", "\146\141\154\163\145", 
+"\146\151\156\141\154", "\146\151\156\141\154\154\171", "\146\154\157\141\164", "\146\157\162", 
+"\147\157\164\157", "\151\146", "\151\155\160\154\145\155\145\156\164\163", 
+"\151\155\160\157\162\164", "\151\156\163\164\141\156\143\145\157\146", "\151\156\164", 
+"\151\156\164\145\162\146\141\143\145", "\154\157\156\147", "\156\141\164\151\166\145", "\156\145\167", 
+"\156\165\154\154", "\160\141\143\153\141\147\145", "\160\162\151\166\141\164\145", 
+"\160\162\157\164\145\143\164\145\144", "\160\165\142\154\151\143", "\162\145\164\165\162\156", 
+"\163\150\157\162\164", "\163\164\141\164\151\143", "\163\164\162\151\143\164\146\160", 
+"\163\165\160\145\162", "\163\167\151\164\143\150", 
+"\163\171\156\143\150\162\157\156\151\172\145\144", "\164\150\151\163", "\164\150\162\157\167", "\164\150\162\157\167\163", 
+"\164\162\141\156\163\151\145\156\164", "\164\162\165\145", "\164\162\171", "\166\157\151\144", 
+"\166\157\154\141\164\151\154\145", "\167\150\151\154\145", null, null, null, null, null, null, null, null, null, 
+null, null, null, null, null, null, null, "\50", "\51", "\173", "\175", "\133", 
+"\135", "\73", "\54", "\56", "\100", "\75", "\74", "\41", "\176", "\77", "\72", 
+"\75\75", "\74\75", "\76\75", "\41\75", "\174\174", "\46\46", "\53\53", "\55\55", "\53", 
+"\55", "\52", "\57", "\46", "\174", "\136", "\45", "\74\74", "\53\75", "\55\75", 
+"\52\75", "\57\75", "\46\75", "\174\75", "\136\75", "\45\75", "\74\74\75", "\76\76\75", 
+"\76\76\76\75", "\56\56\56", "\55\76", "\72\72", "\76\76\76", "\76\76", "\76", "\32", };
+protected Token jjFillToken()
+{
+   final Token t;
+   final String curTokenImage;
+   final int beginLine;
+   final int endLine;
+   final int beginColumn;
+   final int endColumn;
+   String im = jjstrLiteralImages[jjmatchedKind];
+   curTokenImage = (im == null) ? input_stream.GetImage() : im;
+   beginLine = input_stream.getBeginLine();
+   beginColumn = input_stream.getBeginColumn();
+   endLine = input_stream.getEndLine();
+   endColumn = input_stream.getEndColumn();
+   t = ASTParser.GTToken.newToken(jjmatchedKind, curTokenImage);
+
+   t.beginLine = beginLine;
+   t.endLine = endLine;
+   t.beginColumn = beginColumn;
+   t.endColumn = endColumn;
+
+   return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+/** Get the next Token. */
+public Token getNextToken() 
+{
+  Token specialToken = null;
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {
+   try
+   {
+      curChar = input_stream.BeginToken();
+   }
+   catch(Exception e)
+   {
+      jjmatchedKind = 0;
+      jjmatchedPos = -1;
+      matchedToken = jjFillToken();
+      matchedToken.specialToken = specialToken;
+      CommonTokenAction(matchedToken);
+      return matchedToken;
+   }
+   image = jjimage;
+   image.setLength(0);
+   jjimageLen = 0;
+
+   for (;;)
+   {
+     switch(curLexState)
+     {
+       case 0:
+         try { input_stream.backup(0);
+            while (curChar <= 32 && (0x100003600L & (1L << curChar)) != 0L)
+               curChar = input_stream.BeginToken();
+         }
+         catch (java.io.IOException e1) { continue EOFLoop; }
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_0();
+         break;
+       case 1:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_1();
+         if (jjmatchedPos == 0 && jjmatchedKind > 36)
+         {
+            jjmatchedKind = 36;
+         }
+         break;
+       case 2:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_2();
+         if (jjmatchedPos == 0 && jjmatchedKind > 36)
+         {
+            jjmatchedKind = 36;
+         }
+         break;
+     }
+     if (jjmatchedKind != 0x7fffffff)
+     {
+        if (jjmatchedPos + 1 < curPos)
+           input_stream.backup(curPos - jjmatchedPos - 1);
+        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           matchedToken = jjFillToken();
+           matchedToken.specialToken = specialToken;
+           TokenLexicalActions(matchedToken);
+       if (jjnewLexState[jjmatchedKind] != -1)
+         curLexState = jjnewLexState[jjmatchedKind];
+           CommonTokenAction(matchedToken);
+           return matchedToken;
+        }
+        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+           {
+              matchedToken = jjFillToken();
+              if (specialToken == null)
+                 specialToken = matchedToken;
+              else
+              {
+                 matchedToken.specialToken = specialToken;
+                 specialToken = (specialToken.next = matchedToken);
+              }
+              SkipLexicalActions(matchedToken);
+           }
+           else
+              SkipLexicalActions(null);
+         if (jjnewLexState[jjmatchedKind] != -1)
+           curLexState = jjnewLexState[jjmatchedKind];
+           continue EOFLoop;
+        }
+        MoreLexicalActions();
+      if (jjnewLexState[jjmatchedKind] != -1)
+        curLexState = jjnewLexState[jjmatchedKind];
+        curPos = 0;
+        jjmatchedKind = 0x7fffffff;
+        try {
+           curChar = input_stream.readChar();
+           continue;
+        }
+        catch (java.io.IOException e1) { }
+     }
+     int error_line = input_stream.getEndLine();
+     int error_column = input_stream.getEndColumn();
+     String error_after = null;
+     boolean EOFSeen = false;
+     try { input_stream.readChar(); input_stream.backup(1); }
+     catch (java.io.IOException e1) {
+        EOFSeen = true;
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+        if (curChar == '\n' || curChar == '\r') {
+           error_line++;
+           error_column = 0;
+        }
+        else
+           error_column++;
+     }
+     if (!EOFSeen) {
+        input_stream.backup(1);
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+     }
+     throw new TokenMgrException(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrException.LEXICAL_ERROR);
+   }
+  }
+}
+
+void SkipLexicalActions(Token matchedToken)
+{
+   switch(jjmatchedKind)
+   {
+      default :
+         break;
+   }
+}
+void MoreLexicalActions()
+{
+   jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
+   switch(jjmatchedKind)
+   {
+      case 32 :
+         image.append(input_stream.GetSuffix(jjimageLen));
+         jjimageLen = 0;
+                   input_stream.backup(1);
+         break;
+      default :
+         break;
+   }
+}
+void TokenLexicalActions(Token matchedToken)
+{
+   switch(jjmatchedKind)
+   {
+      case 153 :
+        image.append(jjstrLiteralImages[153]);
+        lengthOfMatch = jjstrLiteralImages[153].length();
+     matchedToken.kind = GT;
+     ((ASTParser.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT;
+     input_stream.backup(2);
+         break;
+      case 154 :
+        image.append(jjstrLiteralImages[154]);
+        lengthOfMatch = jjstrLiteralImages[154].length();
+     matchedToken.kind = GT;
+     ((ASTParser.GTToken)matchedToken).realKind = RSIGNEDSHIFT;
+     input_stream.backup(1);
+         break;
+      default :
+         break;
+   }
+}
+private void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private void jjAddStates(int start, int end)
+{
+   do {
+      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+   } while (start++ != end);
+}
+private void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+
+private void jjCheckNAddStates(int start, int end)
+{
+   do {
+      jjCheckNAdd(jjnextStates[start]);
+   } while (start++ != end);
+}
+
+    /** Constructor. */
+    public ASTParserTokenManager(JavaCharStream stream){
+
+      if (JavaCharStream.staticFlag)
+            throw new RuntimeException("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+
+    input_stream = stream;
+  }
+
+  /** Constructor. */
+  public ASTParserTokenManager (JavaCharStream stream, int lexState){
+    ReInit(stream);
+    SwitchTo(lexState);
+  }
+
+  /** Reinitialise parser. */
+  public void ReInit(JavaCharStream stream)
+  {
+	
+    jjmatchedPos = jjnewStateCnt = 0;
+    curLexState = defaultLexState;
+    input_stream = stream;
+    ReInitRounds();
+  }
+
+  private void ReInitRounds()
+  {
+    int i;
+    jjround = 0x80000001;
+    for (i = 130; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+  }
+
+  /** Reinitialise parser. */
+  public void ReInit( JavaCharStream stream, int lexState)
+  {
+  
+    ReInit( stream);
+    SwitchTo(lexState);
+  }
+
+  /** Switch to specified lex state. */
+  public void SwitchTo(int lexState)
+  {
+    if (lexState >= 3 || lexState < 0)
+      throw new TokenMgrException("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrException.INVALID_LEXICAL_STATE);
+    else
+      curLexState = lexState;
+  }
+
+/** Lexer state names. */
+public static final String[] lexStateNames = {
+   "DEFAULT",
+   "IN_JAVA_DOC_COMMENT",
+   "IN_MULTI_LINE_COMMENT",
+};
+
+/** Lex State array. */
+public static final int[] jjnewLexState = {
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, 1, 2, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, 
+};
+static final long[] jjtoToken = {
+   0xffffffe000000001L, 0xfffffce10fffffffL, 0x1fffffffL, 
+};
+static final long[] jjtoSkip = {
+   0xcfffffffeL, 0x0L, 0x0L, 
+};
+static final long[] jjtoSpecial = {
+   0xc80000000L, 0x0L, 0x0L, 
+};
+static final long[] jjtoMore = {
+   0x1300000000L, 0x0L, 0x0L, 
+};
+    protected JavaCharStream  input_stream;
+
+    private final int[] jjrounds = new int[130];
+    private final int[] jjstateSet = new int[2 * 130];
+
+    private final StringBuilder jjimage = new StringBuilder();
+    private StringBuilder image = jjimage;
+    private int jjimageLen;
+    private int lengthOfMatch;
+    
+    protected int curChar;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/JavaCharStream.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/JavaCharStream.java
new file mode 100644
index 0000000..da924db
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/JavaCharStream.java
@@ -0,0 +1,560 @@
+/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 6.1 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (with java-like unicode escape processing).
+ */
+ 
+
+public
+class JavaCharStream
+{
+  /** Whether parser is static. */
+  public static final boolean staticFlag = false;
+
+
+  static final int hexval(char c) throws java.io.IOException {
+    switch(c)
+    {
+       case '0' :
+          return 0;
+       case '1' :
+          return 1;
+       case '2' :
+          return 2;
+       case '3' :
+          return 3;
+       case '4' :
+          return 4;
+       case '5' :
+          return 5;
+       case '6' :
+          return 6;
+       case '7' :
+          return 7;
+       case '8' :
+          return 8;
+       case '9' :
+          return 9;
+
+       case 'a' :
+       case 'A' :
+          return 10;
+       case 'b' :
+       case 'B' :
+          return 11;
+       case 'c' :
+       case 'C' :
+          return 12;
+       case 'd' :
+       case 'D' :
+          return 13;
+       case 'e' :
+       case 'E' :
+          return 14;
+       case 'f' :
+       case 'F' :
+          return 15;
+    }
+
+    throw new java.io.IOException(); // Should never come here
+  }
+
+/** Position in buffer. */
+  public int bufpos = -1;
+  int bufsize;
+  int available;
+  int tokenBegin;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected Provider inputStream;
+
+  protected char[] nextCharBuf;
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int nextCharInd = -1;
+  protected int inBuf = 0;
+  protected int tabSize = 1;
+  protected boolean trackLineColumn = true;
+
+  public void setTabSize(int i) { tabSize = i; }
+  public int getTabSize(int i) { return tabSize; }
+
+  protected void ExpandBuff(boolean wrapAround)
+  {
+    char[] newbuffer = new char[bufsize + 2048];
+    int newbufline[] = new int[bufsize + 2048];
+    int newbufcolumn[] = new int[bufsize + 2048];
+
+    try
+    {
+      if (wrapAround)
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+        bufcolumn = newbufcolumn;
+
+        bufpos += (bufsize - tokenBegin);
+    }
+    else
+    {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        bufcolumn = newbufcolumn;
+
+        bufpos -= tokenBegin;
+      }
+    }
+    catch (Exception t)
+    {
+      throw new RuntimeException(t.getMessage());
+    }
+
+    available = (bufsize += 2048);
+    tokenBegin = 0;
+  }
+
+  protected void FillBuff() throws java.io.IOException
+  {
+    int i;
+    if (maxNextCharInd == 4096)
+      maxNextCharInd = nextCharInd = 0;
+
+    try {
+      if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
+                                          4096 - maxNextCharInd)) == -1)
+      {
+        inputStream.close();
+        throw new java.io.IOException();
+      }
+      else
+         maxNextCharInd += i;
+      return;
+    }
+    catch(java.io.IOException e) {
+      if (bufpos != 0)
+      {
+        --bufpos;
+        backup(0);
+      }
+      else
+      {
+        bufline[bufpos] = line;
+        bufcolumn[bufpos] = column;
+      }
+      throw e;
+    }
+  }
+
+  protected char ReadByte() throws java.io.IOException
+  {
+    if (++nextCharInd >= maxNextCharInd)
+      FillBuff();
+
+    return nextCharBuf[nextCharInd];
+  }
+
+/** @return starting character for token. */
+  public char BeginToken() throws java.io.IOException
+  {
+    if (inBuf > 0)
+    {
+      --inBuf;
+
+      if (++bufpos == bufsize)
+        bufpos = 0;
+
+      tokenBegin = bufpos;
+      return buffer[bufpos];
+    }
+
+    tokenBegin = 0;
+    bufpos = -1;
+
+    return readChar();
+  }
+
+  protected void AdjustBuffSize()
+  {
+    if (available == bufsize)
+    {
+      if (tokenBegin > 2048)
+      {
+        bufpos = 0;
+        available = tokenBegin;
+      }
+      else
+        ExpandBuff(false);
+    }
+    else if (available > tokenBegin)
+      available = bufsize;
+    else if ((tokenBegin - available) < 2048)
+      ExpandBuff(true);
+    else
+      available = tokenBegin;
+  }
+
+  protected void UpdateLineColumn(char c)
+  {
+    column++;
+
+    if (prevCharIsLF)
+    {
+      prevCharIsLF = false;
+      line += (column = 1);
+    }
+    else if (prevCharIsCR)
+    {
+      prevCharIsCR = false;
+      if (c == '\n')
+      {
+        prevCharIsLF = true;
+      }
+      else
+        line += (column = 1);
+    }
+
+    switch (c)
+    {
+      case '\r' :
+        prevCharIsCR = true;
+        break;
+      case '\n' :
+        prevCharIsLF = true;
+        break;
+      case '\t' :
+        column--;
+        column += (tabSize - (column % tabSize));
+        break;
+      default :
+        break;
+    }
+
+    bufline[bufpos] = line;
+    bufcolumn[bufpos] = column;
+  }
+
+/** Read a character. */
+  public char readChar() throws java.io.IOException
+  {
+    if (inBuf > 0)
+    {
+      --inBuf;
+
+      if (++bufpos == bufsize)
+        bufpos = 0;
+
+      return buffer[bufpos];
+    }
+
+    char c;
+
+    if (++bufpos == available)
+      AdjustBuffSize();
+
+    if ((buffer[bufpos] = c = ReadByte()) == '\\')
+    {
+      UpdateLineColumn(c);
+
+      int backSlashCnt = 1;
+
+      for (;;) // Read all the backslashes
+      {
+        if (++bufpos == available)
+          AdjustBuffSize();
+
+        try
+        {
+          if ((buffer[bufpos] = c = ReadByte()) != '\\')
+          {
+            UpdateLineColumn(c);
+            // found a non-backslash char.
+            if ((c == 'u') && ((backSlashCnt & 1) == 1))
+            {
+              if (--bufpos < 0)
+                bufpos = bufsize - 1;
+
+              break;
+            }
+
+            backup(backSlashCnt);
+            return '\\';
+          }
+        }
+        catch(java.io.IOException e)
+        {
+	  // We are returning one backslash so we should only backup (count-1)
+          if (backSlashCnt > 1)
+            backup(backSlashCnt-1);
+
+          return '\\';
+        }
+
+        UpdateLineColumn(c);
+        backSlashCnt++;
+      }
+
+      // Here, we have seen an odd number of backslash's followed by a 'u'
+      try
+      {
+        while ((c = ReadByte()) == 'u')
+          ++column;
+
+        buffer[bufpos] = c = (char)(hexval(c) << 12 |
+                                    hexval(ReadByte()) << 8 |
+                                    hexval(ReadByte()) << 4 |
+                                    hexval(ReadByte()));
+
+        column += 4;
+      }
+      catch(java.io.IOException e)
+      {
+        throw new RuntimeException("Invalid escape character at line " + line +
+                                         " column " + column + ".");
+      }
+
+      if (backSlashCnt == 1)
+        return c;
+      else
+      {
+        backup(backSlashCnt - 1);
+        return '\\';
+      }
+    }
+    else
+    {
+      UpdateLineColumn(c);
+      return c;
+    }
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndColumn
+   */
+  public int getColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndLine
+   */
+  public int getLine() {
+    return bufline[bufpos];
+  }
+
+/** Get end column. */
+  public int getEndColumn() {
+    return bufcolumn[bufpos];
+  }
+
+/** Get end line. */
+  public int getEndLine() {
+    return bufline[bufpos];
+  }
+
+/** @return column of token start */
+  public int getBeginColumn() {
+    return bufcolumn[tokenBegin];
+  }
+
+/** @return line number of token start */
+  public int getBeginLine() {
+    return bufline[tokenBegin];
+  }
+
+/** Retreat. */
+  public void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+      bufpos += bufsize;
+  }
+
+/** Constructor. */
+  public JavaCharStream(Provider dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+    nextCharBuf = new char[4096];
+  }
+
+/** Constructor. */
+  public JavaCharStream(Provider dstream,
+                                        int startline, int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+/** Constructor. */
+  public JavaCharStream(Provider dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+/** Reinitialise. */
+  public void ReInit(Provider dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+      nextCharBuf = new char[4096];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    nextCharInd = bufpos = -1;
+  }
+
+/** Reinitialise. */
+  public void ReInit(Provider dstream,
+                                        int startline, int startcolumn)
+  {
+    ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+/** Reinitialise. */
+  public void ReInit(Provider dstream)
+  {
+    ReInit(dstream, 1, 1, 4096);
+  }
+
+
+
+  /** @return token image as String */
+  public String GetImage()
+  {
+    if (bufpos >= tokenBegin)
+      return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+    else
+      return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                              new String(buffer, 0, bufpos + 1);
+  }
+
+  /** @return suffix */
+  public char[] GetSuffix(int len)
+  {
+    char[] ret = new char[len];
+
+    if ((bufpos + 1) >= len)
+      System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+    else
+    {
+      System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                        len - bufpos - 1);
+      System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+    }
+
+    return ret;
+  }
+
+  /** Set buffers back to null when finished. */
+  public void Done()
+  {
+    nextCharBuf = null;
+    buffer = null;
+    bufline = null;
+    bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+    int start = tokenBegin;
+    int len;
+
+    if (bufpos >= tokenBegin)
+    {
+      len = bufpos - tokenBegin + inBuf + 1;
+    }
+    else
+    {
+      len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+    }
+
+    int i = 0, j = 0, k = 0;
+    int nextColDiff = 0, columnDiff = 0;
+
+    while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+    {
+      bufline[j] = newLine;
+      nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+      bufcolumn[j] = newCol + columnDiff;
+      columnDiff = nextColDiff;
+      i++;
+    }
+
+    if (i < len)
+    {
+      bufline[j] = newLine++;
+      bufcolumn[j] = newCol + columnDiff;
+
+      while (i++ < len)
+      {
+        if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+          bufline[j] = newLine++;
+        else
+          bufline[j] = newLine;
+      }
+    }
+
+    line = bufline[j];
+    column = bufcolumn[j];
+  }
+  boolean getTrackLineColumn() { return trackLineColumn; }
+  void setTrackLineColumn(boolean tlc) { trackLineColumn = tlc; }
+
+}
+/* JavaCC - OriginalChecksum=9ab0136fd4b1e2a45a251f41181a5bd8 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ParseException.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ParseException.java
new file mode 100644
index 0000000..3228367
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/ParseException.java
@@ -0,0 +1,227 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 6.1 */
+/* JavaCCOptions:KEEP_LINE_COLUMN=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  private static final String INDENT = "    ";
+  
+  /**
+   * The end of line string (we do not use System.getProperty("") so that we are compatible with Android/GWT);
+   */
+  protected static String EOL = "\n";
+
+  
+  public ParseException(Token currentTokenVal,
+          int[][] expectedTokenSequencesVal,
+          String[] tokenImageVal
+         )
+	{
+	  this (currentTokenVal, expectedTokenSequencesVal, tokenImageVal, null);
+	}
+  
+  
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal,
+                        String lexicalStateName
+                       )
+  {
+    super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal, lexicalStateName));
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+  }
+
+  /** Constructor with message. */
+  public ParseException(String message) {
+    super(message);
+  }
+
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * It uses "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser) the correct error message
+   * gets displayed.
+   */
+  private static String initialise(Token currentToken,
+                           int[][] expectedTokenSequences,
+                           String[] tokenImage,
+                           String lexicalStateName) {
+	StringBuilder sb = new StringBuilder();
+    StringBuffer expected = new StringBuffer();
+    
+    int maxSize = 0;
+    java.util.TreeSet<String> sortedOptions = new java.util.TreeSet<String>();
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+    	  sortedOptions.add(tokenImage[expectedTokenSequences[i][j]]);
+      }
+    }
+    
+    for (String option : sortedOptions) {
+        expected.append(INDENT).append(option).append(EOL);
+      }
+    
+    sb.append("Encountered unexpected token:");
+    
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      String tokenText = tok.image;
+  	  String escapedTokenText = add_escapes(tokenText);
+      if (i != 0) {
+      	sb.append(" ");
+      }
+      if (tok.kind == 0) {
+      	sb.append(tokenImage[0]);
+        break;
+      }
+      sb.append(" \"");
+	  sb.append(escapedTokenText);
+      sb.append("\"");
+      sb.append(" " + tokenImage[tok.kind]);
+      tok = tok.next;
+    }
+	sb.append(EOL).append(INDENT).append("at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn);
+	sb.append(".").append(EOL);
+    
+    if (expectedTokenSequences.length == 0) {
+        // Nothing to add here
+    } else {
+    	int numExpectedTokens = expectedTokenSequences.length;
+    	sb.append(EOL).append("Was expecting"+ (numExpectedTokens == 1 ? ":" : " one of:") + EOL + EOL);
+    	sb.append(expected.toString());
+    }
+    // 2013/07/30 --> Seems to be inaccurate as represents the readahead state, not the lexical state BEFORE the unknown token
+//    if (lexicalStateName != null) {
+//    	sb.append(EOL).append("** Lexical State : ").append(lexicalStateName).append(EOL).append(EOL);
+//    }
+    
+    return sb.toString();
+  }
+
+
+  /**
+   * Used to convert raw characters to their escaped version
+   * when these raw version cannot be used as part of an ASCII
+   * string literal.
+   */
+  static String add_escapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+}
+/* JavaCC - OriginalChecksum=c0da6a86ac0d0ec8b633aeafa43e6e37 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/Provider.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/Provider.java
new file mode 100644
index 0000000..bfd9da8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/Provider.java
@@ -0,0 +1,39 @@
+/* Generated By:JavaCC: Do not edit this line. Provider.java Version 6.1 */
+/* JavaCCOptions:KEEP_LINE_COLUMN=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+
+import java.io.IOException;
+
+public interface Provider {
+    /**
+     * Reads characters into an array
+     * @param buffer  Destination buffer
+     * @param offset   Offset at which to start storing characters
+     * @param length   The maximum possible number of characters to read
+     * @return The number of characters read, or -1 if all read
+     * @exception  IOException
+     */
+    public int read(char buffer[], int offset, int len) throws IOException;
+    
+    /**
+     * Closes the stream and releases any system resources associated with
+     * it.
+     * @exception IOException
+     */
+     public void close() throws IOException;
+    
+}
+/* JavaCC - OriginalChecksum=89684d4e3db82aa5e480d095c170b352 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/StreamProvider.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/StreamProvider.java
new file mode 100644
index 0000000..2c30e16
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/StreamProvider.java
@@ -0,0 +1,70 @@
+/* Generated By:JavaCC: Do not edit this line. StreamProvider.java Version 6.1 */
+/* JavaCCOptions:KEEP_LINE_COLUMN=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+/**
+ * NOTE : This generated class can be safely deleted if installing in a GWT installation (use StringProvider instead)
+ */
+public class StreamProvider implements Provider {
+
+	Reader _reader;
+
+	public StreamProvider(Reader reader) {
+		_reader = reader;
+	}
+	
+	public StreamProvider(InputStream stream) throws IOException {
+		_reader = new BufferedReader(new InputStreamReader(stream));
+	}
+	
+	public StreamProvider(InputStream stream, String charsetName) throws IOException {
+		_reader = new BufferedReader(new InputStreamReader(stream, charsetName));
+	}
+
+	@Override
+	public int read(char[] buffer, int off, int len) throws IOException {
+	   int result = _reader.read(buffer, off, len);
+
+	   /* CBA -- Added 2014/03/29 -- 
+	             This logic allows the generated Java code to be easily translated to C# (via sharpen) -
+	             as in C# 0 represents end of file, and in Java, -1 represents end of file
+	             See : http://msdn.microsoft.com/en-us/library/9kstw824(v=vs.110).aspx
+	             ** Technically, this is not required for java but the overhead is extremely low compared to the code generation benefits.
+	   */
+	   
+	   if (result == 0) {
+	      if (off < buffer.length && len > 0) {
+	        result = -1;
+	      }
+	   }
+	   
+		return result;
+	}
+
+	@Override
+	public void close() throws IOException {
+		_reader.close();
+	}
+
+}
+
+/* JavaCC - OriginalChecksum=b849e0746bbbf4528197ca9d130650d6 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/StringProvider.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/StringProvider.java
new file mode 100644
index 0000000..83c3504
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/StringProvider.java
@@ -0,0 +1,60 @@
+/* Generated By:JavaCC: Do not edit this line. StringProvider.java Version 6.1 */
+/* JavaCCOptions:KEEP_LINE_COLUMN=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+	
+	import java.io.IOException;
+	
+	public class StringProvider implements Provider {
+
+		String _string;
+		int _position = 0;
+		int _size;
+		
+		public StringProvider(String string) {
+			_string = string;
+			_size = string.length();
+		}
+		
+		@Override
+		public int read(char[] cbuf, int off, int len) throws IOException {
+			int numCharsOutstandingInString = _size - _position;
+			
+			if (numCharsOutstandingInString == 0) {
+				return -1;
+			}
+			
+			int numBytesInBuffer = cbuf.length;
+			int numBytesToRead = numBytesInBuffer -off;
+			numBytesToRead = numBytesToRead > len ? len : numBytesToRead;
+			
+			if (numBytesToRead > numCharsOutstandingInString) {
+				numBytesToRead = numCharsOutstandingInString;
+			}
+			
+			_string.getChars(_position, _position + numBytesToRead, cbuf, off);
+			
+			_position += numBytesToRead;
+			
+			return numBytesToRead;
+		}
+
+		@Override
+		public void close() throws IOException {
+			_string = null;
+		}
+		
+	}
+/* JavaCC - OriginalChecksum=9873e92cad8666980a4c6d392c0c7ad4 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/Token.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/Token.java
new file mode 100644
index 0000000..2731d04
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/Token.java
@@ -0,0 +1,143 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 6.1 */
+/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COLUMN=true,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token implements java.io.Serializable {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /** The line number of the first character of this Token. */
+  public int beginLine;
+  /** The column number of the first character of this Token. */
+  public int beginColumn;
+  /** The line number of the last character of this Token. */
+  public int endLine;
+  /** The column number of the last character of this Token. */
+  public int endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * An optional attribute value of the Token.
+   * Tokens which are not used as syntactic sugar will often contain
+   * meaningful values that will be used later on by the compiler or
+   * interpreter. This attribute value is often different from the image.
+   * Any subclass of Token that actually wants to return a non-null value can
+   * override this method as appropriate.
+   */
+  public Object getValue() {
+    return null;
+  }
+
+  /**
+   * No-argument constructor
+   */
+  public Token() {}
+
+  /**
+   * Constructs a new token for the specified Image.
+   */
+  public Token(int kind)
+  {
+    this(kind, null);
+  }
+
+  /**
+   * Constructs a new token for the specified Image and Kind.
+   */
+  public Token(int kind, String image)
+  {
+    this.kind = kind;
+    this.image = image;
+  }
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+    return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simply add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken(ofKind, image);
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use sit in your lexical actions.
+   */
+  public static Token newToken(int ofKind, String image)
+  {
+    switch(ofKind)
+    {
+      default : return new Token(ofKind, image);
+    }
+  }
+
+  public static Token newToken(int ofKind)
+  {
+    return newToken(ofKind, null);
+  }
+
+}
+/* JavaCC - OriginalChecksum=fd43051db65fcdc22df39a61d81bf7a4 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/TokenMgrError.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/TokenMgrError.java
new file mode 100644
index 0000000..09197e8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/TokenMgrError.java
@@ -0,0 +1,159 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
+/* JavaCCOptions: */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/** Token Manager Error. */
+public class TokenMgrError extends Error
+{
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /*
+   * Ordinals for various reasons why an Error of this type can be thrown.
+   */
+
+  /**
+   * Lexical error occurred.
+   */
+  static final int LEXICAL_ERROR = 0;
+
+  /**
+   * An attempt was made to create a second instance of a static token manager.
+   */
+  static final int STATIC_LEXER_ERROR = 1;
+
+  /**
+   * Tried to change to an invalid lexical state.
+   */
+  static final int INVALID_LEXICAL_STATE = 2;
+
+  /**
+   * Detected (and bailed out of) an infinite loop in the token manager.
+   */
+  static final int LOOP_DETECTED = 3;
+
+  /**
+   * Indicates the reason why the exception is thrown. It will have
+   * one of the above 4 values.
+   */
+  int errorCode;
+
+  /**
+   * Replaces unprintable characters by their escaped (or unicode escaped)
+   * equivalents in the given string
+   */
+  protected static final String addEscapes(String str) {
+    StringBuffer retval = new StringBuffer();
+    char ch;
+    for (int i = 0; i < str.length(); i++) {
+      switch (str.charAt(i))
+      {
+        case 0 :
+          continue;
+        case '\b':
+          retval.append("\\b");
+          continue;
+        case '\t':
+          retval.append("\\t");
+          continue;
+        case '\n':
+          retval.append("\\n");
+          continue;
+        case '\f':
+          retval.append("\\f");
+          continue;
+        case '\r':
+          retval.append("\\r");
+          continue;
+        case '\"':
+          retval.append("\\\"");
+          continue;
+        case '\'':
+          retval.append("\\\'");
+          continue;
+        case '\\':
+          retval.append("\\\\");
+          continue;
+        default:
+          if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+            String s = "0000" + Integer.toString(ch, 16);
+            retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+          } else {
+            retval.append(ch);
+          }
+          continue;
+      }
+    }
+    return retval.toString();
+  }
+
+  /**
+   * Returns a detailed message for the Error when it is thrown by the
+   * token manager to indicate a lexical error.
+   * Parameters :
+   *    EOFSeen     : indicates if EOF caused the lexical error
+   *    curLexState : lexical state in which this error occurred
+   *    errorLine   : line number when the error occurred
+   *    errorColumn : column number when the error occurred
+   *    errorAfter  : prefix that was seen before this error occurred
+   *    curchar     : the offending character
+   * Note: You can customize the lexical error message by modifying this method.
+   */
+  protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+    return("Lexical error at line " +
+          errorLine + ", column " +
+          errorColumn + ".  Encountered: " +
+          (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+          "after : \"" + addEscapes(errorAfter) + "\"");
+  }
+
+  /**
+   * You can also modify the body of this method to customize your error messages.
+   * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+   * of end-users concern, so you can return something like :
+   *
+   *     "Internal Error : Please file a bug report .... "
+   *
+   * from this method for such cases in the release version of your parser.
+   */
+  public String getMessage() {
+    return super.getMessage();
+  }
+
+  /*
+   * Constructors of various flavors follow.
+   */
+
+  /** No arg constructor. */
+  public TokenMgrError() {
+  }
+
+  /** Constructor with message and reason. */
+  public TokenMgrError(String message, int reason) {
+    super(message);
+    errorCode = reason;
+  }
+
+  /** Full Constructor. */
+  public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+    this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+  }
+}
+/* JavaCC - OriginalChecksum=f06c7e964b5c13a732337c2f3fb4f836 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/TokenMgrException.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/TokenMgrException.java
new file mode 100644
index 0000000..d290424
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_new_src/javaparser-generated-sources/com/github/javaparser/TokenMgrException.java
@@ -0,0 +1,158 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrException.java Version 6.1 */
+/* JavaCCOptions: */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/** Token Manager Error. */
+public class TokenMgrException extends RuntimeException
+{
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /*
+   * Ordinals for various reasons why an Error of this type can be thrown.
+   */
+
+  /**
+   * Lexical error occurred.
+   */
+  public static final int LEXICAL_ERROR = 0;
+
+  /**
+   * An attempt was made to create a second instance of a static token manager.
+   */
+  public static final int STATIC_LEXER_ERROR = 1;
+
+  /**
+   * Tried to change to an invalid lexical state.
+   */
+  public static final int INVALID_LEXICAL_STATE = 2;
+
+  /**
+   * Detected (and bailed out of) an infinite loop in the token manager.
+   */
+  public static final int LOOP_DETECTED = 3;
+
+  /**
+   * Indicates the reason why the exception is thrown. It will have
+   * one of the above 4 values.
+   */
+  int errorCode;
+
+  /**
+   * Replaces unprintable characters by their escaped (or unicode escaped)
+   * equivalents in the given string
+   */
+  protected static final String addEscapes(String str) {
+    StringBuffer retval = new StringBuffer();
+    char ch;
+    for (int i = 0; i < str.length(); i++) {
+      switch (str.charAt(i))
+      {
+        case '\b':
+          retval.append("\\b");
+          continue;
+        case '\t':
+          retval.append("\\t");
+          continue;
+        case '\n':
+          retval.append("\\n");
+          continue;
+        case '\f':
+          retval.append("\\f");
+          continue;
+        case '\r':
+          retval.append("\\r");
+          continue;
+        case '\"':
+          retval.append("\\\"");
+          continue;
+        case '\'':
+          retval.append("\\\'");
+          continue;
+        case '\\':
+          retval.append("\\\\");
+          continue;
+        default:
+          if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+            String s = "0000" + Integer.toString(ch, 16);
+            retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+          } else {
+            retval.append(ch);
+          }
+          continue;
+      }
+    }
+    return retval.toString();
+  }
+
+  /**
+   * Returns a detailed message for the Error when it is thrown by the
+   * token manager to indicate a lexical error.
+   * Parameters :
+   *    EOFSeen     : indicates if EOF caused the lexical error
+   *    curLexState : lexical state in which this error occurred
+   *    errorLine   : line number when the error occurred
+   *    errorColumn : column number when the error occurred
+   *    errorAfter  : prefix that was seen before this error occurred
+   *    curchar     : the offending character
+   * Note: You can customize the lexical error message by modifying this method.
+   */
+  protected static String LexicalErr(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, int curChar) {
+    char curChar1 = (char)curChar;
+    return("Lexical error at line " +
+          errorLine + ", column " +
+          errorColumn + ".  Encountered: " +
+          (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar1)) + "\"") + " (" + (int)curChar + "), ") +
+          "after : \"" + addEscapes(errorAfter) + "\"");
+  }
+
+  /**
+   * You can also modify the body of this method to customize your error messages.
+   * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+   * of end-users concern, so you can return something like :
+   *
+   *     "Internal Error : Please file a bug report .... "
+   *
+   * from this method for such cases in the release version of your parser.
+   */
+  public String getMessage() {
+    return super.getMessage();
+  }
+
+  /*
+   * Constructors of various flavors follow.
+   */
+
+  /** No arg constructor. */
+  public TokenMgrException() {
+  }
+
+  /** Constructor with message and reason. */
+  public TokenMgrException(String message, int reason) {
+    super(message);
+    errorCode = reason;
+  }
+
+  /** Full Constructor. */
+  public TokenMgrException(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, int curChar, int reason) {
+    this(LexicalErr(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+  }
+}
+/* JavaCC - OriginalChecksum=d2d40125d51af5fe5bc7e2ab87d062ad (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParser.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParser.java
new file mode 100644
index 0000000..151cff2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParser.java
@@ -0,0 +1,9148 @@
+/* Generated By:JavaCC: Do not edit this line. ASTParser.java */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+import java.io.*;
+import java.util.*;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * <p>This class was generated automatically by javacc, do not edit.</p>
+ */
+final class ASTParser implements ASTParserConstants {
+
+    void reset(InputStream in, String encoding) {
+        ReInit(in, encoding);
+    }
+
+    private List add(List list, Object obj) {
+        if (list == null) {
+                list = new LinkedList();
+        }
+        list.add(obj);
+        return list;
+    }
+
+    private List add(int pos, List list, Object obj) {
+        if (list == null) {
+                list = new LinkedList();
+        }
+        list.add(pos, obj);
+        return list;
+    }
+
+        private class Modifier {
+
+                final int modifiers;
+                final List annotations;
+                final int beginLine;
+                final int beginColumn;
+
+                public Modifier(int beginLine, int beginColumn, int modifiers, List annotations) {
+                        this.beginLine = beginLine;
+                        this.beginColumn = beginColumn;
+                        this.modifiers = modifiers;
+                        this.annotations = annotations;
+                }
+        }
+
+    public int addModifier(int modifiers, int mod, Token token) {
+        if ((ModifierSet.hasModifier(modifiers, mod))) {
+            throwParseException(token, "Duplicated modifier");
+        }
+        return ModifierSet.addModifier(modifiers, mod);
+    }
+
+    private void throwParseException(Token token, String message) {
+        StringBuilder buf = new StringBuilder();
+        buf.append(message);
+        buf.append(": \"");
+        buf.append(token.image);
+        buf.append("\" at line ");
+        buf.append(token.beginLine);
+        buf.append(", column ");
+        buf.append(token.beginColumn);
+        ParseException e = new ParseException(buf.toString());
+        e.currentToken = token;
+        throw e;
+    }
+
+    private Expression generateLambda(Expression ret, Statement lambdaBody) {
+            if (ret instanceof EnclosedExpr) {
+                Expression inner = ((EnclosedExpr) ret).getInner();
+                if (inner != null && inner instanceof NameExpr) {
+                    VariableDeclaratorId id = new VariableDeclaratorId(inner.getBeginLine(), inner.getBeginColumn(), inner.getEndLine(), inner.getEndColumn(), ((NameExpr)inner).getName(), 0);
+                    List params = add(null, new Parameter(ret.getBeginLine(), ret.getBeginColumn(), ret.getEndLine(), ret.getEndColumn(), 0, null, new UnknownType(), false, id));
+                    ret = new LambdaExpr(ret.getBeginLine(), ret.getBeginColumn(), lambdaBody.getEndLine(), lambdaBody.getEndColumn(), params, lambdaBody, true);
+                } else {
+                    ret = new LambdaExpr(ret.getBeginLine(), ret.getBeginColumn(), lambdaBody.getEndLine(), lambdaBody.getEndColumn(), null, lambdaBody, true);
+                }
+            } else if (ret instanceof NameExpr) {
+                    VariableDeclaratorId id = new VariableDeclaratorId(ret.getBeginLine(), ret.getBeginColumn(), ret.getEndLine(), ret.getEndColumn(), ((NameExpr)ret).getName(), 0);
+                List params = add(null, new Parameter(ret.getBeginLine(), ret.getBeginColumn(), ret.getEndLine(), ret.getEndColumn(), 0, null, new UnknownType(), false, id));
+                ret = new LambdaExpr(ret.getBeginLine(), ret.getBeginColumn(), ret.getEndLine(), ret.getEndColumn(), params, lambdaBody, false);
+            } else if (ret instanceof LambdaExpr) {
+                ((LambdaExpr) ret).setBody(lambdaBody);
+                ret.setEndLine(lambdaBody.getEndLine());
+                ret.setEndColumn(lambdaBody.getEndColumn());
+            } else {
+                throw new ParseException("Failed to parse lambda expression! Please create an issue at https://github.com/javaparser/javaparser/issues");
+            }
+            return ret;
+    }
+
+    static final class GTToken extends Token {
+
+        int realKind = ASTParserConstants.GT;
+
+        GTToken(int kind, String image) {
+            this.kind = kind;
+            this.image = image;
+        }
+
+        public static Token newToken(int kind, String image) {
+            return new GTToken(kind, image);
+        }
+    }
+
+    private Token last_special_token = null;
+
+/*****************************************
+ * THE JAVA LANGUAGE GRAMMAR STARTS HERE *
+ *****************************************/
+
+/*
+ * Program structuring syntax follows.
+ */
+  final public CompilationUnit CompilationUnit() {
+        PackageDeclaration pakage = null;
+        List imports = null;
+        ImportDeclaration in = null;
+        List types = null;
+        TypeDeclaration tn = null;
+        int line = -1;
+        int column = 0;
+    if (jj_2_1(2147483647)) {
+      pakage = PackageDeclaration();
+                                                                   line = pakage.getBeginLine(); column = pakage.getBeginColumn();
+    } else {
+      ;
+    }
+    label_1:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case IMPORT:
+        ;
+        break;
+      default:
+        jj_la1[0] = jj_gen;
+        break label_1;
+      }
+      in = ImportDeclaration();
+                               if(line==-1){line = in.getBeginLine(); column = in.getBeginColumn();} imports = add(imports, in);
+    }
+    label_2:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ABSTRACT:
+      case CLASS:
+      case ENUM:
+      case FINAL:
+      case INTERFACE:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOLATILE:
+      case SEMICOLON:
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[1] = jj_gen;
+        break label_2;
+      }
+      tn = TypeDeclaration();
+                             if(line==-1){line = tn.getBeginLine(); column = tn.getBeginColumn();} types = add(types, tn);
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 0:
+      jj_consume_token(0);
+      break;
+    case 131:
+      jj_consume_token(131);
+      break;
+    default:
+      jj_la1[2] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return new CompilationUnit(line == -1 ? 0 : line, column, token.endLine, token.endColumn,pakage, imports, types);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public PackageDeclaration PackageDeclaration() {
+        List annotations = null;
+        AnnotationExpr ann;
+        NameExpr name;
+        int line;
+        int column;
+    label_3:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[3] = jj_gen;
+        break label_3;
+      }
+      ann = Annotation();
+                       annotations = add(annotations, ann);
+    }
+    jj_consume_token(PACKAGE);
+             line=token.beginLine; column=token.beginColumn;
+    name = Name();
+    jj_consume_token(SEMICOLON);
+    {if (true) return new PackageDeclaration(line, column, token.endLine, token.endColumn,annotations, name);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ImportDeclaration ImportDeclaration() {
+        NameExpr name;
+        boolean isStatic = false;
+        boolean isAsterisk = false;
+        int line;
+        int column;
+    jj_consume_token(IMPORT);
+            line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case STATIC:
+      jj_consume_token(STATIC);
+                                                                          isStatic = true;
+      break;
+    default:
+      jj_la1[4] = jj_gen;
+      ;
+    }
+    name = Name();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case DOT:
+      jj_consume_token(DOT);
+      jj_consume_token(STAR);
+                                                                                                                         isAsterisk = true;
+      break;
+    default:
+      jj_la1[5] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+    {if (true) return new ImportDeclaration(line, column, token.endLine, token.endColumn,name, isStatic, isAsterisk);}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Modifiers. We match all modifiers in a single rule to reduce the chances of
+ * syntax errors for simple modifier mistakes. It will also enable us to give
+ * better error messages.
+ */
+  final public Modifier Modifiers() {
+    int beginLine = -1;
+    int beginColumn = -1;
+    int modifiers = 0;
+    List annotations = null;
+    AnnotationExpr ann;
+    label_4:
+    while (true) {
+      if (jj_2_2(2)) {
+        ;
+      } else {
+        break label_4;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case PUBLIC:
+        jj_consume_token(PUBLIC);
+              modifiers = addModifier(modifiers, ModifierSet.PUBLIC, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case STATIC:
+        jj_consume_token(STATIC);
+              modifiers = addModifier(modifiers, ModifierSet.STATIC, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case PROTECTED:
+        jj_consume_token(PROTECTED);
+                 modifiers = addModifier(modifiers, ModifierSet.PROTECTED, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case PRIVATE:
+        jj_consume_token(PRIVATE);
+               modifiers = addModifier(modifiers, ModifierSet.PRIVATE, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case FINAL:
+        jj_consume_token(FINAL);
+             modifiers = addModifier(modifiers, ModifierSet.FINAL, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case ABSTRACT:
+        jj_consume_token(ABSTRACT);
+                modifiers = addModifier(modifiers, ModifierSet.ABSTRACT, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case SYNCHRONIZED:
+        jj_consume_token(SYNCHRONIZED);
+                    modifiers = addModifier(modifiers, ModifierSet.SYNCHRONIZED, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case NATIVE:
+        jj_consume_token(NATIVE);
+              modifiers = addModifier(modifiers, ModifierSet.NATIVE, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case TRANSIENT:
+        jj_consume_token(TRANSIENT);
+                 modifiers = addModifier(modifiers, ModifierSet.TRANSIENT, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case VOLATILE:
+        jj_consume_token(VOLATILE);
+                modifiers = addModifier(modifiers, ModifierSet.VOLATILE, token); if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case STRICTFP:
+        jj_consume_token(STRICTFP);
+                modifiers = addModifier(modifiers, ModifierSet.STRICTFP, token);  if(beginLine==-1) {beginLine=token.beginLine; beginColumn=token.beginColumn;}
+        break;
+      case AT:
+        ann = Annotation();
+                        annotations = add(annotations, ann); if(beginLine==-1) {beginLine=ann.getBeginLine(); beginColumn=ann.getBeginColumn();}
+        break;
+      default:
+        jj_la1[6] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return new Modifier(beginLine, beginColumn, modifiers, annotations);}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Declaration syntax follows.
+ */
+  final public TypeDeclaration TypeDeclaration() {
+   Modifier modifier;
+   TypeDeclaration ret;
+
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SEMICOLON:
+      jj_consume_token(SEMICOLON);
+          ret = new EmptyTypeDeclaration(token.beginLine, token.beginColumn, token.endLine, token.endColumn);
+      break;
+    case ABSTRACT:
+    case CLASS:
+    case ENUM:
+    case FINAL:
+    case INTERFACE:
+    case NATIVE:
+    case PRIVATE:
+    case PROTECTED:
+    case PUBLIC:
+    case STATIC:
+    case STRICTFP:
+    case SYNCHRONIZED:
+    case TRANSIENT:
+    case VOLATILE:
+    case AT:
+      modifier = Modifiers();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case CLASS:
+      case INTERFACE:
+        ret = ClassOrInterfaceDeclaration(modifier);
+        break;
+      case ENUM:
+        ret = EnumDeclaration(modifier);
+        break;
+      case AT:
+        ret = AnnotationTypeDeclaration(modifier);
+        break;
+      default:
+        jj_la1[7] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    default:
+      jj_la1[8] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ClassOrInterfaceDeclaration ClassOrInterfaceDeclaration(Modifier modifier) {
+   boolean isInterface = false;
+   NameExpr name;
+   List typePar = null;
+   List extList = null;
+   List impList = null;
+   List members;
+   int line = modifier.beginLine;
+   int column = modifier.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case CLASS:
+      jj_consume_token(CLASS);
+      break;
+    case INTERFACE:
+      jj_consume_token(INTERFACE);
+                            isInterface = true;
+      break;
+    default:
+      jj_la1[9] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+                                                      if (line == -1) {line=token.beginLine; column=token.beginColumn;}
+    name = Name();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LT:
+      typePar = TypeParameters();
+                                typePar.remove(0);
+      break;
+    default:
+      jj_la1[10] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case EXTENDS:
+      extList = ExtendsList(isInterface);
+      break;
+    default:
+      jj_la1[11] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IMPLEMENTS:
+      impList = ImplementsList(isInterface);
+      break;
+    default:
+      jj_la1[12] = jj_gen;
+      ;
+    }
+    members = ClassOrInterfaceBody(isInterface);
+    ClassOrInterfaceDeclaration tmp = new ClassOrInterfaceDeclaration(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, isInterface, null, typePar, extList, impList, members);
+    tmp.setNameExpr(name);
+    {if (true) return tmp;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ExtendsList(boolean isInterface) {
+   boolean extendsMoreThanOne = false;
+   List ret = new LinkedList();
+   ClassOrInterfaceType cit;
+    AnnotationExpr ann;
+   List annotations = null;
+    jj_consume_token(EXTENDS);
+    label_5:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[13] = jj_gen;
+        break label_5;
+      }
+      ann = Annotation();
+                                     annotations = add(annotations, ann);
+    }
+    cit = ClassOrInterfaceType();
+                                                                                                            cit.setAnnotations(annotations); ret.add(cit);
+    label_6:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[14] = jj_gen;
+        break label_6;
+      }
+      jj_consume_token(COMMA);
+      cit = ClassOrInterfaceType();
+                                        ret.add(cit); extendsMoreThanOne = true;
+    }
+      if (extendsMoreThanOne && !isInterface)
+         throwParseException(token, "A class cannot extend more than one other class");
+     {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ImplementsList(boolean isInterface) {
+   List ret = new LinkedList();
+   ClassOrInterfaceType cit;
+   AnnotationExpr ann;
+   List annotations = null;
+    jj_consume_token(IMPLEMENTS);
+    label_7:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[15] = jj_gen;
+        break label_7;
+      }
+      ann = Annotation();
+                                        annotations = add(annotations, ann);
+    }
+    cit = ClassOrInterfaceType();
+                                                                                                               cit.setAnnotations(annotations); ret.add(cit);
+    label_8:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[16] = jj_gen;
+        break label_8;
+      }
+      jj_consume_token(COMMA);
+      cit = ClassOrInterfaceType();
+                                        ret.add(cit);
+    }
+      if (isInterface)
+         throwParseException(token, "An interface cannot implement other interfaces");
+     {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public EnumDeclaration EnumDeclaration(Modifier modifier) {
+        NameExpr name;
+        List impList = null;
+        EnumConstantDeclaration entry;
+        List entries = null;
+        BodyDeclaration member;
+        List members = null;
+        int line = modifier.beginLine;
+        int column = modifier.beginColumn;
+    jj_consume_token(ENUM);
+           if (line == -1) {line=token.beginLine; column=token.beginColumn;}
+    name = Name();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IMPLEMENTS:
+      impList = ImplementsList(false);
+      break;
+    default:
+      jj_la1[17] = jj_gen;
+      ;
+    }
+    jj_consume_token(LBRACE);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IDENTIFIER:
+    case AT:
+          entries = new LinkedList();
+      entry = EnumConstantDeclaration();
+                                            entries.add(entry);
+      label_9:
+      while (true) {
+        if (jj_2_3(2)) {
+          ;
+        } else {
+          break label_9;
+        }
+        jj_consume_token(COMMA);
+        entry = EnumConstantDeclaration();
+                                                                                                                         entries.add(entry);
+      }
+      break;
+    default:
+      jj_la1[18] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case COMMA:
+      jj_consume_token(COMMA);
+      break;
+    default:
+      jj_la1[19] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SEMICOLON:
+      jj_consume_token(SEMICOLON);
+      label_10:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case ABSTRACT:
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case CLASS:
+        case _DEFAULT:
+        case DOUBLE:
+        case ENUM:
+        case FINAL:
+        case FLOAT:
+        case INT:
+        case INTERFACE:
+        case LONG:
+        case NATIVE:
+        case PRIVATE:
+        case PROTECTED:
+        case PUBLIC:
+        case SHORT:
+        case STATIC:
+        case STRICTFP:
+        case SYNCHRONIZED:
+        case TRANSIENT:
+        case VOID:
+        case VOLATILE:
+        case IDENTIFIER:
+        case LBRACE:
+        case SEMICOLON:
+        case AT:
+        case LT:
+          ;
+          break;
+        default:
+          jj_la1[20] = jj_gen;
+          break label_10;
+        }
+        member = ClassOrInterfaceBodyDeclaration(false);
+                                                                          members = add(members, member);
+      }
+      break;
+    default:
+      jj_la1[21] = jj_gen;
+      ;
+    }
+    jj_consume_token(RBRACE);
+      EnumDeclaration tmp = new EnumDeclaration(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, null, impList, entries, members);
+      tmp.setNameExpr(name);
+      {if (true) return tmp;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public EnumConstantDeclaration EnumConstantDeclaration() {
+        List annotations = null;
+        AnnotationExpr ann;
+        String name;
+        List args = null;
+        List classBody = null;
+        int line = -1;
+        int column = -1;
+
+    label_11:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[22] = jj_gen;
+        break label_11;
+      }
+      ann = Annotation();
+                         annotations = add(annotations, ann); if(line==-1){line=ann.getBeginLine(); column=ann.getBeginColumn();}
+    }
+    jj_consume_token(IDENTIFIER);
+                 name = token.image; if(line==-1){line=token.beginLine; column=token.beginColumn;}
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LPAREN:
+      args = Arguments();
+      break;
+    default:
+      jj_la1[23] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LBRACE:
+      classBody = ClassOrInterfaceBody(false);
+      break;
+    default:
+      jj_la1[24] = jj_gen;
+      ;
+    }
+      EnumConstantDeclaration tmp = new EnumConstantDeclaration(line, column, token.endLine, token.endColumn, annotations, name, args, classBody);
+
+      {if (true) return tmp;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List TypeParameters() {
+        List ret = new LinkedList();
+        TypeParameter tp;
+        List annotations = null;
+        AnnotationExpr ann;
+    jj_consume_token(LT);
+         ret.add(new int[]{token.beginLine, token.beginColumn});
+    label_12:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[25] = jj_gen;
+        break label_12;
+      }
+      ann = Annotation();
+                           annotations = add(annotations, ann);
+    }
+    tp = TypeParameter();
+                          ret.add(tp); tp.setAnnotations(annotations); annotations = null;
+    label_13:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[26] = jj_gen;
+        break label_13;
+      }
+      jj_consume_token(COMMA);
+      label_14:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case AT:
+          ;
+          break;
+        default:
+          jj_la1[27] = jj_gen;
+          break label_14;
+        }
+        ann = Annotation();
+                                 annotations = add(annotations, ann);
+      }
+      tp = TypeParameter();
+                                                                                                ret.add(tp); tp.setAnnotations(annotations); annotations = null;
+    }
+    jj_consume_token(GT);
+     {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TypeParameter TypeParameter() {
+        String name;
+        List typeBound = null;
+        int line;
+        int column;
+    jj_consume_token(IDENTIFIER);
+                  name = token.image; line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case EXTENDS:
+      typeBound = TypeBound();
+      break;
+    default:
+      jj_la1[28] = jj_gen;
+      ;
+    }
+     {if (true) return new TypeParameter(line, column, token.endLine, token.endColumn,name, typeBound);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List TypeBound() {
+        List ret = new LinkedList();
+        ClassOrInterfaceType cit;
+        AnnotationExpr ann;
+        List annotations = null;
+    jj_consume_token(EXTENDS);
+    label_15:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[29] = jj_gen;
+        break label_15;
+      }
+      ann = Annotation();
+                                     annotations = add(annotations, ann);
+    }
+    cit = ClassOrInterfaceType();
+                                                                                                            cit.setAnnotations(annotations); ret.add(cit); annotations=null;
+    label_16:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case BIT_AND:
+        ;
+        break;
+      default:
+        jj_la1[30] = jj_gen;
+        break label_16;
+      }
+      jj_consume_token(BIT_AND);
+      label_17:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case AT:
+          ;
+          break;
+        default:
+          jj_la1[31] = jj_gen;
+          break label_17;
+        }
+        ann = Annotation();
+                                   annotations = add(annotations, ann);
+      }
+      cit = ClassOrInterfaceType();
+                                                                                                           cit.setAnnotations(annotations); ret.add(cit); annotations=null;
+    }
+     {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ClassOrInterfaceBody(boolean isInterface) {
+        List ret = new LinkedList();
+        BodyDeclaration member;
+    jj_consume_token(LBRACE);
+    label_18:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case _DEFAULT:
+      case DOUBLE:
+      case ENUM:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOID:
+      case VOLATILE:
+      case IDENTIFIER:
+      case LBRACE:
+      case SEMICOLON:
+      case AT:
+      case LT:
+        ;
+        break;
+      default:
+        jj_la1[32] = jj_gen;
+        break label_18;
+      }
+      member = ClassOrInterfaceBodyDeclaration(isInterface);
+                                                                ret.add(member);
+    }
+    jj_consume_token(RBRACE);
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public BodyDeclaration ClassOrInterfaceBodyDeclaration(boolean isInterface) {
+   boolean isNestedInterface = false;
+   Modifier modifier;
+   Modifier modifier2 = null;
+   int aux = 0;
+   BodyDeclaration ret;
+   boolean isDefault = false;
+
+    if (jj_2_6(2)) {
+      ret = InitializerDeclaration();
+             if (isInterface)
+                throwParseException(token, "An interface cannot have initializers");
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case _DEFAULT:
+      case DOUBLE:
+      case ENUM:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOID:
+      case VOLATILE:
+      case IDENTIFIER:
+      case AT:
+      case LT:
+        modifier = Modifiers();
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case _DEFAULT:
+          jj_consume_token(_DEFAULT);
+          modifier2 = Modifiers();
+            if(!isInterface)
+            {
+              throwParseException(token, "An interface cannot have default members");
+            }
+            isDefault = true;
+          break;
+        default:
+          jj_la1[33] = jj_gen;
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case CLASS:
+        case INTERFACE:
+          ret = ClassOrInterfaceDeclaration(modifier);
+          break;
+        case ENUM:
+          ret = EnumDeclaration(modifier);
+          break;
+        case AT:
+          ret = AnnotationTypeDeclaration(modifier);
+          break;
+        default:
+          jj_la1[34] = jj_gen;
+          if (jj_2_4(2147483647)) {
+            ret = ConstructorDeclaration(modifier);
+          } else if (jj_2_5(2147483647)) {
+            ret = FieldDeclaration(modifier);
+          } else {
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case BOOLEAN:
+            case BYTE:
+            case CHAR:
+            case DOUBLE:
+            case FLOAT:
+            case INT:
+            case LONG:
+            case SHORT:
+            case VOID:
+            case IDENTIFIER:
+            case LT:
+              ret = MethodDeclaration(modifier);
+                if(isDefault && ret!= null && ((MethodDeclaration)ret).getBody() == null)
+                {
+                  throwParseException(token, "\"default\" methods must have a body");
+                }
+                ((MethodDeclaration)ret).setDefault(isDefault);
+                if(modifier2!= null)
+                {
+                  aux = modifier2.modifiers;
+                }
+                ((MethodDeclaration)ret).setModifiers(addModifier(modifier.modifiers, aux, token));
+              break;
+            default:
+              jj_la1[35] = jj_gen;
+              jj_consume_token(-1);
+              throw new ParseException();
+            }
+          }
+        }
+            if(isDefault && ! (ret instanceof MethodDeclaration))
+            {
+              throwParseException(token, "Just methods can have the keyword \"default\".");
+            }
+        break;
+      case SEMICOLON:
+        jj_consume_token(SEMICOLON);
+                ret = new EmptyMemberDeclaration(token.beginLine, token.beginColumn, token.endLine, token.endColumn);
+        break;
+      default:
+        jj_la1[36] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public FieldDeclaration FieldDeclaration(Modifier modifier) {
+        Type type;
+        List variables = new LinkedList();
+        VariableDeclarator val;
+    // Modifiers are already matched in the caller
+      type = Type();
+    val = VariableDeclarator();
+                                     variables.add(val);
+    label_19:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[37] = jj_gen;
+        break label_19;
+      }
+      jj_consume_token(COMMA);
+      val = VariableDeclarator();
+                                     variables.add(val);
+    }
+    jj_consume_token(SEMICOLON);
+        int line = modifier.beginLine;
+        int column = modifier.beginColumn;
+        if (line == -1) { line=type.getBeginLine(); column=type.getBeginColumn(); }
+        {if (true) return new FieldDeclaration(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, type, variables);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public VariableDeclarator VariableDeclarator() {
+        VariableDeclaratorId id;
+        Expression init = null;
+    id = VariableDeclaratorId();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ASSIGN:
+      jj_consume_token(ASSIGN);
+      init = VariableInitializer();
+      break;
+    default:
+      jj_la1[38] = jj_gen;
+      ;
+    }
+    {if (true) return new  VariableDeclarator(id.getBeginLine(), id.getBeginColumn(), token.endLine, token.endColumn, id, init);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public VariableDeclaratorId VariableDeclaratorId() {
+        String name;
+        int arrayCount = 0;
+        int line;
+        int column;
+    jj_consume_token(IDENTIFIER);
+                 name = token.image; line=token.beginLine; column=token.beginColumn;
+    label_20:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LBRACKET:
+        ;
+        break;
+      default:
+        jj_la1[39] = jj_gen;
+        break label_20;
+      }
+      jj_consume_token(LBRACKET);
+      jj_consume_token(RBRACKET);
+                                                                                                   arrayCount++;
+    }
+    {if (true) return new VariableDeclaratorId(line, column, token.endLine, token.endColumn,name, arrayCount);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression VariableInitializer() {
+        Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LBRACE:
+      ret = ArrayInitializer();
+      break;
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:
+      ret = Expression();
+      break;
+    default:
+      jj_la1[40] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ArrayInitializerExpr ArrayInitializer() {
+        List values = null;
+        Expression val;
+        int line;
+        int column;
+    jj_consume_token(LBRACE);
+       line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case LBRACE:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:
+      val = VariableInitializer();
+                                                                                        values = add(values, val);
+      label_21:
+      while (true) {
+        if (jj_2_7(2)) {
+          ;
+        } else {
+          break label_21;
+        }
+        jj_consume_token(COMMA);
+        val = VariableInitializer();
+                                                                                                                                                                      values = add(values, val);
+      }
+      break;
+    default:
+      jj_la1[41] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case COMMA:
+      jj_consume_token(COMMA);
+      break;
+    default:
+      jj_la1[42] = jj_gen;
+      ;
+    }
+    jj_consume_token(RBRACE);
+    {if (true) return new ArrayInitializerExpr(line, column, token.endLine, token.endColumn,values);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public MethodDeclaration MethodDeclaration(Modifier modifier) {
+        List typeParameters = null;
+        Type type;
+        NameExpr name;
+        List parameters;
+        int arrayCount = 0;
+        List throws_ = null;
+        BlockStmt block = null;
+        int line = modifier.beginLine;
+        int column = modifier.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LT:
+      typeParameters = TypeParameters();
+                                        int[] lineCol=(int[])typeParameters.remove(0); if(line==-1){ line=lineCol[0]; column=lineCol[1];}
+      break;
+    default:
+      jj_la1[43] = jj_gen;
+      ;
+    }
+    type = ResultType();
+                        if(line==-1){line=type.getBeginLine(); column=type.getBeginColumn();}
+    name = Name();
+    parameters = FormalParameters();
+    label_22:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LBRACKET:
+        ;
+        break;
+      default:
+        jj_la1[44] = jj_gen;
+        break label_22;
+      }
+      jj_consume_token(LBRACKET);
+      jj_consume_token(RBRACKET);
+                                                            arrayCount++;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case THROWS:
+      jj_consume_token(THROWS);
+      throws_ = NameList();
+      break;
+    default:
+      jj_la1[45] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LBRACE:
+      block = Block();
+      break;
+    case SEMICOLON:
+      jj_consume_token(SEMICOLON);
+      break;
+    default:
+      jj_la1[46] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+      MethodDeclaration tmp = new MethodDeclaration(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, typeParameters, type, null, parameters, arrayCount, throws_, block);
+      tmp.setNameExpr(name);
+      {if (true) return tmp;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List FormalParameters() {
+        List ret = null;
+        Parameter par;
+    jj_consume_token(LPAREN);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ABSTRACT:
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FINAL:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NATIVE:
+    case PRIVATE:
+    case PROTECTED:
+    case PUBLIC:
+    case SHORT:
+    case STATIC:
+    case STRICTFP:
+    case SYNCHRONIZED:
+    case TRANSIENT:
+    case VOLATILE:
+    case IDENTIFIER:
+    case AT:
+      par = FormalParameter();
+                                  ret = add(ret, par);
+      label_23:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case COMMA:
+          ;
+          break;
+        default:
+          jj_la1[47] = jj_gen;
+          break label_23;
+        }
+        jj_consume_token(COMMA);
+        par = FormalParameter();
+                                                                                         ret = add(ret, par);
+      }
+      break;
+    default:
+      jj_la1[48] = jj_gen;
+      ;
+    }
+    jj_consume_token(RPAREN);
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List FormalLambdaParameters() {
+  List ret = null;
+  Parameter par;
+    jj_consume_token(COMMA);
+    par = FormalParameter();
+                                   ret = add(ret, par);
+    label_24:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[49] = jj_gen;
+        break label_24;
+      }
+      jj_consume_token(COMMA);
+      par = FormalParameter();
+                                                                                           ret = add(ret, par);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List InferredLambdaParameters() {
+  List ret = null;
+  VariableDeclaratorId id;
+    jj_consume_token(COMMA);
+    id = VariableDeclaratorId();
+                                          ret = add(ret, new Parameter(id.getBeginLine(), id.getBeginColumn(), id.getEndLine(), id.getEndColumn(), 0, null, new UnknownType(), false, id));
+    label_25:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[50] = jj_gen;
+        break label_25;
+      }
+      jj_consume_token(COMMA);
+      id = VariableDeclaratorId();
+                                       ret = add(ret, new Parameter(id.getBeginLine(), id.getBeginColumn(), id.getEndLine(), id.getEndColumn(), 0, null, new UnknownType(), false, id));
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Parameter FormalParameter() {
+        Modifier modifier;
+        Type type;
+        boolean isVarArg = false;
+        VariableDeclaratorId id;
+    modifier = Modifiers();
+    type = Type();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ELLIPSIS:
+      jj_consume_token(ELLIPSIS);
+                                                 isVarArg = true;
+      break;
+    default:
+      jj_la1[51] = jj_gen;
+      ;
+    }
+    id = VariableDeclaratorId();
+    int line = modifier.beginLine;
+    int column = modifier.beginColumn;
+    if(line==-1){ line=type.getBeginLine(); column=type.getBeginColumn(); }
+    {if (true) return new Parameter(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, type, isVarArg, id);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ConstructorDeclaration ConstructorDeclaration(Modifier modifier) {
+        List typeParameters = null;
+        NameExpr name;
+        List parameters;
+        List throws_ = null;
+        ExplicitConstructorInvocationStmt exConsInv = null;
+        List stmts;
+        int line = modifier.beginLine;
+        int column = modifier.beginColumn;
+        int bbLine = 0;
+        int bbColumn = 0;
+        int beLine = 0;
+        int beColumn = 0;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LT:
+      typeParameters = TypeParameters();
+                                        int[] lineCol=(int[])typeParameters.remove(0); if(line==-1){ line=lineCol[0]; column=lineCol[1];}
+      break;
+    default:
+      jj_la1[52] = jj_gen;
+      ;
+    }
+    // Modifiers matched in the caller
+      name = SimpleName();
+                        if(line==-1){line=token.beginLine; column=token.beginColumn;}
+    parameters = FormalParameters();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case THROWS:
+      jj_consume_token(THROWS);
+      throws_ = NameList();
+      break;
+    default:
+      jj_la1[53] = jj_gen;
+      ;
+    }
+    jj_consume_token(LBRACE);
+        bbLine=token.beginLine; bbColumn=token.beginColumn;
+    if (jj_2_8(2147483647)) {
+      exConsInv = ExplicitConstructorInvocation();
+    } else {
+      ;
+    }
+    stmts = Statements();
+    jj_consume_token(RBRACE);
+        if (exConsInv != null) {
+                stmts = add(0, stmts, exConsInv);
+        }
+        ConstructorDeclaration tmp = new ConstructorDeclaration(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, typeParameters, null, parameters, throws_, new BlockStmt(bbLine, bbColumn, token.endLine, token.endColumn, stmts));
+    tmp.setNameExpr(name);
+    {if (true) return tmp;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ExplicitConstructorInvocationStmt ExplicitConstructorInvocation() {
+        boolean isThis = false;
+        List args;
+        Expression expr = null;
+        List typeArgs = null;
+        int line = -1;
+        int column = 0;
+    if (jj_2_10(2147483647)) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LT:
+      case 132:
+        typeArgs = TypeArguments();
+                                         int[] lineCol=(int[])typeArgs.remove(0); line=lineCol[0]; column=lineCol[1];
+        break;
+      default:
+        jj_la1[54] = jj_gen;
+        ;
+      }
+      jj_consume_token(THIS);
+                   if (line == -1) {line=token.beginLine; column=token.beginColumn;} isThis = true;
+      args = Arguments();
+      jj_consume_token(SEMICOLON);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case LT:
+      case 132:
+        if (jj_2_9(2147483647)) {
+          expr = PrimaryExpressionWithoutSuperSuffix();
+          jj_consume_token(DOT);
+                  line=expr.getBeginLine(); column=expr.getBeginColumn();
+        } else {
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case LT:
+        case 132:
+          typeArgs = TypeArguments();
+                                        int[] lineCol=(int[])typeArgs.remove(0); if (line == -1) {line=lineCol[0]; column=lineCol[1];}
+          break;
+        default:
+          jj_la1[55] = jj_gen;
+          ;
+        }
+        jj_consume_token(SUPER);
+                   if (line == -1) {line=token.beginLine; column=token.beginColumn;}
+        args = Arguments();
+        jj_consume_token(SEMICOLON);
+        break;
+      default:
+        jj_la1[56] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return new ExplicitConstructorInvocationStmt(line, column, token.endLine, token.endColumn,typeArgs, isThis, expr, args);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List Statements() {
+        List ret = null;
+        Statement stmt;
+    label_26:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ABSTRACT:
+      case ASSERT:
+      case BOOLEAN:
+      case BREAK:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case CONTINUE:
+      case DO:
+      case DOUBLE:
+      case FALSE:
+      case FINAL:
+      case FLOAT:
+      case FOR:
+      case IF:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case NEW:
+      case NULL:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case RETURN:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SUPER:
+      case SWITCH:
+      case SYNCHRONIZED:
+      case THIS:
+      case THROW:
+      case TRANSIENT:
+      case TRUE:
+      case TRY:
+      case VOID:
+      case VOLATILE:
+      case WHILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case LBRACE:
+      case SEMICOLON:
+      case AT:
+      case INCR:
+      case DECR:
+        ;
+        break;
+      default:
+        jj_la1[57] = jj_gen;
+        break label_26;
+      }
+      stmt = BlockStatement();
+                                    ret = add(ret, stmt);
+    }
+          {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public InitializerDeclaration InitializerDeclaration() {
+        BlockStmt block;
+        int line = -1;
+        int column = 0;
+        boolean isStatic = false;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case STATIC:
+      jj_consume_token(STATIC);
+               isStatic = true; line=token.beginLine; column=token.beginColumn;
+      break;
+    default:
+      jj_la1[58] = jj_gen;
+      ;
+    }
+    block = Block();
+                                                                                                    if(line==-1){line=block.getBeginLine(); column=block.getBeginColumn();}
+    {if (true) return new InitializerDeclaration(line, column, token.endLine, token.endColumn, isStatic, block);}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Type, name and expression syntax follows.
+ */
+  final public Type Type() {
+        Type ret;
+    if (jj_2_11(2)) {
+      ret = ReferenceType();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case SHORT:
+        ret = PrimitiveType();
+        break;
+      default:
+        jj_la1[59] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+   {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ReferenceType ReferenceType() {
+        Type type;
+        int arrayCount = 0;
+        List annotations = null;
+        List accum= null;
+        AnnotationExpr ann;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:
+      type = PrimitiveType();
+      label_27:
+      while (true) {
+        label_28:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case AT:
+            ;
+            break;
+          default:
+            jj_la1[60] = jj_gen;
+            break label_28;
+          }
+          ann = Annotation();
+                                                                  annotations = add(annotations, ann);
+        }
+        jj_consume_token(LBRACKET);
+        jj_consume_token(RBRACKET);
+                                                                                                                      arrayCount++; accum = add(accum, annotations); annotations= null;
+        if (jj_2_12(2)) {
+          ;
+        } else {
+          break label_27;
+        }
+      }
+      break;
+    case IDENTIFIER:
+      type = ClassOrInterfaceType();
+      label_29:
+      while (true) {
+        if (jj_2_13(2)) {
+          ;
+        } else {
+          break label_29;
+        }
+        label_30:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case AT:
+            ;
+            break;
+          default:
+            jj_la1[61] = jj_gen;
+            break label_30;
+          }
+          ann = Annotation();
+                                                                         annotations = add(annotations, ann);
+        }
+        jj_consume_token(LBRACKET);
+        jj_consume_token(RBRACKET);
+                                                                                                                             arrayCount++; accum = add(accum, annotations); annotations= null;
+      }
+      break;
+    default:
+      jj_la1[62] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return new ReferenceType(type.getBeginLine(), type.getBeginColumn(), token.endLine, token.endColumn, type, arrayCount, null, accum);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ClassOrInterfaceType ClassOrInterfaceType() {
+        ClassOrInterfaceType ret;
+        String name;
+        List typeArgs = null;
+        int line;
+        int column;
+        List annotations = null;
+        AnnotationExpr ann;
+    jj_consume_token(IDENTIFIER);
+                line=token.beginLine; column=token.beginColumn;
+                                                                   name = token.image;
+    if (jj_2_14(2)) {
+      typeArgs = TypeArguments();
+                                             typeArgs.remove(0);
+    } else {
+      ;
+    }
+    ret = new ClassOrInterfaceType(line, column, token.endLine, token.endColumn,null, name, typeArgs);
+    label_31:
+    while (true) {
+      if (jj_2_15(2)) {
+        ;
+      } else {
+        break label_31;
+      }
+      jj_consume_token(DOT);
+      label_32:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case AT:
+          ;
+          break;
+        default:
+          jj_la1[63] = jj_gen;
+          break label_32;
+        }
+        ann = Annotation();
+                                                   annotations = add(annotations, ann);
+      }
+      jj_consume_token(IDENTIFIER);
+                                                                                                           name = token.image;
+      if (jj_2_16(2)) {
+        typeArgs = TypeArguments();
+                                                     typeArgs.remove(0);
+      } else {
+        ;
+      }
+                                                                              ret = new ClassOrInterfaceType(line, column, token.endLine, token.endColumn,ret, name, typeArgs); ret.setAnnotations(annotations); annotations = null;
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List TypeArguments() {
+        List ret = new LinkedList();
+        Type type;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LT:
+      jj_consume_token(LT);
+           ret.add(new int[]{token.beginLine, token.beginColumn});
+      type = TypeArgument();
+                             ret.add(type);
+      label_33:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case COMMA:
+          ;
+          break;
+        default:
+          jj_la1[64] = jj_gen;
+          break label_33;
+        }
+        jj_consume_token(COMMA);
+        type = TypeArgument();
+                                                                            ret.add(type);
+      }
+      jj_consume_token(GT);
+     {if (true) return ret;}
+      break;
+    case 132:
+      jj_consume_token(132);
+          ret.add(null);
+     {if (true) return ret;}
+      break;
+    default:
+      jj_la1[65] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Type TypeArgument() {
+        Type ret;
+        List annotations = null;
+        AnnotationExpr ann;
+    label_34:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[66] = jj_gen;
+        break label_34;
+      }
+      ann = Annotation();
+                          annotations = add(annotations, ann);
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:
+    case IDENTIFIER:
+      ret = ReferenceType();
+      break;
+    case HOOK:
+      ret = Wildcard();
+      break;
+    default:
+      jj_la1[67] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+   ret.setAnnotations(annotations); {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public WildcardType Wildcard() {
+        ReferenceType ext = null;
+        ReferenceType sup = null;
+        int line;
+        int column;
+        AnnotationExpr ann;
+        List annotations = null;
+    jj_consume_token(HOOK);
+        line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case EXTENDS:
+    case SUPER:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case EXTENDS:
+        jj_consume_token(EXTENDS);
+        label_35:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case AT:
+            ;
+            break;
+          default:
+            jj_la1[68] = jj_gen;
+            break label_35;
+          }
+          ann = Annotation();
+                                                  annotations = add(annotations, ann);
+        }
+        ext = ReferenceType();
+                  ext.setAnnotations(annotations);
+        break;
+      case SUPER:
+        jj_consume_token(SUPER);
+        label_36:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case AT:
+            ;
+            break;
+          default:
+            jj_la1[69] = jj_gen;
+            break label_36;
+          }
+          ann = Annotation();
+                                                annotations = add(annotations, ann);
+        }
+        sup = ReferenceType();
+                  sup.setAnnotations(annotations);
+        break;
+      default:
+        jj_la1[70] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    default:
+      jj_la1[71] = jj_gen;
+      ;
+    }
+     {if (true) return new WildcardType(line, column, token.endLine, token.endColumn,ext, sup);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public PrimitiveType PrimitiveType() {
+        PrimitiveType ret;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+      jj_consume_token(BOOLEAN);
+              ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Boolean);
+      break;
+    case CHAR:
+      jj_consume_token(CHAR);
+           ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Char);
+      break;
+    case BYTE:
+      jj_consume_token(BYTE);
+           ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Byte);
+      break;
+    case SHORT:
+      jj_consume_token(SHORT);
+            ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Short);
+      break;
+    case INT:
+      jj_consume_token(INT);
+          ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Int);
+      break;
+    case LONG:
+      jj_consume_token(LONG);
+           ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Long);
+      break;
+    case FLOAT:
+      jj_consume_token(FLOAT);
+            ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Float);
+      break;
+    case DOUBLE:
+      jj_consume_token(DOUBLE);
+             ret = new PrimitiveType(token.beginLine, token.beginColumn, token.endLine, token.endColumn, PrimitiveType.Primitive.Double);
+      break;
+    default:
+      jj_la1[72] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Type ResultType() {
+        Type ret;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case VOID:
+      jj_consume_token(VOID);
+                   ret = new VoidType(token.beginLine, token.beginColumn, token.endLine, token.endColumn);
+      break;
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:
+    case IDENTIFIER:
+      ret = Type();
+      break;
+    default:
+      jj_la1[73] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public NameExpr Name() {
+        NameExpr ret;
+    jj_consume_token(IDENTIFIER);
+                 ret = new NameExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image);
+    label_37:
+    while (true) {
+      if (jj_2_17(2)) {
+        ;
+      } else {
+        break label_37;
+      }
+      jj_consume_token(DOT);
+      jj_consume_token(IDENTIFIER);
+                                    ret = new QualifiedNameExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, token.image);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ClassOrInterfaceTypeList() {
+        List ret = new LinkedList();
+        ClassOrInterfaceType type;
+        List annotations= null;
+        AnnotationExpr ann;
+    label_38:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[74] = jj_gen;
+        break label_38;
+      }
+      ann = Annotation();
+                          annotations = add(annotations, ann);
+    }
+    type = ClassOrInterfaceType();
+                                                                                                    type.setAnnotations(annotations); ret.add(type); annotations=null;
+    label_39:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[75] = jj_gen;
+        break label_39;
+      }
+      jj_consume_token(COMMA);
+      label_40:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case AT:
+          ;
+          break;
+        default:
+          jj_la1[76] = jj_gen;
+          break label_40;
+        }
+        ann = Annotation();
+                                                                                                                                                                                                       annotations = add(annotations, ann);
+      }
+      type = ClassOrInterfaceType();
+                                                                                                                                                                                                                                                                                 type.setAnnotations(annotations); ret.add(type); annotations=null;
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public NameExpr SimpleName() {
+    NameExpr ret;
+    jj_consume_token(IDENTIFIER);
+                 ret = new NameExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image);
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List NameList() {
+        List ret = new LinkedList();
+        NameExpr name;
+    name = Name();
+                  ret.add(name);
+    label_41:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[77] = jj_gen;
+        break label_41;
+      }
+      jj_consume_token(COMMA);
+      name = Name();
+                                                          ret.add(name);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Expression syntax follows.
+ */
+  final public Expression Expression() {
+        Expression ret;
+        AssignExpr.Operator op;
+        Expression value;
+        Statement lambdaBody = null;
+        List params = null;
+        List typeArgs = null;
+        VariableDeclaratorId id = null;
+        Expression inner = null;
+    ret = ConditionalExpression();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ASSIGN:
+    case PLUSASSIGN:
+    case MINUSASSIGN:
+    case STARASSIGN:
+    case SLASHASSIGN:
+    case ANDASSIGN:
+    case ORASSIGN:
+    case XORASSIGN:
+    case REMASSIGN:
+    case LSHIFTASSIGN:
+    case RSIGNEDSHIFTASSIGN:
+    case RUNSIGNEDSHIFTASSIGN:
+    case ARROW:
+    case DOUBLECOLON:
+      if (jj_2_18(2)) {
+        op = AssignmentOperator();
+        value = Expression();
+                                                     ret = new AssignExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, value, op);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case ARROW:
+          jj_consume_token(ARROW);
+          lambdaBody = LambdaBody();
+     if (ret instanceof CastExpr)
+     {
+       inner = generateLambda(((CastExpr)ret).getExpr(), lambdaBody);
+       ((CastExpr)ret).setExpr(inner);
+     }
+     else if (ret instanceof ConditionalExpr){
+         ConditionalExpr ce = (ConditionalExpr) ret;
+         if(ce.getElseExpr() != null){
+            ce.setElseExpr(generateLambda(ce.getElseExpr(), lambdaBody));
+         }
+     }
+     else
+     {
+       ret = generateLambda(ret, lambdaBody);
+     }
+          break;
+        case DOUBLECOLON:
+          jj_consume_token(DOUBLECOLON);
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case LT:
+            typeArgs = TypeParameters();
+                                        typeArgs.remove(0);
+            break;
+          default:
+            jj_la1[78] = jj_gen;
+            ;
+          }
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case IDENTIFIER:
+            jj_consume_token(IDENTIFIER);
+            break;
+          case NEW:
+            jj_consume_token(NEW);
+            break;
+          default:
+            jj_la1[79] = jj_gen;
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+   ret = new MethodReferenceExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, typeArgs, token.image);
+          break;
+        default:
+          jj_la1[80] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      break;
+    default:
+      jj_la1[81] = jj_gen;
+      ;
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public AssignExpr.Operator AssignmentOperator() {
+        AssignExpr.Operator ret;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ASSIGN:
+      jj_consume_token(ASSIGN);
+               ret = AssignExpr.Operator.assign;
+      break;
+    case STARASSIGN:
+      jj_consume_token(STARASSIGN);
+               ret = AssignExpr.Operator.star;
+      break;
+    case SLASHASSIGN:
+      jj_consume_token(SLASHASSIGN);
+               ret = AssignExpr.Operator.slash;
+      break;
+    case REMASSIGN:
+      jj_consume_token(REMASSIGN);
+               ret = AssignExpr.Operator.rem;
+      break;
+    case PLUSASSIGN:
+      jj_consume_token(PLUSASSIGN);
+               ret = AssignExpr.Operator.plus;
+      break;
+    case MINUSASSIGN:
+      jj_consume_token(MINUSASSIGN);
+               ret = AssignExpr.Operator.minus;
+      break;
+    case LSHIFTASSIGN:
+      jj_consume_token(LSHIFTASSIGN);
+               ret = AssignExpr.Operator.lShift;
+      break;
+    case RSIGNEDSHIFTASSIGN:
+      jj_consume_token(RSIGNEDSHIFTASSIGN);
+               ret = AssignExpr.Operator.rSignedShift;
+      break;
+    case RUNSIGNEDSHIFTASSIGN:
+      jj_consume_token(RUNSIGNEDSHIFTASSIGN);
+               ret = AssignExpr.Operator.rUnsignedShift;
+      break;
+    case ANDASSIGN:
+      jj_consume_token(ANDASSIGN);
+               ret = AssignExpr.Operator.and;
+      break;
+    case XORASSIGN:
+      jj_consume_token(XORASSIGN);
+               ret = AssignExpr.Operator.xor;
+      break;
+    case ORASSIGN:
+      jj_consume_token(ORASSIGN);
+               ret = AssignExpr.Operator.or;
+      break;
+    default:
+      jj_la1[82] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression ConditionalExpression() {
+        Expression ret;
+        Expression left;
+        Expression right;
+    ret = ConditionalOrExpression();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case HOOK:
+      jj_consume_token(HOOK);
+      left = Expression();
+      jj_consume_token(COLON);
+      right = ConditionalExpression();
+                                                                  ret = new ConditionalExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, left, right);
+      break;
+    default:
+      jj_la1[83] = jj_gen;
+      ;
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression ConditionalOrExpression() {
+        Expression ret;
+        Expression right;
+    ret = ConditionalAndExpression();
+    label_42:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case SC_OR:
+        ;
+        break;
+      default:
+        jj_la1[84] = jj_gen;
+        break label_42;
+      }
+      jj_consume_token(SC_OR);
+      right = ConditionalAndExpression();
+                                                                               ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, BinaryExpr.Operator.or);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression ConditionalAndExpression() {
+        Expression ret;
+        Expression right;
+    ret = InclusiveOrExpression();
+    label_43:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case SC_AND:
+        ;
+        break;
+      default:
+        jj_la1[85] = jj_gen;
+        break label_43;
+      }
+      jj_consume_token(SC_AND);
+      right = InclusiveOrExpression();
+                                                                         ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, BinaryExpr.Operator.and);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression InclusiveOrExpression() {
+        Expression ret;
+        Expression right;
+    ret = ExclusiveOrExpression();
+    label_44:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case BIT_OR:
+        ;
+        break;
+      default:
+        jj_la1[86] = jj_gen;
+        break label_44;
+      }
+      jj_consume_token(BIT_OR);
+      right = ExclusiveOrExpression();
+                                                                        ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, BinaryExpr.Operator.binOr);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression ExclusiveOrExpression() {
+        Expression ret;
+        Expression right;
+    ret = AndExpression();
+    label_45:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case XOR:
+        ;
+        break;
+      default:
+        jj_la1[87] = jj_gen;
+        break label_45;
+      }
+      jj_consume_token(XOR);
+      right = AndExpression();
+                                                        ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, BinaryExpr.Operator.xor);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression AndExpression() {
+        Expression ret;
+        Expression right;
+    ret = EqualityExpression();
+    label_46:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case BIT_AND:
+        ;
+        break;
+      default:
+        jj_la1[88] = jj_gen;
+        break label_46;
+      }
+      jj_consume_token(BIT_AND);
+      right = EqualityExpression();
+                                                                  ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, BinaryExpr.Operator.binAnd);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression EqualityExpression() {
+        Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = InstanceOfExpression();
+    label_47:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case EQ:
+      case NE:
+        ;
+        break;
+      default:
+        jj_la1[89] = jj_gen;
+        break label_47;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case EQ:
+        jj_consume_token(EQ);
+             op = BinaryExpr.Operator.equals;
+        break;
+      case NE:
+        jj_consume_token(NE);
+             op = BinaryExpr.Operator.notEquals;
+        break;
+      default:
+        jj_la1[90] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = InstanceOfExpression();
+                                       ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, op);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression InstanceOfExpression() {
+        Expression ret;
+        Type type;
+    ret = RelationalExpression();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INSTANCEOF:
+      jj_consume_token(INSTANCEOF);
+      type = Type();
+                                                              ret = new InstanceOfExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, type);
+      break;
+    default:
+      jj_la1[91] = jj_gen;
+      ;
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression RelationalExpression() {
+        Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = ShiftExpression();
+    label_48:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LT:
+      case LE:
+      case GE:
+      case GT:
+        ;
+        break;
+      default:
+        jj_la1[92] = jj_gen;
+        break label_48;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LT:
+        jj_consume_token(LT);
+                 op = BinaryExpr.Operator.less;
+        break;
+      case GT:
+        jj_consume_token(GT);
+                 op = BinaryExpr.Operator.greater;
+        break;
+      case LE:
+        jj_consume_token(LE);
+                 op = BinaryExpr.Operator.lessEquals;
+        break;
+      case GE:
+        jj_consume_token(GE);
+                 op = BinaryExpr.Operator.greaterEquals;
+        break;
+      default:
+        jj_la1[93] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = ShiftExpression();
+                                      ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, op);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression ShiftExpression() {
+        Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = AdditiveExpression();
+    label_49:
+    while (true) {
+      if (jj_2_19(1)) {
+        ;
+      } else {
+        break label_49;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LSHIFT:
+        jj_consume_token(LSHIFT);
+                             op = BinaryExpr.Operator.lShift;
+        break;
+      default:
+        jj_la1[94] = jj_gen;
+        if (jj_2_20(1)) {
+          RSIGNEDSHIFT();
+                             op = BinaryExpr.Operator.rSignedShift;
+        } else if (jj_2_21(1)) {
+          RUNSIGNEDSHIFT();
+                             op = BinaryExpr.Operator.rUnsignedShift;
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      right = AdditiveExpression();
+                                         ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, op);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression AdditiveExpression() {
+        Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = MultiplicativeExpression();
+    label_50:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case PLUS:
+      case MINUS:
+        ;
+        break;
+      default:
+        jj_la1[95] = jj_gen;
+        break label_50;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case PLUS:
+        jj_consume_token(PLUS);
+                op = BinaryExpr.Operator.plus;
+        break;
+      case MINUS:
+        jj_consume_token(MINUS);
+                op = BinaryExpr.Operator.minus;
+        break;
+      default:
+        jj_la1[96] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = MultiplicativeExpression();
+                                               ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, op);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression MultiplicativeExpression() {
+        Expression ret;
+        Expression right;
+        BinaryExpr.Operator op;
+    ret = UnaryExpression();
+    label_51:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case STAR:
+      case SLASH:
+      case REM:
+        ;
+        break;
+      default:
+        jj_la1[97] = jj_gen;
+        break label_51;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case STAR:
+        jj_consume_token(STAR);
+                op = BinaryExpr.Operator.times;
+        break;
+      case SLASH:
+        jj_consume_token(SLASH);
+                op = BinaryExpr.Operator.divide;
+        break;
+      case REM:
+        jj_consume_token(REM);
+                op = BinaryExpr.Operator.remainder;
+        break;
+      default:
+        jj_la1[98] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      right = UnaryExpression();
+                                      ret = new BinaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, right, op);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression UnaryExpression() {
+        Expression ret;
+        UnaryExpr.Operator op;
+        int line = 0;
+        int column = 0;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INCR:
+      ret = PreIncrementExpression();
+      break;
+    case DECR:
+      ret = PreDecrementExpression();
+      break;
+    case PLUS:
+    case MINUS:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case PLUS:
+        jj_consume_token(PLUS);
+                  op = UnaryExpr.Operator.positive; line=token.beginLine; column=token.beginColumn;
+        break;
+      case MINUS:
+        jj_consume_token(MINUS);
+                  op = UnaryExpr.Operator.negative; line=token.beginLine; column=token.beginColumn;
+        break;
+      default:
+        jj_la1[99] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      ret = UnaryExpression();
+                 if(op == UnaryExpr.Operator.negative) {
+                        if (ret instanceof IntegerLiteralExpr && ((IntegerLiteralExpr)ret).isMinValue()) {
+                                ret = new IntegerLiteralMinValueExpr(line, column, token.endLine, token.endColumn);
+                        } else if (ret instanceof LongLiteralExpr && ((LongLiteralExpr)ret).isMinValue()) {
+                                ret = new LongLiteralMinValueExpr(line, column, token.endLine, token.endColumn);
+                        } else {
+                                ret = new UnaryExpr(line, column, token.endLine, token.endColumn,ret, op);
+                        }
+                 } else {
+                        ret = new UnaryExpr(line, column, token.endLine, token.endColumn,ret, op);
+                 }
+      break;
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+      ret = UnaryExpressionNotPlusMinus();
+      break;
+    default:
+      jj_la1[100] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PreIncrementExpression() {
+        Expression ret;
+        int line;
+        int column;
+    jj_consume_token(INCR);
+        line=token.beginLine; column=token.beginColumn;
+    ret = UnaryExpression();
+                                                                                   ret = new UnaryExpr(line, column, token.endLine, token.endColumn,ret, UnaryExpr.Operator.preIncrement);
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PreDecrementExpression() {
+        Expression ret;
+        int line;
+        int column;
+    jj_consume_token(DECR);
+        line=token.beginLine; column=token.beginColumn;
+    ret = UnaryExpression();
+                                                                                   ret = new UnaryExpr(line, column, token.endLine, token.endColumn,ret, UnaryExpr.Operator.preDecrement);
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression UnaryExpressionNotPlusMinus() {
+        Expression ret;
+        UnaryExpr.Operator op;
+        int line = 0;
+        int column = 0;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BANG:
+    case TILDE:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case TILDE:
+        jj_consume_token(TILDE);
+                  op = UnaryExpr.Operator.inverse; line=token.beginLine; column=token.beginColumn;
+        break;
+      case BANG:
+        jj_consume_token(BANG);
+                  op = UnaryExpr.Operator.not;     line=token.beginLine; column=token.beginColumn;
+        break;
+      default:
+        jj_la1[101] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      ret = UnaryExpression();
+                                      ret = new UnaryExpr(line, column, token.endLine, token.endColumn,ret, op);
+      break;
+    default:
+      jj_la1[102] = jj_gen;
+      if (jj_2_22(2147483647)) {
+        ret = CastExpression();
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NEW:
+        case NULL:
+        case SHORT:
+        case SUPER:
+        case THIS:
+        case TRUE:
+        case VOID:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:
+          ret = PostfixExpression();
+          break;
+        default:
+          jj_la1[103] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PostfixExpression() {
+        Expression ret;
+        UnaryExpr.Operator op;
+    ret = PrimaryExpression();
+    if (jj_2_23(2)) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case INCR:
+        jj_consume_token(INCR);
+             op = UnaryExpr.Operator.posIncrement;
+        break;
+      case DECR:
+        jj_consume_token(DECR);
+             op = UnaryExpr.Operator.posDecrement;
+        break;
+      default:
+        jj_la1[104] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+        ret = new UnaryExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, op);
+    } else {
+      ;
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression CastExpression() {
+        Expression ret;
+        Type type;
+        int line;
+        int column;
+        AnnotationExpr ann;
+        List annotations = null;
+    jj_consume_token(LPAREN);
+       line=token.beginLine; column=token.beginColumn;
+    label_52:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[105] = jj_gen;
+        break label_52;
+      }
+      ann = Annotation();
+                           annotations = add(annotations, ann);
+    }
+    if (jj_2_24(2)) {
+      type = PrimitiveType();
+      jj_consume_token(RPAREN);
+      ret = UnaryExpression();
+                                                               type.setAnnotations(annotations); ret = new CastExpr(line, column, token.endLine, token.endColumn,type, ret);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case SHORT:
+      case IDENTIFIER:
+        type = ReferenceType();
+        jj_consume_token(RPAREN);
+        ret = UnaryExpressionNotPlusMinus();
+                                                                           type.setAnnotations(annotations); ret = new CastExpr(line, column, token.endLine, token.endColumn,type, ret);
+        break;
+      default:
+        jj_la1[106] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PrimaryExpression() {
+        Expression ret;
+        Expression inner;
+    ret = PrimaryPrefix();
+    label_53:
+    while (true) {
+      if (jj_2_25(2)) {
+        ;
+      } else {
+        break label_53;
+      }
+      ret = PrimarySuffix(ret);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PrimaryExpressionWithoutSuperSuffix() {
+        Expression ret;
+        Expression inner;
+    ret = PrimaryPrefix();
+    label_54:
+    while (true) {
+      if (jj_2_26(2147483647)) {
+        ;
+      } else {
+        break label_54;
+      }
+      ret = PrimarySuffixWithoutSuper(ret);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PrimaryPrefix() {
+        Expression ret = null;
+        NameExpr name;
+        List typeArgs = null;
+        List args = null;
+        boolean hasArgs = false;
+        boolean isLambda = false;
+        Type type;
+        int line;
+        int column;
+        Parameter p = null;
+        VariableDeclaratorId id = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case FALSE:
+    case NULL:
+    case TRUE:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+      ret = Literal();
+      break;
+    case THIS:
+      jj_consume_token(THIS);
+                   ret = new ThisExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, null);
+      break;
+    case SUPER:
+      jj_consume_token(SUPER);
+                    ret = new SuperExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, null);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case DOT:
+        jj_consume_token(DOT);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case LT:
+        case 132:
+          typeArgs = TypeArguments();
+                                        typeArgs.remove(0);
+          break;
+        default:
+          jj_la1[107] = jj_gen;
+          ;
+        }
+        name = SimpleName();
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case LPAREN:
+          args = Arguments();
+                                hasArgs=true;
+          break;
+        default:
+          jj_la1[108] = jj_gen;
+          ;
+        }
+                        if (hasArgs) {
+                                MethodCallExpr m = new MethodCallExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, typeArgs, null, args);
+                                m.setNameExpr(name);
+                                ret = m;
+                        } else {
+                                FieldAccessExpr f = new FieldAccessExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, null, null);
+                                f.setFieldExpr(name);
+                                ret = f;
+                        }
+        break;
+      case DOUBLECOLON:
+        jj_consume_token(DOUBLECOLON);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case LT:
+          typeArgs = TypeParameters();
+                                                    typeArgs.remove(0);
+          break;
+        default:
+          jj_la1[109] = jj_gen;
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case IDENTIFIER:
+          jj_consume_token(IDENTIFIER);
+          break;
+        case NEW:
+          jj_consume_token(NEW);
+          break;
+        default:
+          jj_la1[110] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+                  ret = new MethodReferenceExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, typeArgs, token.image);
+        break;
+      case LPAREN:
+        args = Arguments();
+                             new MethodCallExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, typeArgs, null, args);
+        break;
+      default:
+        jj_la1[111] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    case LPAREN:
+      jj_consume_token(LPAREN);
+               line=token.beginLine; column=token.beginColumn;
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NATIVE:
+      case NEW:
+      case NULL:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SUPER:
+      case SYNCHRONIZED:
+      case THIS:
+      case TRANSIENT:
+      case TRUE:
+      case VOID:
+      case VOLATILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case AT:
+      case BANG:
+      case TILDE:
+      case INCR:
+      case DECR:
+      case PLUS:
+      case MINUS:
+        if (jj_2_27(2147483647)) {
+          p = FormalParameter();
+                                                                       isLambda = true;
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case COMMA:
+            args = FormalLambdaParameters();
+            break;
+          default:
+            jj_la1[112] = jj_gen;
+            ;
+          }
+        } else {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case BOOLEAN:
+          case BYTE:
+          case CHAR:
+          case DOUBLE:
+          case FALSE:
+          case FLOAT:
+          case INT:
+          case LONG:
+          case NEW:
+          case NULL:
+          case SHORT:
+          case SUPER:
+          case THIS:
+          case TRUE:
+          case VOID:
+          case LONG_LITERAL:
+          case INTEGER_LITERAL:
+          case FLOATING_POINT_LITERAL:
+          case CHARACTER_LITERAL:
+          case STRING_LITERAL:
+          case IDENTIFIER:
+          case LPAREN:
+          case BANG:
+          case TILDE:
+          case INCR:
+          case DECR:
+          case PLUS:
+          case MINUS:
+            ret = Expression();
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case COMMA:
+              args = InferredLambdaParameters();
+                                                                          isLambda = true;
+              break;
+            default:
+              jj_la1[113] = jj_gen;
+              ;
+            }
+            break;
+          default:
+            jj_la1[114] = jj_gen;
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+        }
+        break;
+      default:
+        jj_la1[115] = jj_gen;
+        ;
+      }
+      jj_consume_token(RPAREN);
+                           if(!isLambda) { ret = new EnclosedExpr(line, column, token.endLine, token.endColumn,ret);}
+                           else{
+                                  if(ret != null){
+                                          if(ret instanceof NameExpr)
+                                          {
+                                            id = new VariableDeclaratorId(ret.getBeginLine(), ret.getBeginColumn(), ret.getEndLine(), ret.getEndColumn(), ((NameExpr)ret).getName(), 0);
+                                            p = new Parameter(ret.getBeginLine(), ret.getBeginColumn(), ret.getEndLine(), ret.getEndColumn(), 0, null, new UnknownType(), false, id);
+                                          }
+
+                                        }
+                                        args = add(0, args, p);
+                                        ret = new LambdaExpr(p.getBeginLine(), p.getBeginColumn(), token.endLine, token.endColumn, args, null, true);
+                                }
+      break;
+    case NEW:
+      ret = AllocationExpression(null);
+      break;
+    default:
+      jj_la1[119] = jj_gen;
+      if (jj_2_28(2147483647)) {
+        type = ResultType();
+        jj_consume_token(DOT);
+        jj_consume_token(CLASS);
+                                             ret = new ClassExpr(type.getBeginLine(), type.getBeginColumn(), token.endLine, token.endColumn, type);
+      } else if (jj_2_29(2147483647)) {
+        type = ResultType();
+        jj_consume_token(DOUBLECOLON);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case LT:
+          typeArgs = TypeParameters();
+                                                                  typeArgs.remove(0);
+          break;
+        default:
+          jj_la1[116] = jj_gen;
+          ;
+        }
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case IDENTIFIER:
+          jj_consume_token(IDENTIFIER);
+          break;
+        case NEW:
+          jj_consume_token(NEW);
+          break;
+        default:
+          jj_la1[117] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+                  ret = new TypeExpr(type.getBeginLine(), type.getBeginColumn(), type.getEndLine(), type.getEndColumn(), type);
+                  ret = new MethodReferenceExpr(ret.getBeginLine(), ret.getBeginColumn(), token.endLine, token.endColumn, ret, typeArgs, token.image);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case IDENTIFIER:
+          name = SimpleName();
+                                      line=token.beginLine; column=token.beginColumn;
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case LPAREN:
+            args = Arguments();
+                                      hasArgs=true;
+            break;
+          default:
+            jj_la1[118] = jj_gen;
+            ;
+          }
+                        if (hasArgs) {
+                                MethodCallExpr m = new MethodCallExpr(line, column, token.endLine, token.endColumn, null, null, null, args);
+                                m.setNameExpr(name);
+                                ret = m;
+                        } else {
+                                ret = name;
+                        }
+          break;
+        default:
+          jj_la1[120] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PrimarySuffix(Expression scope) {
+        Expression ret;
+    if (jj_2_30(2)) {
+      ret = PrimarySuffixWithoutSuper(scope);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case DOT:
+        jj_consume_token(DOT);
+        jj_consume_token(SUPER);
+                      ret = new SuperExpr(scope.getBeginLine(), scope.getBeginColumn(), token.endLine, token.endColumn, scope);
+        break;
+      default:
+        jj_la1[121] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression PrimarySuffixWithoutSuper(Expression scope) {
+        Expression ret;
+        List typeArgs = null;
+        List args = null;
+        boolean hasArgs = false;
+        NameExpr name;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case DOT:
+      jj_consume_token(DOT);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case THIS:
+        jj_consume_token(THIS);
+                         ret = new ThisExpr(scope.getBeginLine(), scope.getBeginColumn(), token.endLine, token.endColumn, scope);
+        break;
+      case NEW:
+        ret = AllocationExpression(scope);
+        break;
+      default:
+        jj_la1[124] = jj_gen;
+        if (jj_2_31(2147483647)) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case LT:
+          case 132:
+            typeArgs = TypeArguments();
+                                              typeArgs.remove(0);
+            break;
+          default:
+            jj_la1[122] = jj_gen;
+            ;
+          }
+          name = SimpleName();
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case LPAREN:
+            args = Arguments();
+                                      hasArgs=true;
+            break;
+          default:
+            jj_la1[123] = jj_gen;
+            ;
+          }
+                        if (hasArgs) {
+                                MethodCallExpr m = new MethodCallExpr(scope.getBeginLine(), scope.getBeginColumn(), token.endLine, token.endColumn, scope, typeArgs, null, args);
+                                m.setNameExpr(name);
+                                ret = m;
+                        } else {
+                                FieldAccessExpr f =  new FieldAccessExpr(scope.getBeginLine(), scope.getBeginColumn(), token.endLine, token.endColumn, scope, typeArgs, null);
+                                f.setFieldExpr(name);
+                                ret = f;
+                        }
+        } else {
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      break;
+    case LBRACKET:
+      jj_consume_token(LBRACKET);
+      ret = Expression();
+      jj_consume_token(RBRACKET);
+                                      ret = new ArrayAccessExpr(scope.getBeginLine(), scope.getBeginColumn(), token.endLine, token.endColumn, scope, ret);
+      break;
+    default:
+      jj_la1[125] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression Literal() {
+        Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case INTEGER_LITERAL:
+      jj_consume_token(INTEGER_LITERAL);
+                        ret = new IntegerLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image);
+      break;
+    case LONG_LITERAL:
+      jj_consume_token(LONG_LITERAL);
+                        ret = new LongLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image);
+      break;
+    case FLOATING_POINT_LITERAL:
+      jj_consume_token(FLOATING_POINT_LITERAL);
+                        ret = new DoubleLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image);
+      break;
+    case CHARACTER_LITERAL:
+      jj_consume_token(CHARACTER_LITERAL);
+                ret = new CharLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image.substring(1, token.image.length()-1));
+      break;
+    case STRING_LITERAL:
+      jj_consume_token(STRING_LITERAL);
+                ret = new StringLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, token.image.substring(1, token.image.length()-1));
+      break;
+    case FALSE:
+    case TRUE:
+      ret = BooleanLiteral();
+      break;
+    case NULL:
+      ret = NullLiteral();
+      break;
+    default:
+      jj_la1[126] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression BooleanLiteral() {
+        Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case TRUE:
+      jj_consume_token(TRUE);
+                   ret = new BooleanLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, true);
+      break;
+    case FALSE:
+      jj_consume_token(FALSE);
+                    ret = new BooleanLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn, false);
+      break;
+    default:
+      jj_la1[127] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression NullLiteral() {
+    jj_consume_token(NULL);
+    {if (true) return new NullLiteralExpr(token.beginLine, token.beginColumn, token.endLine, token.endColumn);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List Arguments() {
+        List ret = null;
+    jj_consume_token(LPAREN);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:
+      ret = ArgumentList();
+      break;
+    default:
+      jj_la1[128] = jj_gen;
+      ;
+    }
+    jj_consume_token(RPAREN);
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ArgumentList() {
+        List ret = new LinkedList();
+        Expression expr;
+    expr = Expression();
+                        ret.add(expr);
+    label_55:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[129] = jj_gen;
+        break label_55;
+      }
+      jj_consume_token(COMMA);
+      expr = Expression();
+                                                                     ret.add(expr);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression AllocationExpression(Expression scope) {
+        Expression ret;
+        ArrayCreationExpr arrayExpr;
+        Type type;
+        Object[] arr = null;
+        List typeArgs = null;
+        List anonymousBody = null;
+        List args;
+        int line;
+        int column;
+        List annotations = null;
+        AnnotationExpr ann;
+    jj_consume_token(NEW);
+          if(scope==null) {line=token.beginLine; column=token.beginColumn;} else {line=scope.getBeginLine(); column=scope.getBeginColumn();}
+    label_56:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[130] = jj_gen;
+        break label_56;
+      }
+      ann = Annotation();
+                          annotations = add(annotations, ann);
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case SHORT:
+      type = PrimitiveType();
+                                  type.setAnnotations(annotations);
+      arr = ArrayDimsAndInits();
+            arrayExpr = new ArrayCreationExpr(line, column, token.endLine, token.endColumn, type, null, 0);
+            arrayExpr.setArraysAnnotations((List)arr[2]);
+                if (arr[0] instanceof Integer) {
+                    arrayExpr.setArrayCount(((Integer)arr[0]).intValue());
+                    arrayExpr.setInitializer((ArrayInitializerExpr)arr[1]);
+                } else {
+                    arrayExpr.setArrayCount(((Integer)arr[1]).intValue());
+                    arrayExpr.setDimensions((List)arr[0]);
+                }
+                ret = arrayExpr;
+      break;
+    case IDENTIFIER:
+    case LT:
+    case 132:
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LT:
+      case 132:
+        typeArgs = TypeArguments();
+        label_57:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case AT:
+            ;
+            break;
+          default:
+            jj_la1[131] = jj_gen;
+            break label_57;
+          }
+          ann = Annotation();
+                                                               annotations = add(annotations, ann);
+        }
+                                                                                                        typeArgs.remove(0);
+        break;
+      default:
+        jj_la1[132] = jj_gen;
+        ;
+      }
+      type = ClassOrInterfaceType();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LBRACKET:
+      case AT:
+        arr = ArrayDimsAndInits();
+                                         type.setAnnotations(annotations); arrayExpr = new ArrayCreationExpr(line, column, token.endLine, token.endColumn, type, null, 0);
+                    arrayExpr.setArraysAnnotations((List)arr[2]);
+                        if (arr[0] instanceof Integer) {
+                                arrayExpr.setArrayCount(((Integer)arr[0]).intValue());
+                            arrayExpr.setInitializer((ArrayInitializerExpr)arr[1]);
+                        } else {
+                                arrayExpr.setArrayCount(((Integer)arr[1]).intValue());
+                            arrayExpr.setDimensions((List)arr[0]);
+                        }
+                        ret = arrayExpr;
+        break;
+      case LPAREN:
+        args = Arguments();
+        if (jj_2_32(2)) {
+          anonymousBody = ClassOrInterfaceBody(false);
+        } else {
+          ;
+        }
+                type.setAnnotations(annotations); ret = new ObjectCreationExpr(line, column, token.endLine, token.endColumn, scope, (ClassOrInterfaceType) type, typeArgs, args, anonymousBody);
+        break;
+      default:
+        jj_la1[133] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      break;
+    default:
+      jj_la1[134] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * The third LOOKAHEAD specification below is to parse to PrimarySuffix
+ * if there is an expression between the "[...]".
+ */
+  final public Object[] ArrayDimsAndInits() {
+        Object[] ret = new Object[3];
+        Expression expr;
+        List inits = null;
+        int i = 0;
+        List accum = null;
+        List annotations = null;
+        AnnotationExpr ann;
+    label_58:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[135] = jj_gen;
+        break label_58;
+      }
+      ann = Annotation();
+                          annotations = add(annotations, ann);
+    }
+    if (jj_2_35(2)) {
+      label_59:
+      while (true) {
+        jj_consume_token(LBRACKET);
+        expr = Expression();
+                                                   accum = add(accum, annotations); annotations=null; inits = add(inits, expr);
+        jj_consume_token(RBRACKET);
+        if (jj_2_33(2)) {
+          ;
+        } else {
+          break label_59;
+        }
+      }
+      label_60:
+      while (true) {
+        if (jj_2_34(2)) {
+          ;
+        } else {
+          break label_60;
+        }
+        label_61:
+        while (true) {
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case AT:
+            ;
+            break;
+          default:
+            jj_la1[136] = jj_gen;
+            break label_61;
+          }
+          ann = Annotation();
+                                                                                                                                                                                annotations = add(annotations, ann);
+        }
+        jj_consume_token(LBRACKET);
+        jj_consume_token(RBRACKET);
+                                                                                                                                                                                                                                    i++;
+      }
+                                                                                                                                                                                                                                                 accum = add(accum, annotations); annotations=null; ret[0] = inits; ret[1] = new Integer(i);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case LBRACKET:
+        label_62:
+        while (true) {
+          jj_consume_token(LBRACKET);
+          jj_consume_token(RBRACKET);
+                      i++;
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case LBRACKET:
+            ;
+            break;
+          default:
+            jj_la1[137] = jj_gen;
+            break label_62;
+          }
+        }
+        expr = ArrayInitializer();
+                                                            accum = add(accum, annotations);annotations=null;  ret[0] = new Integer(i); ret[1] = expr;
+        break;
+      default:
+        jj_la1[138] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    ret[2]=accum; {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Statement syntax follows.
+ */
+  final public Statement Statement() {
+        Statement ret;
+    if (jj_2_36(2)) {
+      ret = LabeledStatement();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ASSERT:
+        ret = AssertStatement();
+        break;
+      case LBRACE:
+        ret = Block();
+        break;
+      case SEMICOLON:
+        ret = EmptyStatement();
+        break;
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case INCR:
+      case DECR:
+        ret = StatementExpression();
+        break;
+      case SWITCH:
+        ret = SwitchStatement();
+        break;
+      case IF:
+        ret = IfStatement();
+        break;
+      case WHILE:
+        ret = WhileStatement();
+        break;
+      case DO:
+        ret = DoStatement();
+        break;
+      case FOR:
+        ret = ForStatement();
+        break;
+      case BREAK:
+        ret = BreakStatement();
+        break;
+      case CONTINUE:
+        ret = ContinueStatement();
+        break;
+      case RETURN:
+        ret = ReturnStatement();
+        break;
+      case THROW:
+        ret = ThrowStatement();
+        break;
+      case SYNCHRONIZED:
+        ret = SynchronizedStatement();
+        break;
+      case TRY:
+        ret = TryStatement();
+        break;
+      default:
+        jj_la1[139] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public AssertStmt AssertStatement() {
+        Expression check;
+        Expression msg = null;
+        int line;
+        int column;
+    jj_consume_token(ASSERT);
+            line=token.beginLine; column=token.beginColumn;
+    check = Expression();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case COLON:
+      jj_consume_token(COLON);
+      msg = Expression();
+      break;
+    default:
+      jj_la1[140] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+    {if (true) return new AssertStmt(line, column, token.endLine, token.endColumn,check, msg);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public LabeledStmt LabeledStatement() {
+        String label;
+        Statement stmt;
+        int line;
+        int column;
+    jj_consume_token(IDENTIFIER);
+                line=token.beginLine; column=token.beginColumn;
+                                                                   label = token.image;
+    jj_consume_token(COLON);
+    stmt = Statement();
+    {if (true) return new LabeledStmt(line, column, token.endLine, token.endColumn,label, stmt);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public BlockStmt Block() {
+        List stmts;
+        int beginLine;
+        int beginColumn;
+    jj_consume_token(LBRACE);
+       beginLine=token.beginLine; beginColumn=token.beginColumn;
+    stmts = Statements();
+    jj_consume_token(RBRACE);
+    {if (true) return new BlockStmt(beginLine, beginColumn, token.endLine, token.endColumn, stmts);}
+    throw new Error("Missing return statement in function");
+  }
+
+/*
+ * Classes inside block stametents can only be abstract or final. The semantic must check it.
+ */
+  final public Statement BlockStatement() {
+        Statement ret;
+        Expression expr;
+        ClassOrInterfaceDeclaration typeDecl;
+        Modifier modifier;
+    if (jj_2_37(2147483647)) {
+
+      modifier = Modifiers();
+      typeDecl = ClassOrInterfaceDeclaration(modifier);
+                                                             ret = new TypeDeclarationStmt(typeDecl.getBeginLine(), typeDecl.getBeginColumn(), token.endLine, token.endColumn, typeDecl);
+    } else if (jj_2_38(2147483647)) {
+      expr = VariableDeclarationExpression();
+      jj_consume_token(SEMICOLON);
+            ret = new ExpressionStmt(expr.getBeginLine(), expr.getBeginColumn(), token.endLine, token.endColumn, expr);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ASSERT:
+      case BOOLEAN:
+      case BREAK:
+      case BYTE:
+      case CHAR:
+      case CONTINUE:
+      case DO:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case FOR:
+      case IF:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case RETURN:
+      case SHORT:
+      case SUPER:
+      case SWITCH:
+      case SYNCHRONIZED:
+      case THIS:
+      case THROW:
+      case TRUE:
+      case TRY:
+      case VOID:
+      case WHILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case LBRACE:
+      case SEMICOLON:
+      case INCR:
+      case DECR:
+        ret = Statement();
+        break;
+      default:
+        jj_la1[141] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public VariableDeclarationExpr VariableDeclarationExpression() {
+        Modifier modifier;
+        Type type;
+        List vars = new LinkedList();
+        VariableDeclarator var;
+    modifier = Modifiers();
+    type = Type();
+    var = VariableDeclarator();
+                                                                    vars.add(var);
+    label_63:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[142] = jj_gen;
+        break label_63;
+      }
+      jj_consume_token(COMMA);
+      var = VariableDeclarator();
+                                                                                                                        vars.add(var);
+    }
+    int line = modifier.beginLine;
+    int column = modifier.beginColumn;
+    if(line==-1) {line=type.getBeginLine(); column=type.getBeginColumn(); }
+    {if (true) return new VariableDeclarationExpr(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, type, vars);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public EmptyStmt EmptyStatement() {
+    jj_consume_token(SEMICOLON);
+    {if (true) return new EmptyStmt(token.beginLine, token.beginColumn, token.endLine, token.endColumn);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Statement LambdaBody() {
+  Expression expr;
+  Statement n = null;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:
+      expr = Expression();
+          n = new ExpressionStmt(expr.getBeginLine(), expr.getBeginColumn(), token.endLine, token.endColumn, expr);
+      break;
+    case LBRACE:
+      n = Block();
+      break;
+    default:
+      jj_la1[143] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+        {if (true) return n;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ExpressionStmt StatementExpression() {
+        Expression expr;
+        AssignExpr.Operator op;
+        Expression value;
+        Type type;
+        List typeArgs = null;
+        Statement lambdaBody = null;
+        VariableDeclaratorId id = null;
+        List params = null;
+        Expression inner = null;
+    if (jj_2_39(2)) {
+      expr = PreIncrementExpression();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case DECR:
+        expr = PreDecrementExpression();
+        break;
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+        expr = PrimaryExpression();
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case ASSIGN:
+        case INCR:
+        case DECR:
+        case PLUSASSIGN:
+        case MINUSASSIGN:
+        case STARASSIGN:
+        case SLASHASSIGN:
+        case ANDASSIGN:
+        case ORASSIGN:
+        case XORASSIGN:
+        case REMASSIGN:
+        case LSHIFTASSIGN:
+        case RSIGNEDSHIFTASSIGN:
+        case RUNSIGNEDSHIFTASSIGN:
+        case ARROW:
+        case DOUBLECOLON:
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case INCR:
+            jj_consume_token(INCR);
+                   expr = new UnaryExpr(expr.getBeginLine(), expr.getBeginColumn(), token.endLine, token.endColumn, expr, UnaryExpr.Operator.posIncrement);
+            break;
+          case DECR:
+            jj_consume_token(DECR);
+                   expr = new UnaryExpr(expr.getBeginLine(), expr.getBeginColumn(), token.endLine, token.endColumn, expr, UnaryExpr.Operator.posDecrement);
+            break;
+          case ASSIGN:
+          case PLUSASSIGN:
+          case MINUSASSIGN:
+          case STARASSIGN:
+          case SLASHASSIGN:
+          case ANDASSIGN:
+          case ORASSIGN:
+          case XORASSIGN:
+          case REMASSIGN:
+          case LSHIFTASSIGN:
+          case RSIGNEDSHIFTASSIGN:
+          case RUNSIGNEDSHIFTASSIGN:
+            op = AssignmentOperator();
+            value = Expression();
+                                                             expr = new AssignExpr(expr.getBeginLine(), expr.getBeginColumn(), token.endLine, token.endColumn, expr, value, op);
+            break;
+          case DOUBLECOLON:
+            jj_consume_token(DOUBLECOLON);
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case LT:
+              typeArgs = TypeParameters();
+                                                 typeArgs.remove(0);
+              break;
+            default:
+              jj_la1[144] = jj_gen;
+              ;
+            }
+            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+            case IDENTIFIER:
+              jj_consume_token(IDENTIFIER);
+              break;
+            case NEW:
+              jj_consume_token(NEW);
+              break;
+            default:
+              jj_la1[145] = jj_gen;
+              jj_consume_token(-1);
+              throw new ParseException();
+            }
+                                                                                                 expr = new MethodReferenceExpr(expr.getBeginLine(), expr.getBeginColumn(), token.endLine, token.endColumn, expr, typeArgs, token.image);
+            break;
+          case ARROW:
+            jj_consume_token(ARROW);
+            lambdaBody = LambdaBody();
+             if (expr instanceof CastExpr)
+             {
+           inner = generateLambda(((CastExpr)expr).getExpr(), lambdaBody);
+           ((CastExpr)expr).setExpr(inner);
+             }
+             else
+             {
+               expr = generateLambda(expr, lambdaBody);
+             }
+            break;
+          default:
+            jj_la1[146] = jj_gen;
+            jj_consume_token(-1);
+            throw new ParseException();
+          }
+          break;
+        default:
+          jj_la1[147] = jj_gen;
+          ;
+        }
+        break;
+      default:
+        jj_la1[148] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    jj_consume_token(SEMICOLON);
+    {if (true) return new ExpressionStmt(expr.getBeginLine(), expr.getBeginColumn(), token.endLine, token.endColumn, expr);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SwitchStmt SwitchStatement() {
+        Expression selector;
+        SwitchEntryStmt entry;
+        List entries = null;
+        int line;
+        int column;
+    jj_consume_token(SWITCH);
+            line=token.beginLine; column=token.beginColumn;
+    jj_consume_token(LPAREN);
+    selector = Expression();
+    jj_consume_token(RPAREN);
+    jj_consume_token(LBRACE);
+    label_64:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case CASE:
+      case _DEFAULT:
+        ;
+        break;
+      default:
+        jj_la1[149] = jj_gen;
+        break label_64;
+      }
+      entry = SwitchEntry();
+                              entries = add(entries, entry);
+    }
+    jj_consume_token(RBRACE);
+    {if (true) return new SwitchStmt(line, column, token.endLine, token.endColumn,selector, entries);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SwitchEntryStmt SwitchEntry() {
+        Expression label = null;
+        List stmts;
+        int line;
+        int column;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case CASE:
+      jj_consume_token(CASE);
+                  line=token.beginLine; column=token.beginColumn;
+      label = Expression();
+      break;
+    case _DEFAULT:
+      jj_consume_token(_DEFAULT);
+                     line=token.beginLine; column=token.beginColumn;
+      break;
+    default:
+      jj_la1[150] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(COLON);
+    stmts = Statements();
+    {if (true) return new SwitchEntryStmt(line, column, token.endLine, token.endColumn,label, stmts);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public IfStmt IfStatement() {
+        Expression condition;
+        Statement thenStmt;
+        Statement elseStmt = null;
+        int line;
+        int column;
+    Comment thenCmmt = null;
+    Comment elseCmmt = null;
+    jj_consume_token(IF);
+        line=token.beginLine; column=token.beginColumn;
+    jj_consume_token(LPAREN);
+    condition = Expression();
+    jj_consume_token(RPAREN);
+
+    thenStmt = Statement();
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case ELSE:
+      jj_consume_token(ELSE);
+
+      elseStmt = Statement();
+      break;
+    default:
+      jj_la1[151] = jj_gen;
+      ;
+    }
+      IfStmt tmp = new IfStmt(line, column, token.endLine, token.endColumn,condition, thenStmt, elseStmt);
+
+      thenStmt.setComment(thenCmmt);
+      if (elseStmt != null)
+          elseStmt.setComment(elseCmmt);
+      {if (true) return tmp;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public WhileStmt WhileStatement() {
+        Expression condition;
+        Statement body;
+        int line;
+        int column;
+    jj_consume_token(WHILE);
+           line=token.beginLine; column=token.beginColumn;
+    jj_consume_token(LPAREN);
+    condition = Expression();
+    jj_consume_token(RPAREN);
+    body = Statement();
+    {if (true) return new WhileStmt(line, column, token.endLine, token.endColumn,condition, body);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public DoStmt DoStatement() {
+        Expression condition;
+        Statement body;
+        int line;
+        int column;
+    jj_consume_token(DO);
+        line=token.beginLine; column=token.beginColumn;
+    body = Statement();
+    jj_consume_token(WHILE);
+    jj_consume_token(LPAREN);
+    condition = Expression();
+    jj_consume_token(RPAREN);
+    jj_consume_token(SEMICOLON);
+    {if (true) return new DoStmt(line, column, token.endLine, token.endColumn,body, condition);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Statement ForStatement() {
+        String id = null;
+        VariableDeclarationExpr varExpr = null;
+        Expression expr = null;
+        List init = null;
+        List update = null;
+        Statement body;
+        int line;
+        int column;
+    jj_consume_token(FOR);
+         line=token.beginLine; column=token.beginColumn;
+    jj_consume_token(LPAREN);
+    if (jj_2_40(2147483647)) {
+      varExpr = VariableDeclarationExpression();
+      jj_consume_token(COLON);
+      expr = Expression();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NATIVE:
+      case NEW:
+      case NULL:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SUPER:
+      case SYNCHRONIZED:
+      case THIS:
+      case TRANSIENT:
+      case TRUE:
+      case VOID:
+      case VOLATILE:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case SEMICOLON:
+      case AT:
+      case BANG:
+      case TILDE:
+      case INCR:
+      case DECR:
+      case PLUS:
+      case MINUS:
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case ABSTRACT:
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FINAL:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NATIVE:
+        case NEW:
+        case NULL:
+        case PRIVATE:
+        case PROTECTED:
+        case PUBLIC:
+        case SHORT:
+        case STATIC:
+        case STRICTFP:
+        case SUPER:
+        case SYNCHRONIZED:
+        case THIS:
+        case TRANSIENT:
+        case TRUE:
+        case VOID:
+        case VOLATILE:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:
+        case AT:
+        case BANG:
+        case TILDE:
+        case INCR:
+        case DECR:
+        case PLUS:
+        case MINUS:
+          init = ForInit();
+          break;
+        default:
+          jj_la1[152] = jj_gen;
+          ;
+        }
+        jj_consume_token(SEMICOLON);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NEW:
+        case NULL:
+        case SHORT:
+        case SUPER:
+        case THIS:
+        case TRUE:
+        case VOID:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:
+        case BANG:
+        case TILDE:
+        case INCR:
+        case DECR:
+        case PLUS:
+        case MINUS:
+          expr = Expression();
+          break;
+        default:
+          jj_la1[153] = jj_gen;
+          ;
+        }
+        jj_consume_token(SEMICOLON);
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FALSE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case NEW:
+        case NULL:
+        case SHORT:
+        case SUPER:
+        case THIS:
+        case TRUE:
+        case VOID:
+        case LONG_LITERAL:
+        case INTEGER_LITERAL:
+        case FLOATING_POINT_LITERAL:
+        case CHARACTER_LITERAL:
+        case STRING_LITERAL:
+        case IDENTIFIER:
+        case LPAREN:
+        case BANG:
+        case TILDE:
+        case INCR:
+        case DECR:
+        case PLUS:
+        case MINUS:
+          update = ForUpdate();
+          break;
+        default:
+          jj_la1[154] = jj_gen;
+          ;
+        }
+        break;
+      default:
+        jj_la1[155] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    jj_consume_token(RPAREN);
+    body = Statement();
+        if (varExpr != null) {
+                {if (true) return new ForeachStmt(line, column, token.endLine, token.endColumn,varExpr, expr, body);}
+        }
+        {if (true) return new ForStmt(line, column, token.endLine, token.endColumn,init, expr, update, body);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ForInit() {
+        List ret;
+        Expression expr;
+    if (jj_2_41(2147483647)) {
+      expr = VariableDeclarationExpression();
+                                                   ret = new LinkedList(); ret.add(expr);
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case DOUBLE:
+      case FALSE:
+      case FLOAT:
+      case INT:
+      case LONG:
+      case NEW:
+      case NULL:
+      case SHORT:
+      case SUPER:
+      case THIS:
+      case TRUE:
+      case VOID:
+      case LONG_LITERAL:
+      case INTEGER_LITERAL:
+      case FLOATING_POINT_LITERAL:
+      case CHARACTER_LITERAL:
+      case STRING_LITERAL:
+      case IDENTIFIER:
+      case LPAREN:
+      case BANG:
+      case TILDE:
+      case INCR:
+      case DECR:
+      case PLUS:
+      case MINUS:
+        ret = ExpressionList();
+        break;
+      default:
+        jj_la1[156] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ExpressionList() {
+        List ret = new LinkedList();
+        Expression expr;
+    expr = Expression();
+                        ret.add(expr);
+    label_65:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[157] = jj_gen;
+        break label_65;
+      }
+      jj_consume_token(COMMA);
+      expr = Expression();
+                                                                      ret.add(expr);
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ForUpdate() {
+        List ret;
+    ret = ExpressionList();
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public BreakStmt BreakStatement() {
+        String id = null;
+        int line;
+        int column;
+    jj_consume_token(BREAK);
+           line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IDENTIFIER:
+      jj_consume_token(IDENTIFIER);
+                                                                             id = token.image;
+      break;
+    default:
+      jj_la1[158] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+    {if (true) return new BreakStmt(line, column, token.endLine, token.endColumn,id);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ContinueStmt ContinueStatement() {
+        String id = null;
+        int line;
+        int column;
+    jj_consume_token(CONTINUE);
+              line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IDENTIFIER:
+      jj_consume_token(IDENTIFIER);
+                                                                                id = token.image;
+      break;
+    default:
+      jj_la1[159] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+    {if (true) return new ContinueStmt(line, column, token.endLine, token.endColumn,id);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ReturnStmt ReturnStatement() {
+        Expression expr = null;
+        int line;
+        int column;
+    jj_consume_token(RETURN);
+            line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:
+      expr = Expression();
+      break;
+    default:
+      jj_la1[160] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+    {if (true) return new ReturnStmt(line, column, token.endLine, token.endColumn,expr);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public ThrowStmt ThrowStatement() {
+        Expression expr;
+        int line;
+        int column;
+    jj_consume_token(THROW);
+           line=token.beginLine; column=token.beginColumn;
+    expr = Expression();
+    jj_consume_token(SEMICOLON);
+    {if (true) return new ThrowStmt(line, column, token.endLine, token.endColumn,expr);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SynchronizedStmt SynchronizedStatement() {
+        Expression expr;
+        BlockStmt block;
+        int line;
+        int column;
+    jj_consume_token(SYNCHRONIZED);
+                  line=token.beginLine; column=token.beginColumn;
+    jj_consume_token(LPAREN);
+    expr = Expression();
+    jj_consume_token(RPAREN);
+    block = Block();
+    {if (true) return new SynchronizedStmt(line, column, token.endLine, token.endColumn,expr, block);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public TryStmt TryStatement() {
+        List resources = new LinkedList();
+        BlockStmt tryBlock;
+        BlockStmt finallyBlock = null;
+        List catchs = null;
+        Parameter except;
+        BlockStmt catchBlock;
+        Modifier exceptModifier;
+        Type exceptType;
+        List exceptTypes = new LinkedList();
+        VariableDeclaratorId exceptId;
+        int line;
+        int column;
+        int cLine;
+        int cColumn;
+    jj_consume_token(TRY);
+         line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case LPAREN:
+      resources = ResourceSpecification();
+      break;
+    default:
+      jj_la1[161] = jj_gen;
+      ;
+    }
+    tryBlock = Block();
+    label_66:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case CATCH:
+        ;
+        break;
+      default:
+        jj_la1[162] = jj_gen;
+        break label_66;
+      }
+      jj_consume_token(CATCH);
+                                 cLine=token.beginLine; cColumn=token.beginColumn;
+      jj_consume_token(LPAREN);
+      exceptModifier = Modifiers();
+      exceptType = Type();
+                                                                           exceptTypes.add(exceptType);
+      label_67:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case BIT_OR:
+          ;
+          break;
+        default:
+          jj_la1[163] = jj_gen;
+          break label_67;
+        }
+        jj_consume_token(BIT_OR);
+        exceptType = Type();
+                                                    exceptTypes.add(exceptType);
+      }
+      exceptId = VariableDeclaratorId();
+      jj_consume_token(RPAREN);
+      catchBlock = Block();
+                          catchs = add(catchs, new CatchClause(cLine, cColumn, token.endLine, token.endColumn, exceptModifier.modifiers, exceptModifier.annotations, exceptTypes, exceptId, catchBlock)); exceptTypes = new LinkedList();
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case FINALLY:
+      jj_consume_token(FINALLY);
+      finallyBlock = Block();
+      break;
+    default:
+      jj_la1[164] = jj_gen;
+      ;
+    }
+    {if (true) return new TryStmt(line, column, token.endLine, token.endColumn, resources, tryBlock, catchs, finallyBlock);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List ResourceSpecification() {
+List vars;
+    jj_consume_token(LPAREN);
+    vars = Resources();
+    if (jj_2_42(2)) {
+      jj_consume_token(SEMICOLON);
+    } else {
+      ;
+    }
+    jj_consume_token(RPAREN);
+    {if (true) return vars;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List Resources() {
+        List vars = new LinkedList();
+        VariableDeclarationExpr var;
+    /*this is a bit more lenient than we need to be, eg allowing access modifiers like private*/
+      var = VariableDeclarationExpression();
+                                         vars.add(var);
+    label_68:
+    while (true) {
+      if (jj_2_43(2)) {
+        ;
+      } else {
+        break label_68;
+      }
+      jj_consume_token(SEMICOLON);
+      var = VariableDeclarationExpression();
+                                                                                                                  vars.add(var);
+    }
+    {if (true) return vars;}
+    throw new Error("Missing return statement in function");
+  }
+
+/* We use productions to match >>>, >> and > so that we can keep the
+ * type declaration syntax with generics clean
+ */
+  final public void RUNSIGNEDSHIFT() {
+    if (getToken(1).kind == GT &&
+                    ((GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT) {
+
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(GT);
+    jj_consume_token(GT);
+    jj_consume_token(GT);
+  }
+
+  final public void RSIGNEDSHIFT() {
+    if (getToken(1).kind == GT &&
+                    ((GTToken)getToken(1)).realKind == RSIGNEDSHIFT) {
+
+    } else {
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    jj_consume_token(GT);
+    jj_consume_token(GT);
+  }
+
+/* Annotation syntax follows. */
+  final public AnnotationExpr Annotation() {
+        AnnotationExpr ret;
+    if (jj_2_44(2147483647)) {
+      ret = NormalAnnotation();
+    } else if (jj_2_45(2147483647)) {
+      ret = SingleMemberAnnotation();
+    } else {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case AT:
+        ret = MarkerAnnotation();
+        break;
+      default:
+        jj_la1[165] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public NormalAnnotationExpr NormalAnnotation() {
+        NameExpr name;
+        List pairs = null;
+        int line;
+        int column;
+    jj_consume_token(AT);
+        line=token.beginLine; column=token.beginColumn;
+    name = Name();
+    jj_consume_token(LPAREN);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IDENTIFIER:
+      pairs = MemberValuePairs();
+      break;
+    default:
+      jj_la1[166] = jj_gen;
+      ;
+    }
+    jj_consume_token(RPAREN);
+     {if (true) return new NormalAnnotationExpr(line, column, token.endLine, token.endColumn,name, pairs);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public MarkerAnnotationExpr MarkerAnnotation() {
+        NameExpr name;
+        int line;
+        int column;
+    jj_consume_token(AT);
+       line=token.beginLine; column=token.beginColumn;
+    name = Name();
+    {if (true) return new MarkerAnnotationExpr(line, column, token.endLine, token.endColumn,name);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public SingleMemberAnnotationExpr SingleMemberAnnotation() {
+        NameExpr name;
+        Expression memberVal;
+        int line;
+        int column;
+    jj_consume_token(AT);
+       line=token.beginLine; column=token.beginColumn;
+    name = Name();
+    jj_consume_token(LPAREN);
+    memberVal = MemberValue();
+    jj_consume_token(RPAREN);
+    {if (true) return new SingleMemberAnnotationExpr(line, column, token.endLine, token.endColumn,name, memberVal);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List MemberValuePairs() {
+        List ret = new LinkedList();
+        MemberValuePair pair;
+    pair = MemberValuePair();
+                              ret.add(pair);
+    label_69:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case COMMA:
+        ;
+        break;
+      default:
+        jj_la1[167] = jj_gen;
+        break label_69;
+      }
+      jj_consume_token(COMMA);
+      pair = MemberValuePair();
+                                                                                ret.add(pair);
+    }
+     {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public MemberValuePair MemberValuePair() {
+        String name;
+        Expression value;
+        int line;
+        int column;
+    jj_consume_token(IDENTIFIER);
+                   name = token.image; line=token.beginLine; column=token.beginColumn;
+    jj_consume_token(ASSIGN);
+    value = MemberValue();
+      {if (true) return new MemberValuePair(line, column, token.endLine, token.endColumn,name, value);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression MemberValue() {
+        Expression ret;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case AT:
+      ret = Annotation();
+      break;
+    case LBRACE:
+      ret = MemberValueArrayInitializer();
+      break;
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:
+      ret = ConditionalExpression();
+      break;
+    default:
+      jj_la1[168] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression MemberValueArrayInitializer() {
+        List ret = new LinkedList();
+        Expression member;
+        int line;
+        int column;
+    jj_consume_token(LBRACE);
+       line=token.beginLine; column=token.beginColumn;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case DOUBLE:
+    case FALSE:
+    case FLOAT:
+    case INT:
+    case LONG:
+    case NEW:
+    case NULL:
+    case SHORT:
+    case SUPER:
+    case THIS:
+    case TRUE:
+    case VOID:
+    case LONG_LITERAL:
+    case INTEGER_LITERAL:
+    case FLOATING_POINT_LITERAL:
+    case CHARACTER_LITERAL:
+    case STRING_LITERAL:
+    case IDENTIFIER:
+    case LPAREN:
+    case LBRACE:
+    case AT:
+    case BANG:
+    case TILDE:
+    case INCR:
+    case DECR:
+    case PLUS:
+    case MINUS:
+      member = MemberValue();
+                                 ret.add(member);
+      label_70:
+      while (true) {
+        if (jj_2_46(2)) {
+          ;
+        } else {
+          break label_70;
+        }
+        jj_consume_token(COMMA);
+        member = MemberValue();
+                                                                                                ret.add(member);
+      }
+      break;
+    default:
+      jj_la1[169] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case COMMA:
+      jj_consume_token(COMMA);
+      break;
+    default:
+      jj_la1[170] = jj_gen;
+      ;
+    }
+    jj_consume_token(RBRACE);
+    {if (true) return new ArrayInitializerExpr(line, column, token.endLine, token.endColumn,ret);}
+    throw new Error("Missing return statement in function");
+  }
+
+/* Annotation Types. */
+  final public AnnotationDeclaration AnnotationTypeDeclaration(Modifier modifier) {
+        NameExpr name;
+        List members;
+        int line = modifier.beginLine;
+        int column = modifier.beginColumn;
+    jj_consume_token(AT);
+        if (line == -1) {line=token.beginLine; column=token.beginColumn;}
+    jj_consume_token(INTERFACE);
+    name = Name();
+    members = AnnotationTypeBody();
+      AnnotationDeclaration tmp = new AnnotationDeclaration(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, null, members);
+      tmp.setNameExpr(name);
+      {if (true) return tmp;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public List AnnotationTypeBody() {
+        List ret = null;
+        BodyDeclaration member;
+    jj_consume_token(LBRACE);
+    label_71:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case ABSTRACT:
+      case BOOLEAN:
+      case BYTE:
+      case CHAR:
+      case CLASS:
+      case DOUBLE:
+      case ENUM:
+      case FINAL:
+      case FLOAT:
+      case INT:
+      case INTERFACE:
+      case LONG:
+      case NATIVE:
+      case PRIVATE:
+      case PROTECTED:
+      case PUBLIC:
+      case SHORT:
+      case STATIC:
+      case STRICTFP:
+      case SYNCHRONIZED:
+      case TRANSIENT:
+      case VOLATILE:
+      case IDENTIFIER:
+      case SEMICOLON:
+      case AT:
+        ;
+        break;
+      default:
+        jj_la1[171] = jj_gen;
+        break label_71;
+      }
+      member = AnnotationBodyDeclaration();
+                                               ret = add(ret, member);
+    }
+    jj_consume_token(RBRACE);
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public BodyDeclaration AnnotationBodyDeclaration() {
+   Modifier modifier;
+   BodyDeclaration ret;
+
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case SEMICOLON:
+      jj_consume_token(SEMICOLON);
+              ret = new EmptyTypeDeclaration(token.beginLine, token.beginColumn, token.endLine, token.endColumn);
+      break;
+    case ABSTRACT:
+    case BOOLEAN:
+    case BYTE:
+    case CHAR:
+    case CLASS:
+    case DOUBLE:
+    case ENUM:
+    case FINAL:
+    case FLOAT:
+    case INT:
+    case INTERFACE:
+    case LONG:
+    case NATIVE:
+    case PRIVATE:
+    case PROTECTED:
+    case PUBLIC:
+    case SHORT:
+    case STATIC:
+    case STRICTFP:
+    case SYNCHRONIZED:
+    case TRANSIENT:
+    case VOLATILE:
+    case IDENTIFIER:
+    case AT:
+      modifier = Modifiers();
+      if (jj_2_47(2147483647)) {
+        ret = AnnotationTypeMemberDeclaration(modifier);
+      } else {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case CLASS:
+        case INTERFACE:
+          ret = ClassOrInterfaceDeclaration(modifier);
+          break;
+        case ENUM:
+          ret = EnumDeclaration(modifier);
+          break;
+        case AT:
+          ret = AnnotationTypeDeclaration(modifier);
+          break;
+        case BOOLEAN:
+        case BYTE:
+        case CHAR:
+        case DOUBLE:
+        case FLOAT:
+        case INT:
+        case LONG:
+        case SHORT:
+        case IDENTIFIER:
+          ret = FieldDeclaration(modifier);
+          break;
+        default:
+          jj_la1[172] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+      }
+      break;
+    default:
+      jj_la1[173] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public AnnotationMemberDeclaration AnnotationTypeMemberDeclaration(Modifier modifier) {
+        Type type;
+        String name;
+        Expression defaultVal = null;
+    type = Type();
+    jj_consume_token(IDENTIFIER);
+                               name = token.image;
+    jj_consume_token(LPAREN);
+    jj_consume_token(RPAREN);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case _DEFAULT:
+      defaultVal = DefaultValue();
+      break;
+    default:
+      jj_la1[174] = jj_gen;
+      ;
+    }
+    jj_consume_token(SEMICOLON);
+    int line = modifier.beginLine;
+    int column = modifier.beginColumn;
+    { if (line == -1) {line=type.getBeginLine(); column=type.getBeginColumn();} }
+    {if (true) return new AnnotationMemberDeclaration(line, column, token.endLine, token.endColumn, modifier.modifiers, modifier.annotations, type, name, defaultVal);}
+    throw new Error("Missing return statement in function");
+  }
+
+  final public Expression DefaultValue() {
+        Expression ret;
+    jj_consume_token(_DEFAULT);
+    ret = MemberValue();
+    {if (true) return ret;}
+    throw new Error("Missing return statement in function");
+  }
+
+  private boolean jj_2_1(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_1(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(0, xla); }
+  }
+
+  private boolean jj_2_2(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_2(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(1, xla); }
+  }
+
+  private boolean jj_2_3(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_3(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(2, xla); }
+  }
+
+  private boolean jj_2_4(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_4(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(3, xla); }
+  }
+
+  private boolean jj_2_5(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_5(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(4, xla); }
+  }
+
+  private boolean jj_2_6(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_6(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(5, xla); }
+  }
+
+  private boolean jj_2_7(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_7(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(6, xla); }
+  }
+
+  private boolean jj_2_8(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_8(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(7, xla); }
+  }
+
+  private boolean jj_2_9(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_9(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(8, xla); }
+  }
+
+  private boolean jj_2_10(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_10(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(9, xla); }
+  }
+
+  private boolean jj_2_11(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_11(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(10, xla); }
+  }
+
+  private boolean jj_2_12(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_12(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(11, xla); }
+  }
+
+  private boolean jj_2_13(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_13(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(12, xla); }
+  }
+
+  private boolean jj_2_14(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_14(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(13, xla); }
+  }
+
+  private boolean jj_2_15(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_15(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(14, xla); }
+  }
+
+  private boolean jj_2_16(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_16(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(15, xla); }
+  }
+
+  private boolean jj_2_17(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_17(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(16, xla); }
+  }
+
+  private boolean jj_2_18(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_18(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(17, xla); }
+  }
+
+  private boolean jj_2_19(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_19(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(18, xla); }
+  }
+
+  private boolean jj_2_20(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_20(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(19, xla); }
+  }
+
+  private boolean jj_2_21(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_21(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(20, xla); }
+  }
+
+  private boolean jj_2_22(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_22(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(21, xla); }
+  }
+
+  private boolean jj_2_23(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_23(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(22, xla); }
+  }
+
+  private boolean jj_2_24(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_24(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(23, xla); }
+  }
+
+  private boolean jj_2_25(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_25(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(24, xla); }
+  }
+
+  private boolean jj_2_26(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_26(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(25, xla); }
+  }
+
+  private boolean jj_2_27(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_27(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(26, xla); }
+  }
+
+  private boolean jj_2_28(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_28(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(27, xla); }
+  }
+
+  private boolean jj_2_29(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_29(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(28, xla); }
+  }
+
+  private boolean jj_2_30(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_30(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(29, xla); }
+  }
+
+  private boolean jj_2_31(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_31(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(30, xla); }
+  }
+
+  private boolean jj_2_32(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_32(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(31, xla); }
+  }
+
+  private boolean jj_2_33(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_33(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(32, xla); }
+  }
+
+  private boolean jj_2_34(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_34(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(33, xla); }
+  }
+
+  private boolean jj_2_35(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_35(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(34, xla); }
+  }
+
+  private boolean jj_2_36(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_36(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(35, xla); }
+  }
+
+  private boolean jj_2_37(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_37(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(36, xla); }
+  }
+
+  private boolean jj_2_38(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_38(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(37, xla); }
+  }
+
+  private boolean jj_2_39(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_39(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(38, xla); }
+  }
+
+  private boolean jj_2_40(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_40(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(39, xla); }
+  }
+
+  private boolean jj_2_41(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_41(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(40, xla); }
+  }
+
+  private boolean jj_2_42(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_42(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(41, xla); }
+  }
+
+  private boolean jj_2_43(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_43(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(42, xla); }
+  }
+
+  private boolean jj_2_44(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_44(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(43, xla); }
+  }
+
+  private boolean jj_2_45(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_45(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(44, xla); }
+  }
+
+  private boolean jj_2_46(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_46(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(45, xla); }
+  }
+
+  private boolean jj_2_47(int xla) {
+    jj_la = xla; jj_lastpos = jj_scanpos = token;
+    try { return !jj_3_47(); }
+    catch(LookaheadSuccess ls) { return true; }
+    finally { jj_save(46, xla); }
+  }
+
+  private boolean jj_3R_172() {
+    if (jj_3R_168()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_207()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_294() {
+    if (jj_3R_133()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_25()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_422() {
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_155() {
+    if (jj_3R_94()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_201()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_424() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_437()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3R_438()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3_24() {
+    if (jj_3R_107()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_174()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_88() {
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_421() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_423() {
+    if (jj_3R_436()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_388() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_172()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_361() {
+    if (jj_scan_token(TRY)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_423()) jj_scanpos = xsp;
+    if (jj_3R_128()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_424()) {
+    jj_scanpos = xsp;
+    if (jj_3R_425()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_154() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_302() {
+    if (jj_3R_87()) return true;
+    if (jj_3R_172()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_388()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_104() {
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_154()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3_24()) {
+    jj_scanpos = xsp;
+    if (jj_3R_155()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_241() {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_420() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_106() {
+    if (jj_scan_token(DECR)) return true;
+    return false;
+  }
+
+  private boolean jj_3_23() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_105()) {
+    jj_scanpos = xsp;
+    if (jj_3R_106()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_105() {
+    if (jj_scan_token(INCR)) return true;
+    return false;
+  }
+
+  private boolean jj_3_5() {
+    if (jj_3R_87()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_88()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_scan_token(88)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(91)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(87)) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_86() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3_22() {
+    if (jj_3R_104()) return true;
+    return false;
+  }
+
+  private boolean jj_3_4() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_86()) jj_scanpos = xsp;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_216() {
+    if (jj_3R_245()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_267() {
+    if (jj_3R_294()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_23()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_277() {
+    if (jj_3R_303()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_360() {
+    if (jj_scan_token(SYNCHRONIZED)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_271() {
+    if (jj_scan_token(_DEFAULT)) return true;
+    if (jj_3R_116()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_276() {
+    if (jj_3R_302()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_235() {
+    if (jj_3R_104()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_236() {
+    if (jj_3R_267()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_266() {
+    if (jj_scan_token(BANG)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_275() {
+    if (jj_3R_301()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_265() {
+    if (jj_scan_token(TILDE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_274() {
+    if (jj_3R_300()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_234() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_265()) {
+    jj_scanpos = xsp;
+    if (jj_3R_266()) return true;
+    }
+    if (jj_3R_174()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_273() {
+    if (jj_3R_299()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_272() {
+    if (jj_3R_298()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_359() {
+    if (jj_scan_token(THROW)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_201() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_234()) {
+    jj_scanpos = xsp;
+    if (jj_3R_235()) {
+    jj_scanpos = xsp;
+    if (jj_3R_236()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_358() {
+    if (jj_scan_token(RETURN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_422()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_461() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_240() {
+    if (jj_3R_116()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_271()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_272()) {
+    jj_scanpos = xsp;
+    if (jj_3R_273()) {
+    jj_scanpos = xsp;
+    if (jj_3R_274()) {
+    jj_scanpos = xsp;
+    if (jj_3R_275()) {
+    jj_scanpos = xsp;
+    if (jj_3R_276()) {
+    jj_scanpos = xsp;
+    if (jj_3R_277()) return true;
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_242() {
+    if (jj_scan_token(DECR)) return true;
+    if (jj_3R_174()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_357() {
+    if (jj_scan_token(CONTINUE)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_421()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3_6() {
+    if (jj_3R_89()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_417() {
+    if (jj_scan_token(ELSE)) return true;
+    if (jj_3R_306()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_118() {
+    if (jj_scan_token(INCR)) return true;
+    if (jj_3R_174()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_435() {
+    if (jj_3R_452()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_211() {
+    if (jj_3R_201()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_206() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_6()) {
+    jj_scanpos = xsp;
+    if (jj_3R_240()) {
+    jj_scanpos = xsp;
+    if (jj_3R_241()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_356() {
+    if (jj_scan_token(BREAK)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_420()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_171() {
+    if (jj_3R_206()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_452() {
+    if (jj_3R_459()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_279() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_244() {
+    if (jj_scan_token(MINUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_113() {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_171()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_305() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_243() {
+    if (jj_scan_token(PLUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_210() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_243()) {
+    jj_scanpos = xsp;
+    if (jj_3R_244()) return true;
+    }
+    if (jj_3R_174()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_209() {
+    if (jj_3R_242()) return true;
+    return false;
+  }
+
+  private boolean jj_3_41() {
+    if (jj_3R_116()) return true;
+    if (jj_3R_87()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_208() {
+    if (jj_3R_118()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_280() {
+    if (jj_scan_token(BIT_AND)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_305()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_198()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_459() {
+    if (jj_3R_100()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_461()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_245() {
+    if (jj_scan_token(EXTENDS)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_279()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_198()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_280()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_458() {
+    if (jj_3R_459()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_434() {
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_457() {
+    if (jj_3R_117()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_174() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_208()) {
+    jj_scanpos = xsp;
+    if (jj_3R_209()) {
+    jj_scanpos = xsp;
+    if (jj_3R_210()) {
+    jj_scanpos = xsp;
+    if (jj_3R_211()) return true;
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_430() {
+    if (jj_scan_token(REM)) return true;
+    return false;
+  }
+
+  private boolean jj_3_3() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_85()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_429() {
+    if (jj_scan_token(SLASH)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_182() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_216()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_428() {
+    if (jj_scan_token(STAR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_451() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_457()) {
+    jj_scanpos = xsp;
+    if (jj_3R_458()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_412() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_428()) {
+    jj_scanpos = xsp;
+    if (jj_3R_429()) {
+    jj_scanpos = xsp;
+    if (jj_3R_430()) return true;
+    }
+    }
+    if (jj_3R_174()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_217() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_408() {
+    if (jj_3R_113()) return true;
+    return false;
+  }
+
+  private boolean jj_3_40() {
+    if (jj_3R_117()) return true;
+    if (jj_scan_token(COLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_376() {
+    if (jj_3R_174()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_412()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_183() {
+    if (jj_scan_token(COMMA)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_217()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_182()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_181() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_433() {
+    if (jj_3R_451()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_414() {
+    if (jj_scan_token(MINUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_413() {
+    if (jj_scan_token(PLUS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_125() {
+    if (jj_scan_token(LT)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_181()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_182()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_183()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_419() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_433()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_434()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_435()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_402() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_413()) {
+    jj_scanpos = xsp;
+    if (jj_3R_414()) return true;
+    }
+    if (jj_3R_376()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_418() {
+    if (jj_3R_117()) return true;
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_372() {
+    if (jj_3R_376()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_402()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_355() {
+    if (jj_scan_token(FOR)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_418()) {
+    jj_scanpos = xsp;
+    if (jj_3R_419()) return true;
+    }
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_306()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_407() {
+    if (jj_3R_187()) return true;
+    return false;
+  }
+
+  private boolean jj_3_21() {
+    if (jj_3R_103()) return true;
+    return false;
+  }
+
+  private boolean jj_3_20() {
+    if (jj_3R_102()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_124() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_101() {
+    if (jj_scan_token(LSHIFT)) return true;
+    return false;
+  }
+
+  private boolean jj_3_19() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_101()) {
+    jj_scanpos = xsp;
+    if (jj_3_20()) {
+    jj_scanpos = xsp;
+    if (jj_3_21()) return true;
+    }
+    }
+    if (jj_3R_372()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_85() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_124()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(IDENTIFIER)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_407()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_408()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_398() {
+    if (jj_3R_206()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_373() {
+    if (jj_scan_token(INSTANCEOF)) return true;
+    if (jj_3R_87()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_354() {
+    if (jj_scan_token(DO)) return true;
+    if (jj_3R_306()) return true;
+    if (jj_scan_token(WHILE)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_370() {
+    if (jj_3R_372()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_19()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_383() {
+    if (jj_scan_token(SEMICOLON)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_398()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_395() {
+    if (jj_scan_token(GE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_394() {
+    if (jj_scan_token(LE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_393() {
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_392() {
+    if (jj_scan_token(LT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_377() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_392()) {
+    jj_scanpos = xsp;
+    if (jj_3R_393()) {
+    jj_scanpos = xsp;
+    if (jj_3R_394()) {
+    jj_scanpos = xsp;
+    if (jj_3R_395()) return true;
+    }
+    }
+    }
+    if (jj_3R_370()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_353() {
+    if (jj_scan_token(WHILE)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_306()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_382() {
+    if (jj_3R_85()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_3()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_368() {
+    if (jj_3R_370()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_377()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_381() {
+    if (jj_3R_397()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_369() {
+    if (jj_scan_token(BIT_AND)) return true;
+    if (jj_3R_345()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_299() {
+    if (jj_scan_token(ENUM)) return true;
+    if (jj_3R_119()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_381()) jj_scanpos = xsp;
+    if (jj_scan_token(LBRACE)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_382()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(88)) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_383()) jj_scanpos = xsp;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_364() {
+    if (jj_3R_368()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_373()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_352() {
+    if (jj_scan_token(IF)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_306()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_417()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_405() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_375() {
+    if (jj_scan_token(NE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_374() {
+    if (jj_scan_token(EQ)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_371() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_374()) {
+    jj_scanpos = xsp;
+    if (jj_3R_375()) return true;
+    }
+    if (jj_3R_364()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_365() {
+    if (jj_scan_token(XOR)) return true;
+    if (jj_3R_315()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_346() {
+    if (jj_scan_token(BIT_OR)) return true;
+    if (jj_3R_293()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_406() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_198()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_345() {
+    if (jj_3R_364()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_371()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_450() {
+    if (jj_scan_token(_DEFAULT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_449() {
+    if (jj_scan_token(CASE)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_397() {
+    if (jj_scan_token(IMPLEMENTS)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_405()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_198()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_406()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_403() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_316() {
+    if (jj_scan_token(SC_AND)) return true;
+    if (jj_3R_264()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_315() {
+    if (jj_3R_345()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_369()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_432() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_449()) {
+    jj_scanpos = xsp;
+    if (jj_3R_450()) return true;
+    }
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_184()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_295() {
+    if (jj_scan_token(SC_OR)) return true;
+    if (jj_3R_233()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_404() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_198()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_396() {
+    if (jj_scan_token(EXTENDS)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_403()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_198()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_404()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_293() {
+    if (jj_3R_315()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_365()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_416() {
+    if (jj_3R_432()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_351() {
+    if (jj_scan_token(SWITCH)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_416()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_319() {
+    if (jj_scan_token(INTERFACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_264() {
+    if (jj_3R_293()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_346()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_380() {
+    if (jj_3R_397()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_173() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_172()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_379() {
+    if (jj_3R_396()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_378() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_456() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_233() {
+    if (jj_3R_264()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_316()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_298() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(20)) {
+    jj_scanpos = xsp;
+    if (jj_3R_319()) return true;
+    }
+    if (jj_3R_119()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_378()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_379()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_380()) jj_scanpos = xsp;
+    if (jj_3R_113()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_448() {
+    if (jj_scan_token(ARROW)) return true;
+    if (jj_3R_296()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_447() {
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_456()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(78)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(43)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_446() {
+    if (jj_3R_99()) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_445() {
+    if (jj_scan_token(DECR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_200() {
+    if (jj_3R_233()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_295()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_444() {
+    if (jj_scan_token(INCR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_431() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_444()) {
+    jj_scanpos = xsp;
+    if (jj_3R_445()) {
+    jj_scanpos = xsp;
+    if (jj_3R_446()) {
+    jj_scanpos = xsp;
+    if (jj_3R_447()) {
+    jj_scanpos = xsp;
+    if (jj_3R_448()) return true;
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_367() {
+    if (jj_3R_294()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_431()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_366() {
+    if (jj_3R_242()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_268() {
+    if (jj_scan_token(HOOK)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_151() {
+    if (jj_3R_200()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_268()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3_39() {
+    if (jj_3R_118()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_350() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_39()) {
+    jj_scanpos = xsp;
+    if (jj_3R_366()) {
+    jj_scanpos = xsp;
+    if (jj_3R_367()) return true;
+    }
+    }
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_150() {
+    if (jj_scan_token(ORASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_149() {
+    if (jj_scan_token(XORASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_148() {
+    if (jj_scan_token(ANDASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_147() {
+    if (jj_scan_token(RUNSIGNEDSHIFTASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_146() {
+    if (jj_scan_token(RSIGNEDSHIFTASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_145() {
+    if (jj_scan_token(LSHIFTASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_144() {
+    if (jj_scan_token(MINUSASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_143() {
+    if (jj_scan_token(PLUSASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_142() {
+    if (jj_scan_token(REMASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_141() {
+    if (jj_scan_token(SLASHASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_140() {
+    if (jj_scan_token(STARASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_139() {
+    if (jj_scan_token(ASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_318() {
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_99() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_139()) {
+    jj_scanpos = xsp;
+    if (jj_3R_140()) {
+    jj_scanpos = xsp;
+    if (jj_3R_141()) {
+    jj_scanpos = xsp;
+    if (jj_3R_142()) {
+    jj_scanpos = xsp;
+    if (jj_3R_143()) {
+    jj_scanpos = xsp;
+    if (jj_3R_144()) {
+    jj_scanpos = xsp;
+    if (jj_3R_145()) {
+    jj_scanpos = xsp;
+    if (jj_3R_146()) {
+    jj_scanpos = xsp;
+    if (jj_3R_147()) {
+    jj_scanpos = xsp;
+    if (jj_3R_148()) {
+    jj_scanpos = xsp;
+    if (jj_3R_149()) {
+    jj_scanpos = xsp;
+    if (jj_3R_150()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_84() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_83() {
+    if (jj_scan_token(STRICTFP)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_297() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_317() {
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_82() {
+    if (jj_scan_token(VOLATILE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_81() {
+    if (jj_scan_token(TRANSIENT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_114() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_80() {
+    if (jj_scan_token(NATIVE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_79() {
+    if (jj_scan_token(SYNCHRONIZED)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_270() {
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_297()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(78)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(43)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_296() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_317()) {
+    jj_scanpos = xsp;
+    if (jj_3R_318()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_78() {
+    if (jj_scan_token(ABSTRACT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_415() {
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_77() {
+    if (jj_scan_token(FINAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_76() {
+    if (jj_scan_token(PRIVATE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_75() {
+    if (jj_scan_token(PROTECTED)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_74() {
+    if (jj_scan_token(STATIC)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_349() {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3_34() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_114()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_73() {
+    if (jj_scan_token(PUBLIC)) return true;
+    return false;
+  }
+
+  private boolean jj_3_2() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_73()) {
+    jj_scanpos = xsp;
+    if (jj_3R_74()) {
+    jj_scanpos = xsp;
+    if (jj_3R_75()) {
+    jj_scanpos = xsp;
+    if (jj_3R_76()) {
+    jj_scanpos = xsp;
+    if (jj_3R_77()) {
+    jj_scanpos = xsp;
+    if (jj_3R_78()) {
+    jj_scanpos = xsp;
+    if (jj_3R_79()) {
+    jj_scanpos = xsp;
+    if (jj_3R_80()) {
+    jj_scanpos = xsp;
+    if (jj_3R_81()) {
+    jj_scanpos = xsp;
+    if (jj_3R_82()) {
+    jj_scanpos = xsp;
+    if (jj_3R_83()) {
+    jj_scanpos = xsp;
+    if (jj_3R_84()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_116() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_2()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3_18() {
+    if (jj_3R_99()) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_269() {
+    if (jj_scan_token(ARROW)) return true;
+    if (jj_3R_296()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_411() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_119()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_239() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_18()) {
+    jj_scanpos = xsp;
+    if (jj_3R_269()) {
+    jj_scanpos = xsp;
+    if (jj_3R_270()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3_38() {
+    if (jj_3R_117()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_117() {
+    if (jj_3R_116()) return true;
+    if (jj_3R_87()) return true;
+    if (jj_3R_172()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_173()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_100() {
+    if (jj_3R_151()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_239()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3_37() {
+    if (jj_3R_116()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(20)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(40)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_283() {
+    if (jj_3R_306()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_282() {
+    if (jj_3R_117()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_281() {
+    if (jj_3R_116()) return true;
+    if (jj_3R_298()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_246() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_281()) {
+    jj_scanpos = xsp;
+    if (jj_3R_282()) {
+    jj_scanpos = xsp;
+    if (jj_3R_283()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_122() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_72() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_122()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(PACKAGE)) return true;
+    if (jj_3R_119()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3_1() {
+    if (jj_3R_72()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_401() {
+    if (jj_3R_119()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_411()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_128() {
+    if (jj_scan_token(LBRACE)) return true;
+    if (jj_3R_184()) return true;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_227() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_115() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(COLON)) return true;
+    if (jj_3R_306()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_348() {
+    if (jj_scan_token(ASSERT)) return true;
+    if (jj_3R_100()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_415()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3_17() {
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_119() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_17()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_339() {
+    if (jj_3R_361()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_338() {
+    if (jj_3R_360()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_337() {
+    if (jj_3R_359()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_170() {
+    if (jj_3R_87()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_336() {
+    if (jj_3R_358()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_169() {
+    if (jj_scan_token(VOID)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_335() {
+    if (jj_3R_357()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_334() {
+    if (jj_3R_356()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_333() {
+    if (jj_3R_355()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_332() {
+    if (jj_3R_354()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_331() {
+    if (jj_3R_353()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_111() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_169()) {
+    jj_scanpos = xsp;
+    if (jj_3R_170()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_330() {
+    if (jj_3R_352()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_329() {
+    if (jj_3R_351()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_328() {
+    if (jj_3R_350()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_327() {
+    if (jj_3R_349()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_326() {
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_163() {
+    if (jj_scan_token(DOUBLE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_325() {
+    if (jj_3R_348()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_162() {
+    if (jj_scan_token(FLOAT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_161() {
+    if (jj_scan_token(LONG)) return true;
+    return false;
+  }
+
+  private boolean jj_3_36() {
+    if (jj_3R_115()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_160() {
+    if (jj_scan_token(INT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_363() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_159() {
+    if (jj_scan_token(SHORT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_362() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_158() {
+    if (jj_scan_token(BYTE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_157() {
+    if (jj_scan_token(CHAR)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_156() {
+    if (jj_scan_token(BOOLEAN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_306() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_36()) {
+    jj_scanpos = xsp;
+    if (jj_3R_325()) {
+    jj_scanpos = xsp;
+    if (jj_3R_326()) {
+    jj_scanpos = xsp;
+    if (jj_3R_327()) {
+    jj_scanpos = xsp;
+    if (jj_3R_328()) {
+    jj_scanpos = xsp;
+    if (jj_3R_329()) {
+    jj_scanpos = xsp;
+    if (jj_3R_330()) {
+    jj_scanpos = xsp;
+    if (jj_3R_331()) {
+    jj_scanpos = xsp;
+    if (jj_3R_332()) {
+    jj_scanpos = xsp;
+    if (jj_3R_333()) {
+    jj_scanpos = xsp;
+    if (jj_3R_334()) {
+    jj_scanpos = xsp;
+    if (jj_3R_335()) {
+    jj_scanpos = xsp;
+    if (jj_3R_336()) {
+    jj_scanpos = xsp;
+    if (jj_3R_337()) {
+    jj_scanpos = xsp;
+    if (jj_3R_338()) {
+    jj_scanpos = xsp;
+    if (jj_3R_339()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_344() {
+    if (jj_scan_token(SUPER)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_363()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_94()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_107() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_156()) {
+    jj_scanpos = xsp;
+    if (jj_3R_157()) {
+    jj_scanpos = xsp;
+    if (jj_3R_158()) {
+    jj_scanpos = xsp;
+    if (jj_3R_159()) {
+    jj_scanpos = xsp;
+    if (jj_3R_160()) {
+    jj_scanpos = xsp;
+    if (jj_3R_161()) {
+    jj_scanpos = xsp;
+    if (jj_3R_162()) {
+    jj_scanpos = xsp;
+    if (jj_3R_163()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_342() {
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_343() {
+    if (jj_scan_token(EXTENDS)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_362()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_94()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_314() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_343()) {
+    jj_scanpos = xsp;
+    if (jj_3R_344()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_312() {
+    Token xsp;
+    if (jj_3R_342()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_342()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_185()) return true;
+    return false;
+  }
+
+  private boolean jj_3_33() {
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3_32() {
+    if (jj_3R_113()) return true;
+    return false;
+  }
+
+  private boolean jj_3_35() {
+    Token xsp;
+    if (jj_3_33()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_33()) { jj_scanpos = xsp; break; }
+    }
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_34()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_229() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_199()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_311() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_289() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_311()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3_35()) {
+    jj_scanpos = xsp;
+    if (jj_3R_312()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_313() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_263() {
+    if (jj_scan_token(HOOK)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_314()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_292() {
+    if (jj_3R_187()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_32()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_232() {
+    if (jj_3R_263()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_231() {
+    if (jj_3R_94()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_460() {
+    if (jj_3R_462()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_230() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_199() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_230()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3R_231()) {
+    jj_scanpos = xsp;
+    if (jj_3R_232()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_291() {
+    if (jj_3R_289()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_96() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_98() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_290() {
+    if (jj_3R_97()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_313()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_138() {
+    if (jj_scan_token(132)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_262() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_290()) jj_scanpos = xsp;
+    if (jj_3R_198()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_291()) {
+    jj_scanpos = xsp;
+    if (jj_3R_292()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_95() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_284() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3_13() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_96()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_137() {
+    if (jj_scan_token(LT)) return true;
+    if (jj_3R_199()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_229()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_97() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_137()) {
+    jj_scanpos = xsp;
+    if (jj_3R_138()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3_16() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3_15() {
+    if (jj_scan_token(DOT)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_98()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(IDENTIFIER)) return true;
+    xsp = jj_scanpos;
+    if (jj_3_16()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_261() {
+    if (jj_3R_107()) return true;
+    if (jj_3R_289()) return true;
+    return false;
+  }
+
+  private boolean jj_3_12() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_95()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_386() {
+    if (jj_scan_token(THROWS)) return true;
+    if (jj_3R_401()) return true;
+    return false;
+  }
+
+  private boolean jj_3_14() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_260() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_198() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_14()) jj_scanpos = xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_15()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_225() {
+    if (jj_scan_token(NEW)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_260()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3R_261()) {
+    jj_scanpos = xsp;
+    if (jj_3R_262()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_462() {
+    if (jj_scan_token(_DEFAULT)) return true;
+    if (jj_3R_121()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_136() {
+    if (jj_3R_198()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_13()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_135() {
+    if (jj_3R_107()) return true;
+    Token xsp;
+    if (jj_3_12()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_12()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_94() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_135()) {
+    jj_scanpos = xsp;
+    if (jj_3R_136()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_247() {
+    if (jj_3R_100()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_284()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_455() {
+    if (jj_3R_87()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_460()) jj_scanpos = xsp;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_219() {
+    if (jj_3R_247()) return true;
+    return false;
+  }
+
+  private boolean jj_3_47() {
+    if (jj_3R_87()) return true;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_443() {
+    if (jj_3R_302()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_442() {
+    if (jj_3R_300()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_187() {
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_219()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_126() {
+    if (jj_3R_107()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_441() {
+    if (jj_3R_299()) return true;
+    return false;
+  }
+
+  private boolean jj_3_11() {
+    if (jj_3R_94()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_440() {
+    if (jj_3R_298()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_87() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_11()) {
+    jj_scanpos = xsp;
+    if (jj_3R_126()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_439() {
+    if (jj_3R_455()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_286() {
+    if (jj_scan_token(NULL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_308() {
+    if (jj_scan_token(FALSE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_307() {
+    if (jj_scan_token(TRUE)) return true;
+    return false;
+  }
+
+  private boolean jj_3_46() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_121()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_426() {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_427() {
+    if (jj_3R_116()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_439()) {
+    jj_scanpos = xsp;
+    if (jj_3R_440()) {
+    jj_scanpos = xsp;
+    if (jj_3R_441()) {
+    jj_scanpos = xsp;
+    if (jj_3R_442()) {
+    jj_scanpos = xsp;
+    if (jj_3R_443()) return true;
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_127() {
+    if (jj_scan_token(STATIC)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_89() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_127()) jj_scanpos = xsp;
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_285() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_307()) {
+    jj_scanpos = xsp;
+    if (jj_3R_308()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_409() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_426()) {
+    jj_scanpos = xsp;
+    if (jj_3R_427()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_254() {
+    if (jj_3R_286()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_218() {
+    if (jj_3R_246()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_253() {
+    if (jj_3R_285()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_184() {
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_218()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_399() {
+    if (jj_3R_409()) return true;
+    return false;
+  }
+
+  private boolean jj_3_9() {
+    if (jj_3R_92()) return true;
+    if (jj_scan_token(DOT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_252() {
+    if (jj_scan_token(STRING_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_251() {
+    if (jj_scan_token(CHARACTER_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_384() {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_399()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_93() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_189() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3_10() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_93()) jj_scanpos = xsp;
+    if (jj_scan_token(THIS)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_250() {
+    if (jj_scan_token(FLOATING_POINT_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_188() {
+    if (jj_3R_92()) return true;
+    if (jj_scan_token(DOT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_249() {
+    if (jj_scan_token(LONG_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_132() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_188()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_189()) jj_scanpos = xsp;
+    if (jj_scan_token(SUPER)) return true;
+    if (jj_3R_187()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_186() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_248() {
+    if (jj_scan_token(INTEGER_LITERAL)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_131() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_186()) jj_scanpos = xsp;
+    if (jj_scan_token(THIS)) return true;
+    if (jj_3R_187()) return true;
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_300() {
+    if (jj_scan_token(AT)) return true;
+    if (jj_scan_token(INTERFACE)) return true;
+    if (jj_3R_119()) return true;
+    if (jj_3R_384()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_112() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_220() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_248()) {
+    jj_scanpos = xsp;
+    if (jj_3R_249()) {
+    jj_scanpos = xsp;
+    if (jj_3R_250()) {
+    jj_scanpos = xsp;
+    if (jj_3R_251()) {
+    jj_scanpos = xsp;
+    if (jj_3R_252()) {
+    jj_scanpos = xsp;
+    if (jj_3R_253()) {
+    jj_scanpos = xsp;
+    if (jj_3R_254()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_91() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_131()) {
+    jj_scanpos = xsp;
+    if (jj_3R_132()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_166() {
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_3R_100()) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3_31() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_112()) jj_scanpos = xsp;
+    if (jj_scan_token(IDENTIFIER)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_324() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_323()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_347() {
+    if (jj_3R_121()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_46()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_238() {
+    if (jj_3R_187()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_237() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_278() {
+    if (jj_3R_304()) return true;
+    return false;
+  }
+
+  private boolean jj_3_8() {
+    if (jj_3R_91()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_204() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_237()) jj_scanpos = xsp;
+    if (jj_3R_227()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_238()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_212() {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_347()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(88)) jj_scanpos = xsp;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3_7() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_90()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_203() {
+    if (jj_3R_225()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_167() {
+    if (jj_scan_token(ELLIPSIS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_202() {
+    if (jj_scan_token(THIS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_177() {
+    if (jj_3R_151()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_287() {
+    if (jj_3R_309()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_176() {
+    if (jj_3R_212()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_175() {
+    if (jj_3R_123()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_387() {
+    if (jj_3R_91()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_340() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_110()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_165() {
+    if (jj_scan_token(DOT)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_202()) {
+    jj_scanpos = xsp;
+    if (jj_3R_203()) {
+    jj_scanpos = xsp;
+    if (jj_3R_204()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_320() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_301() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_320()) jj_scanpos = xsp;
+    if (jj_3R_227()) return true;
+    if (jj_3R_385()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_386()) jj_scanpos = xsp;
+    if (jj_scan_token(LBRACE)) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_387()) jj_scanpos = xsp;
+    if (jj_3R_184()) return true;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_121() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_175()) {
+    jj_scanpos = xsp;
+    if (jj_3R_176()) {
+    jj_scanpos = xsp;
+    if (jj_3R_177()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_109() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_165()) {
+    jj_scanpos = xsp;
+    if (jj_3R_166()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_410() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_110()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_323() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(ASSIGN)) return true;
+    if (jj_3R_121()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_164() {
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(SUPER)) return true;
+    return false;
+  }
+
+  private boolean jj_3_30() {
+    if (jj_3R_109()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_226() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_304() {
+    if (jj_3R_323()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_324()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_108() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_30()) {
+    jj_scanpos = xsp;
+    if (jj_3R_164()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_228() {
+    if (jj_3R_187()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_110() {
+    if (jj_3R_116()) return true;
+    if (jj_3R_87()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_167()) jj_scanpos = xsp;
+    if (jj_3R_168()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_197() {
+    if (jj_3R_227()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_228()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3_29() {
+    if (jj_3R_111()) return true;
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_214() {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_119()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_121()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_389() {
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3_28() {
+    if (jj_3R_111()) return true;
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(CLASS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_341() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_168()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_120() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    if (jj_scan_token(ASSIGN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_205() {
+    if (jj_scan_token(LBRACKET)) return true;
+    if (jj_scan_token(RBRACKET)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_288() {
+    if (jj_3R_310()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_310() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_168()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_341()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_196() {
+    if (jj_3R_111()) return true;
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_226()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(78)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(43)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_215() {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_119()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_322() {
+    if (jj_3R_90()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_7()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_195() {
+    if (jj_3R_111()) return true;
+    if (jj_scan_token(DOT)) return true;
+    if (jj_scan_token(CLASS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_194() {
+    if (jj_3R_225()) return true;
+    return false;
+  }
+
+  private boolean jj_3_27() {
+    if (jj_3R_110()) return true;
+    return false;
+  }
+
+  private boolean jj_3_45() {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_119()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_309() {
+    if (jj_scan_token(COMMA)) return true;
+    if (jj_3R_110()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_340()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3_43() {
+    if (jj_scan_token(SEMICOLON)) return true;
+    if (jj_3R_117()) return true;
+    return false;
+  }
+
+  private boolean jj_3_44() {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_119()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_120()) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(82)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_213() {
+    if (jj_scan_token(AT)) return true;
+    if (jj_3R_119()) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_278()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_400() {
+    if (jj_3R_110()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_410()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_180() {
+    if (jj_3R_215()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_259() {
+    if (jj_3R_100()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_288()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_258() {
+    if (jj_3R_110()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_287()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_179() {
+    if (jj_3R_214()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_224() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_258()) {
+    jj_scanpos = xsp;
+    if (jj_3R_259()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_385() {
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_400()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_178() {
+    if (jj_3R_213()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_257() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_193() {
+    if (jj_scan_token(LPAREN)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_224()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_222() {
+    if (jj_scan_token(DOUBLECOLON)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_257()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(78)) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(43)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_123() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_178()) {
+    jj_scanpos = xsp;
+    if (jj_3R_179()) {
+    jj_scanpos = xsp;
+    if (jj_3R_180()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_223() {
+    if (jj_3R_187()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_152() {
+    return false;
+  }
+
+  private boolean jj_3R_391() {
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_390() {
+    if (jj_scan_token(THROWS)) return true;
+    if (jj_3R_401()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_321() {
+    if (jj_3R_125()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_303() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_321()) jj_scanpos = xsp;
+    if (jj_3R_111()) return true;
+    if (jj_3R_119()) return true;
+    if (jj_3R_385()) return true;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_389()) { jj_scanpos = xsp; break; }
+    }
+    xsp = jj_scanpos;
+    if (jj_3R_390()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_391()) {
+    jj_scanpos = xsp;
+    if (jj_scan_token(87)) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_153() {
+    return false;
+  }
+
+  private boolean jj_3R_102() {
+    jj_lookingAhead = true;
+    jj_semLA = getToken(1).kind == GT &&
+                ((GTToken)getToken(1)).realKind == RSIGNEDSHIFT;
+    jj_lookingAhead = false;
+    if (!jj_semLA || jj_3R_152()) return true;
+    if (jj_scan_token(GT)) return true;
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_256() {
+    if (jj_3R_187()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_221() {
+    if (jj_scan_token(DOT)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_255()) jj_scanpos = xsp;
+    if (jj_3R_227()) return true;
+    xsp = jj_scanpos;
+    if (jj_3R_256()) jj_scanpos = xsp;
+    return false;
+  }
+
+  private boolean jj_3R_255() {
+    if (jj_3R_97()) return true;
+    return false;
+  }
+
+  private boolean jj_3_26() {
+    if (jj_3R_109()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_192() {
+    if (jj_scan_token(SUPER)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_221()) {
+    jj_scanpos = xsp;
+    if (jj_3R_222()) {
+    jj_scanpos = xsp;
+    if (jj_3R_223()) return true;
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_103() {
+    jj_lookingAhead = true;
+    jj_semLA = getToken(1).kind == GT &&
+                ((GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT;
+    jj_lookingAhead = false;
+    if (!jj_semLA || jj_3R_153()) return true;
+    if (jj_scan_token(GT)) return true;
+    if (jj_scan_token(GT)) return true;
+    if (jj_scan_token(GT)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_191() {
+    if (jj_scan_token(THIS)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_185() {
+    if (jj_scan_token(LBRACE)) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_322()) jj_scanpos = xsp;
+    xsp = jj_scanpos;
+    if (jj_scan_token(88)) jj_scanpos = xsp;
+    if (jj_scan_token(RBRACE)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_190() {
+    if (jj_3R_220()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_134() {
+    if (jj_3R_109()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_130() {
+    if (jj_3R_100()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_129() {
+    if (jj_3R_185()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_207() {
+    if (jj_scan_token(ASSIGN)) return true;
+    if (jj_3R_90()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_453() {
+    if (jj_3R_117()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3_43()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_133() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_190()) {
+    jj_scanpos = xsp;
+    if (jj_3R_191()) {
+    jj_scanpos = xsp;
+    if (jj_3R_192()) {
+    jj_scanpos = xsp;
+    if (jj_3R_193()) {
+    jj_scanpos = xsp;
+    if (jj_3R_194()) {
+    jj_scanpos = xsp;
+    if (jj_3R_195()) {
+    jj_scanpos = xsp;
+    if (jj_3R_196()) {
+    jj_scanpos = xsp;
+    if (jj_3R_197()) return true;
+    }
+    }
+    }
+    }
+    }
+    }
+    }
+    return false;
+  }
+
+  private boolean jj_3_25() {
+    if (jj_3R_108()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_90() {
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3R_129()) {
+    jj_scanpos = xsp;
+    if (jj_3R_130()) return true;
+    }
+    return false;
+  }
+
+  private boolean jj_3R_454() {
+    if (jj_scan_token(BIT_OR)) return true;
+    if (jj_3R_87()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_438() {
+    if (jj_scan_token(FINALLY)) return true;
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_425() {
+    if (jj_scan_token(FINALLY)) return true;
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3_42() {
+    if (jj_scan_token(SEMICOLON)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_436() {
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_453()) return true;
+    Token xsp;
+    xsp = jj_scanpos;
+    if (jj_3_42()) jj_scanpos = xsp;
+    if (jj_scan_token(RPAREN)) return true;
+    return false;
+  }
+
+  private boolean jj_3R_437() {
+    if (jj_scan_token(CATCH)) return true;
+    if (jj_scan_token(LPAREN)) return true;
+    if (jj_3R_116()) return true;
+    if (jj_3R_87()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_454()) { jj_scanpos = xsp; break; }
+    }
+    if (jj_3R_168()) return true;
+    if (jj_scan_token(RPAREN)) return true;
+    if (jj_3R_128()) return true;
+    return false;
+  }
+
+  private boolean jj_3R_168() {
+    if (jj_scan_token(IDENTIFIER)) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_205()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  private boolean jj_3R_92() {
+    if (jj_3R_133()) return true;
+    Token xsp;
+    while (true) {
+      xsp = jj_scanpos;
+      if (jj_3R_134()) { jj_scanpos = xsp; break; }
+    }
+    return false;
+  }
+
+  /** Generated Token Manager. */
+  public ASTParserTokenManager token_source;
+  JavaCharStream jj_input_stream;
+  /** Current token. */
+  public Token token;
+  /** Next token. */
+  public Token jj_nt;
+  private int jj_ntk;
+  private Token jj_scanpos, jj_lastpos;
+  private int jj_la;
+  /** Whether we are looking ahead. */
+  private boolean jj_lookingAhead = false;
+  private boolean jj_semLA;
+  private int jj_gen;
+  final private int[] jj_la1 = new int[175];
+  static private int[] jj_la1_0;
+  static private int[] jj_la1_1;
+  static private int[] jj_la1_2;
+  static private int[] jj_la1_3;
+  static private int[] jj_la1_4;
+  static {
+      jj_la1_init_0();
+      jj_la1_init_1();
+      jj_la1_init_2();
+      jj_la1_init_3();
+      jj_la1_init_4();
+   }
+   private static void jj_la1_init_0() {
+      jj_la1_0 = new int[] {0x0,0x48101000,0x1,0x0,0x0,0x0,0x40001000,0x8100000,0x48101000,0x100000,0x0,0x10000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4a995000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10000000,0x0,0x0,0x0,0x4a995000,0x800000,0x8100000,0x2094000,0x4a995000,0x0,0x0,0x0,0x22094000,0x22094000,0x0,0x0,0x0,0x0,0x0,0x0,0x42095000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x22094000,0x6359f000,0x0,0x2094000,0x0,0x0,0x2094000,0x0,0x0,0x0,0x0,0x2094000,0x0,0x0,0x10000000,0x10000000,0x2094000,0x2094000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x22094000,0x0,0x0,0x22094000,0x0,0x0,0x2094000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x22094000,0x62095000,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x20000000,0x22094000,0x0,0x0,0x0,0x0,0x0,0x2094000,0x0,0x0,0x0,0x0,0x2349e000,0x0,0x2349e000,0x0,0x22094000,0x0,0x0,0x0,0x0,0x22094000,0x820000,0x820000,0x4000000,0x62095000,0x22094000,0x22094000,0x62095000,0x22094000,0x0,0x0,0x0,0x22094000,0x0,0x40000,0x0,0x80000000,0x0,0x0,0x0,0x22094000,0x22094000,0x0,0x4a195000,0xa194000,0x4a195000,0x800000,};
+   }
+   private static void jj_la1_init_1() {
+      jj_la1_1 = new int[] {0x20,0x8899c500,0x0,0x0,0x80000,0x0,0x8899c400,0x100,0x8899c500,0x100,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0xc89dc781,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc89dc781,0x0,0x100,0x40040281,0xc89dc781,0x0,0x0,0x0,0x51241a81,0x51241a81,0x0,0x0,0x0,0x4000000,0x0,0x0,0x889dc681,0x0,0x0,0x0,0x0,0x4000000,0x0,0x0,0x51241a81,0xfbffdf8b,0x80000,0x40281,0x0,0x0,0x40281,0x0,0x0,0x0,0x0,0x40281,0x0,0x0,0x200000,0x200000,0x40281,0x40040281,0x0,0x0,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x51241a81,0x0,0x0,0x51241a81,0x0,0x0,0x40281,0x0,0x0,0x0,0x800,0x0,0x0,0x0,0x51241a81,0xd9bdde81,0x0,0x800,0x0,0x11201800,0x0,0x0,0x0,0x0,0x1000800,0x0,0x10001000,0x10000000,0x51241a81,0x0,0x0,0x0,0x0,0x0,0x40281,0x0,0x0,0x0,0x0,0x73e61a8b,0x0,0x73e61a8b,0x0,0x51241a81,0x0,0x800,0x0,0x0,0x51241a81,0x0,0x0,0x0,0xd9bdde81,0x51241a81,0x51241a81,0xd9bdde81,0x51241a81,0x0,0x0,0x0,0x51241a81,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x51241a81,0x51241a81,0x0,0x889dc781,0x40381,0x889dc781,0x0,};
+   }
+   private static void jj_la1_init_2() {
+      jj_la1_2 = new int[] {0x0,0x4800000,0x0,0x4000000,0x0,0x2000000,0x4000000,0x4000000,0x4800000,0x0,0x10000000,0x0,0x0,0x4000000,0x1000000,0x4000000,0x1000000,0x0,0x4004000,0x1000000,0x14884000,0x800000,0x4000000,0x20000,0x80000,0x4000000,0x1000000,0x4000000,0x0,0x4000000,0x0,0x4000000,0x14884000,0x0,0x4000000,0x10004000,0x14804000,0x1000000,0x8000000,0x200000,0x600a7086,0x600a7086,0x1000000,0x10000000,0x200000,0x0,0x880000,0x1000000,0x4004000,0x1000000,0x1000000,0x0,0x10000000,0x0,0x10000000,0x10000000,0x10027086,0x48a7087,0x0,0x0,0x4000000,0x4000000,0x4000,0x4000000,0x1000000,0x10000000,0x4000000,0x80004000,0x4000000,0x4000000,0x0,0x0,0x0,0x4000,0x4000000,0x1000000,0x4000000,0x1000000,0x10000000,0x4000,0x0,0x8000000,0x8000000,0x80000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10000000,0x10000000,0x0,0x0,0x0,0x0,0x0,0x0,0x60027086,0x60000000,0x60000000,0x27086,0x0,0x4000000,0x4000,0x10000000,0x20000,0x10000000,0x4000,0x2020000,0x1000000,0x1000000,0x60027086,0x64027086,0x10000000,0x4000,0x20000,0x23086,0x4000,0x2000000,0x10000000,0x20000,0x0,0x2200000,0x3086,0x0,0x60027086,0x1000000,0x4000000,0x4000000,0x10000000,0x4220000,0x10004000,0x4000000,0x4000000,0x200000,0x200000,0x8a7087,0x0,0x8a7087,0x1000000,0x600a7086,0x10000000,0x4000,0x8000000,0x8000000,0x27086,0x0,0x0,0x0,0x64027086,0x60027086,0x60027086,0x64827086,0x60027086,0x1000000,0x4000,0x4000,0x60027086,0x20000,0x0,0x0,0x0,0x4000000,0x4000,0x1000000,0x640a7086,0x640a7086,0x1000000,0x4804000,0x4004000,0x4804000,0x0,};
+   }
+   private static void jj_la1_init_3() {
+      jj_la1_3 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780,0x780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20000000,0x0,0x0,0x0,0x0,0x0,0x180,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0000000,0xdffc0000,0x1ffc0000,0x0,0x20,0x40,0x4000,0x8000,0x2000,0x12,0x12,0x0,0xc,0xc,0x20000,0x600,0x600,0x11800,0x11800,0x600,0x780,0x0,0x0,0x0,0x180,0x0,0x0,0x0,0x0,0x0,0x0,0x80000000,0x0,0x0,0x780,0x780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x780,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x180,0x1,0x180,0x0,0x780,0x0,0x0,0xdffc0180,0xdffc0180,0x100,0x0,0x0,0x0,0x780,0x780,0x780,0x780,0x780,0x0,0x0,0x0,0x780,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x780,0x780,0x0,0x0,0x0,0x0,0x0,};
+   }
+   private static void jj_la1_init_4() {
+      jj_la1_4 = new int[] {0x0,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+   }
+  final private JJCalls[] jj_2_rtns = new JJCalls[47];
+  private boolean jj_rescan = false;
+  private int jj_gc = 0;
+
+  /** Constructor with InputStream. */
+  public ASTParser(java.io.InputStream stream) {
+     this(stream, null);
+  }
+  /** Constructor with InputStream and supplied encoding */
+  public ASTParser(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source = new ASTParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 175; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream stream) {
+     ReInit(stream, null);
+  }
+  /** Reinitialise. */
+  public void ReInit(java.io.InputStream stream, String encoding) {
+    try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 175; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Constructor. */
+  public ASTParser(java.io.Reader stream) {
+    jj_input_stream = new JavaCharStream(stream, 1, 1);
+    token_source = new ASTParserTokenManager(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 175; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+  public void ReInit(java.io.Reader stream) {
+    jj_input_stream.ReInit(stream, 1, 1);
+    token_source.ReInit(jj_input_stream);
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 175; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Constructor with generated Token Manager. */
+  public ASTParser(ASTParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 175; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  /** Reinitialise. */
+  public void ReInit(ASTParserTokenManager tm) {
+    token_source = tm;
+    token = new Token();
+    jj_ntk = -1;
+    jj_gen = 0;
+    for (int i = 0; i < 175; i++) jj_la1[i] = -1;
+    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
+  }
+
+  private Token jj_consume_token(int kind) {
+    Token oldToken;
+    if ((oldToken = token).next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    if (token.kind == kind) {
+      jj_gen++;
+      if (++jj_gc > 100) {
+        jj_gc = 0;
+        for (int i = 0; i < jj_2_rtns.length; i++) {
+          JJCalls c = jj_2_rtns[i];
+          while (c != null) {
+            if (c.gen < jj_gen) c.first = null;
+            c = c.next;
+          }
+        }
+      }
+      return token;
+    }
+    token = oldToken;
+    jj_kind = kind;
+    throw generateParseException();
+  }
+
+  static private final class LookaheadSuccess extends java.lang.Error { }
+  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
+  private boolean jj_scan_token(int kind) {
+    if (jj_scanpos == jj_lastpos) {
+      jj_la--;
+      if (jj_scanpos.next == null) {
+        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
+      } else {
+        jj_lastpos = jj_scanpos = jj_scanpos.next;
+      }
+    } else {
+      jj_scanpos = jj_scanpos.next;
+    }
+    if (jj_rescan) {
+      int i = 0; Token tok = token;
+      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
+      if (tok != null) jj_add_error_token(kind, i);
+    }
+    if (jj_scanpos.kind != kind) return true;
+    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
+    return false;
+  }
+
+
+/** Get the next Token. */
+  final public Token getNextToken() {
+    if (token.next != null) token = token.next;
+    else token = token.next = token_source.getNextToken();
+    jj_ntk = -1;
+    jj_gen++;
+    return token;
+  }
+
+/** Get the specific Token. */
+  final public Token getToken(int index) {
+    Token t = jj_lookingAhead ? jj_scanpos : token;
+    for (int i = 0; i < index; i++) {
+      if (t.next != null) t = t.next;
+      else t = t.next = token_source.getNextToken();
+    }
+    return t;
+  }
+
+  private int jj_ntk() {
+    if ((jj_nt=token.next) == null)
+      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
+    else
+      return (jj_ntk = jj_nt.kind);
+  }
+
+  private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
+  private int[] jj_expentry;
+  private int jj_kind = -1;
+  private int[] jj_lasttokens = new int[100];
+  private int jj_endpos;
+
+  private void jj_add_error_token(int kind, int pos) {
+    if (pos >= 100) return;
+    if (pos == jj_endpos + 1) {
+      jj_lasttokens[jj_endpos++] = kind;
+    } else if (jj_endpos != 0) {
+      jj_expentry = new int[jj_endpos];
+      for (int i = 0; i < jj_endpos; i++) {
+        jj_expentry[i] = jj_lasttokens[i];
+      }
+      jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
+        int[] oldentry = (int[])(it.next());
+        if (oldentry.length == jj_expentry.length) {
+          for (int i = 0; i < jj_expentry.length; i++) {
+            if (oldentry[i] != jj_expentry[i]) {
+              continue jj_entries_loop;
+            }
+          }
+          jj_expentries.add(jj_expentry);
+          break jj_entries_loop;
+        }
+      }
+      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
+    }
+  }
+
+  /** Generate ParseException. */
+  public ParseException generateParseException() {
+    jj_expentries.clear();
+    boolean[] la1tokens = new boolean[133];
+    if (jj_kind >= 0) {
+      la1tokens[jj_kind] = true;
+      jj_kind = -1;
+    }
+    for (int i = 0; i < 175; i++) {
+      if (jj_la1[i] == jj_gen) {
+        for (int j = 0; j < 32; j++) {
+          if ((jj_la1_0[i] & (1<<j)) != 0) {
+            la1tokens[j] = true;
+          }
+          if ((jj_la1_1[i] & (1<<j)) != 0) {
+            la1tokens[32+j] = true;
+          }
+          if ((jj_la1_2[i] & (1<<j)) != 0) {
+            la1tokens[64+j] = true;
+          }
+          if ((jj_la1_3[i] & (1<<j)) != 0) {
+            la1tokens[96+j] = true;
+          }
+          if ((jj_la1_4[i] & (1<<j)) != 0) {
+            la1tokens[128+j] = true;
+          }
+        }
+      }
+    }
+    for (int i = 0; i < 133; i++) {
+      if (la1tokens[i]) {
+        jj_expentry = new int[1];
+        jj_expentry[0] = i;
+        jj_expentries.add(jj_expentry);
+      }
+    }
+    jj_endpos = 0;
+    jj_rescan_token();
+    jj_add_error_token(0, 0);
+    int[][] exptokseq = new int[jj_expentries.size()][];
+    for (int i = 0; i < jj_expentries.size(); i++) {
+      exptokseq[i] = jj_expentries.get(i);
+    }
+    return new ParseException(token, exptokseq, tokenImage);
+  }
+
+  /** Enable tracing. */
+  final public void enable_tracing() {
+  }
+
+  /** Disable tracing. */
+  final public void disable_tracing() {
+  }
+
+  private void jj_rescan_token() {
+    jj_rescan = true;
+    for (int i = 0; i < 47; i++) {
+    try {
+      JJCalls p = jj_2_rtns[i];
+      do {
+        if (p.gen > jj_gen) {
+          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
+          switch (i) {
+            case 0: jj_3_1(); break;
+            case 1: jj_3_2(); break;
+            case 2: jj_3_3(); break;
+            case 3: jj_3_4(); break;
+            case 4: jj_3_5(); break;
+            case 5: jj_3_6(); break;
+            case 6: jj_3_7(); break;
+            case 7: jj_3_8(); break;
+            case 8: jj_3_9(); break;
+            case 9: jj_3_10(); break;
+            case 10: jj_3_11(); break;
+            case 11: jj_3_12(); break;
+            case 12: jj_3_13(); break;
+            case 13: jj_3_14(); break;
+            case 14: jj_3_15(); break;
+            case 15: jj_3_16(); break;
+            case 16: jj_3_17(); break;
+            case 17: jj_3_18(); break;
+            case 18: jj_3_19(); break;
+            case 19: jj_3_20(); break;
+            case 20: jj_3_21(); break;
+            case 21: jj_3_22(); break;
+            case 22: jj_3_23(); break;
+            case 23: jj_3_24(); break;
+            case 24: jj_3_25(); break;
+            case 25: jj_3_26(); break;
+            case 26: jj_3_27(); break;
+            case 27: jj_3_28(); break;
+            case 28: jj_3_29(); break;
+            case 29: jj_3_30(); break;
+            case 30: jj_3_31(); break;
+            case 31: jj_3_32(); break;
+            case 32: jj_3_33(); break;
+            case 33: jj_3_34(); break;
+            case 34: jj_3_35(); break;
+            case 35: jj_3_36(); break;
+            case 36: jj_3_37(); break;
+            case 37: jj_3_38(); break;
+            case 38: jj_3_39(); break;
+            case 39: jj_3_40(); break;
+            case 40: jj_3_41(); break;
+            case 41: jj_3_42(); break;
+            case 42: jj_3_43(); break;
+            case 43: jj_3_44(); break;
+            case 44: jj_3_45(); break;
+            case 45: jj_3_46(); break;
+            case 46: jj_3_47(); break;
+          }
+        }
+        p = p.next;
+      } while (p != null);
+      } catch(LookaheadSuccess ls) { }
+    }
+    jj_rescan = false;
+  }
+
+  private void jj_save(int index, int xla) {
+    JJCalls p = jj_2_rtns[index];
+    while (p.gen > jj_gen) {
+      if (p.next == null) { p = p.next = new JJCalls(); break; }
+      p = p.next;
+    }
+    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
+  }
+
+  static final class JJCalls {
+    int gen;
+    Token first;
+    int arg;
+    JJCalls next;
+  }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParserConstants.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParserConstants.java
new file mode 100644
index 0000000..3692dfc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParserConstants.java
@@ -0,0 +1,414 @@
+/* Generated By:JavaCC: Do not edit this line. ASTParserConstants.java */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+
+/**
+ * Token literal values and constants.
+ * Generated by org.javacc.parser.OtherFilesGen#start()
+ */
+public interface ASTParserConstants {
+
+  /** End of File. */
+  int EOF = 0;
+  /** RegularExpression Id. */
+  int SINGLE_LINE_COMMENT = 6;
+  /** RegularExpression Id. */
+  int JAVA_DOC_COMMENT = 9;
+  /** RegularExpression Id. */
+  int MULTI_LINE_COMMENT = 10;
+  /** RegularExpression Id. */
+  int ABSTRACT = 12;
+  /** RegularExpression Id. */
+  int ASSERT = 13;
+  /** RegularExpression Id. */
+  int BOOLEAN = 14;
+  /** RegularExpression Id. */
+  int BREAK = 15;
+  /** RegularExpression Id. */
+  int BYTE = 16;
+  /** RegularExpression Id. */
+  int CASE = 17;
+  /** RegularExpression Id. */
+  int CATCH = 18;
+  /** RegularExpression Id. */
+  int CHAR = 19;
+  /** RegularExpression Id. */
+  int CLASS = 20;
+  /** RegularExpression Id. */
+  int CONST = 21;
+  /** RegularExpression Id. */
+  int CONTINUE = 22;
+  /** RegularExpression Id. */
+  int _DEFAULT = 23;
+  /** RegularExpression Id. */
+  int DO = 24;
+  /** RegularExpression Id. */
+  int DOUBLE = 25;
+  /** RegularExpression Id. */
+  int ELSE = 26;
+  /** RegularExpression Id. */
+  int ENUM = 27;
+  /** RegularExpression Id. */
+  int EXTENDS = 28;
+  /** RegularExpression Id. */
+  int FALSE = 29;
+  /** RegularExpression Id. */
+  int FINAL = 30;
+  /** RegularExpression Id. */
+  int FINALLY = 31;
+  /** RegularExpression Id. */
+  int FLOAT = 32;
+  /** RegularExpression Id. */
+  int FOR = 33;
+  /** RegularExpression Id. */
+  int GOTO = 34;
+  /** RegularExpression Id. */
+  int IF = 35;
+  /** RegularExpression Id. */
+  int IMPLEMENTS = 36;
+  /** RegularExpression Id. */
+  int IMPORT = 37;
+  /** RegularExpression Id. */
+  int INSTANCEOF = 38;
+  /** RegularExpression Id. */
+  int INT = 39;
+  /** RegularExpression Id. */
+  int INTERFACE = 40;
+  /** RegularExpression Id. */
+  int LONG = 41;
+  /** RegularExpression Id. */
+  int NATIVE = 42;
+  /** RegularExpression Id. */
+  int NEW = 43;
+  /** RegularExpression Id. */
+  int NULL = 44;
+  /** RegularExpression Id. */
+  int PACKAGE = 45;
+  /** RegularExpression Id. */
+  int PRIVATE = 46;
+  /** RegularExpression Id. */
+  int PROTECTED = 47;
+  /** RegularExpression Id. */
+  int PUBLIC = 48;
+  /** RegularExpression Id. */
+  int RETURN = 49;
+  /** RegularExpression Id. */
+  int SHORT = 50;
+  /** RegularExpression Id. */
+  int STATIC = 51;
+  /** RegularExpression Id. */
+  int STRICTFP = 52;
+  /** RegularExpression Id. */
+  int SUPER = 53;
+  /** RegularExpression Id. */
+  int SWITCH = 54;
+  /** RegularExpression Id. */
+  int SYNCHRONIZED = 55;
+  /** RegularExpression Id. */
+  int THIS = 56;
+  /** RegularExpression Id. */
+  int THROW = 57;
+  /** RegularExpression Id. */
+  int THROWS = 58;
+  /** RegularExpression Id. */
+  int TRANSIENT = 59;
+  /** RegularExpression Id. */
+  int TRUE = 60;
+  /** RegularExpression Id. */
+  int TRY = 61;
+  /** RegularExpression Id. */
+  int VOID = 62;
+  /** RegularExpression Id. */
+  int VOLATILE = 63;
+  /** RegularExpression Id. */
+  int WHILE = 64;
+  /** RegularExpression Id. */
+  int LONG_LITERAL = 65;
+  /** RegularExpression Id. */
+  int INTEGER_LITERAL = 66;
+  /** RegularExpression Id. */
+  int DECIMAL_LITERAL = 67;
+  /** RegularExpression Id. */
+  int HEX_LITERAL = 68;
+  /** RegularExpression Id. */
+  int OCTAL_LITERAL = 69;
+  /** RegularExpression Id. */
+  int BINARY_LITERAL = 70;
+  /** RegularExpression Id. */
+  int FLOATING_POINT_LITERAL = 71;
+  /** RegularExpression Id. */
+  int DECIMAL_FLOATING_POINT_LITERAL = 72;
+  /** RegularExpression Id. */
+  int DECIMAL_EXPONENT = 73;
+  /** RegularExpression Id. */
+  int HEXADECIMAL_FLOATING_POINT_LITERAL = 74;
+  /** RegularExpression Id. */
+  int HEXADECIMAL_EXPONENT = 75;
+  /** RegularExpression Id. */
+  int CHARACTER_LITERAL = 76;
+  /** RegularExpression Id. */
+  int STRING_LITERAL = 77;
+  /** RegularExpression Id. */
+  int IDENTIFIER = 78;
+  /** RegularExpression Id. */
+  int LETTER = 79;
+  /** RegularExpression Id. */
+  int PART_LETTER = 80;
+  /** RegularExpression Id. */
+  int LPAREN = 81;
+  /** RegularExpression Id. */
+  int RPAREN = 82;
+  /** RegularExpression Id. */
+  int LBRACE = 83;
+  /** RegularExpression Id. */
+  int RBRACE = 84;
+  /** RegularExpression Id. */
+  int LBRACKET = 85;
+  /** RegularExpression Id. */
+  int RBRACKET = 86;
+  /** RegularExpression Id. */
+  int SEMICOLON = 87;
+  /** RegularExpression Id. */
+  int COMMA = 88;
+  /** RegularExpression Id. */
+  int DOT = 89;
+  /** RegularExpression Id. */
+  int AT = 90;
+  /** RegularExpression Id. */
+  int ASSIGN = 91;
+  /** RegularExpression Id. */
+  int LT = 92;
+  /** RegularExpression Id. */
+  int BANG = 93;
+  /** RegularExpression Id. */
+  int TILDE = 94;
+  /** RegularExpression Id. */
+  int HOOK = 95;
+  /** RegularExpression Id. */
+  int COLON = 96;
+  /** RegularExpression Id. */
+  int EQ = 97;
+  /** RegularExpression Id. */
+  int LE = 98;
+  /** RegularExpression Id. */
+  int GE = 99;
+  /** RegularExpression Id. */
+  int NE = 100;
+  /** RegularExpression Id. */
+  int SC_OR = 101;
+  /** RegularExpression Id. */
+  int SC_AND = 102;
+  /** RegularExpression Id. */
+  int INCR = 103;
+  /** RegularExpression Id. */
+  int DECR = 104;
+  /** RegularExpression Id. */
+  int PLUS = 105;
+  /** RegularExpression Id. */
+  int MINUS = 106;
+  /** RegularExpression Id. */
+  int STAR = 107;
+  /** RegularExpression Id. */
+  int SLASH = 108;
+  /** RegularExpression Id. */
+  int BIT_AND = 109;
+  /** RegularExpression Id. */
+  int BIT_OR = 110;
+  /** RegularExpression Id. */
+  int XOR = 111;
+  /** RegularExpression Id. */
+  int REM = 112;
+  /** RegularExpression Id. */
+  int LSHIFT = 113;
+  /** RegularExpression Id. */
+  int PLUSASSIGN = 114;
+  /** RegularExpression Id. */
+  int MINUSASSIGN = 115;
+  /** RegularExpression Id. */
+  int STARASSIGN = 116;
+  /** RegularExpression Id. */
+  int SLASHASSIGN = 117;
+  /** RegularExpression Id. */
+  int ANDASSIGN = 118;
+  /** RegularExpression Id. */
+  int ORASSIGN = 119;
+  /** RegularExpression Id. */
+  int XORASSIGN = 120;
+  /** RegularExpression Id. */
+  int REMASSIGN = 121;
+  /** RegularExpression Id. */
+  int LSHIFTASSIGN = 122;
+  /** RegularExpression Id. */
+  int RSIGNEDSHIFTASSIGN = 123;
+  /** RegularExpression Id. */
+  int RUNSIGNEDSHIFTASSIGN = 124;
+  /** RegularExpression Id. */
+  int ELLIPSIS = 125;
+  /** RegularExpression Id. */
+  int ARROW = 126;
+  /** RegularExpression Id. */
+  int DOUBLECOLON = 127;
+  /** RegularExpression Id. */
+  int RUNSIGNEDSHIFT = 128;
+  /** RegularExpression Id. */
+  int RSIGNEDSHIFT = 129;
+  /** RegularExpression Id. */
+  int GT = 130;
+
+  /** Lexical state. */
+  int DEFAULT = 0;
+  /** Lexical state. */
+  int IN_JAVA_DOC_COMMENT = 1;
+  /** Lexical state. */
+  int IN_MULTI_LINE_COMMENT = 2;
+
+  /** Literal token values. */
+  String[] tokenImage = {
+    "<EOF>",
+    "\" \"",
+    "\"\\t\"",
+    "\"\\n\"",
+    "\"\\r\"",
+    "\"\\f\"",
+    "<SINGLE_LINE_COMMENT>",
+    "<token of kind 7>",
+    "\"/*\"",
+    "\"*/\"",
+    "\"*/\"",
+    "<token of kind 11>",
+    "\"abstract\"",
+    "\"assert\"",
+    "\"boolean\"",
+    "\"break\"",
+    "\"byte\"",
+    "\"case\"",
+    "\"catch\"",
+    "\"char\"",
+    "\"class\"",
+    "\"const\"",
+    "\"continue\"",
+    "\"default\"",
+    "\"do\"",
+    "\"double\"",
+    "\"else\"",
+    "\"enum\"",
+    "\"extends\"",
+    "\"false\"",
+    "\"final\"",
+    "\"finally\"",
+    "\"float\"",
+    "\"for\"",
+    "\"goto\"",
+    "\"if\"",
+    "\"implements\"",
+    "\"import\"",
+    "\"instanceof\"",
+    "\"int\"",
+    "\"interface\"",
+    "\"long\"",
+    "\"native\"",
+    "\"new\"",
+    "\"null\"",
+    "\"package\"",
+    "\"private\"",
+    "\"protected\"",
+    "\"public\"",
+    "\"return\"",
+    "\"short\"",
+    "\"static\"",
+    "\"strictfp\"",
+    "\"super\"",
+    "\"switch\"",
+    "\"synchronized\"",
+    "\"this\"",
+    "\"throw\"",
+    "\"throws\"",
+    "\"transient\"",
+    "\"true\"",
+    "\"try\"",
+    "\"void\"",
+    "\"volatile\"",
+    "\"while\"",
+    "<LONG_LITERAL>",
+    "<INTEGER_LITERAL>",
+    "<DECIMAL_LITERAL>",
+    "<HEX_LITERAL>",
+    "<OCTAL_LITERAL>",
+    "<BINARY_LITERAL>",
+    "<FLOATING_POINT_LITERAL>",
+    "<DECIMAL_FLOATING_POINT_LITERAL>",
+    "<DECIMAL_EXPONENT>",
+    "<HEXADECIMAL_FLOATING_POINT_LITERAL>",
+    "<HEXADECIMAL_EXPONENT>",
+    "<CHARACTER_LITERAL>",
+    "<STRING_LITERAL>",
+    "<IDENTIFIER>",
+    "<LETTER>",
+    "<PART_LETTER>",
+    "\"(\"",
+    "\")\"",
+    "\"{\"",
+    "\"}\"",
+    "\"[\"",
+    "\"]\"",
+    "\";\"",
+    "\",\"",
+    "\".\"",
+    "\"@\"",
+    "\"=\"",
+    "\"<\"",
+    "\"!\"",
+    "\"~\"",
+    "\"?\"",
+    "\":\"",
+    "\"==\"",
+    "\"<=\"",
+    "\">=\"",
+    "\"!=\"",
+    "\"||\"",
+    "\"&&\"",
+    "\"++\"",
+    "\"--\"",
+    "\"+\"",
+    "\"-\"",
+    "\"*\"",
+    "\"/\"",
+    "\"&\"",
+    "\"|\"",
+    "\"^\"",
+    "\"%\"",
+    "\"<<\"",
+    "\"+=\"",
+    "\"-=\"",
+    "\"*=\"",
+    "\"/=\"",
+    "\"&=\"",
+    "\"|=\"",
+    "\"^=\"",
+    "\"%=\"",
+    "\"<<=\"",
+    "\">>=\"",
+    "\">>>=\"",
+    "\"...\"",
+    "\"->\"",
+    "\"::\"",
+    "\">>>\"",
+    "\">>\"",
+    "\">\"",
+    "\"\\u001a\"",
+    "\"<>\"",
+  };
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParserTokenManager.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParserTokenManager.java
new file mode 100644
index 0000000..8c15764
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ASTParserTokenManager.java
@@ -0,0 +1,2559 @@
+/* Generated By:JavaCC: Do not edit this line. ASTParserTokenManager.java */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+import java.io.*;
+import java.util.*;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+
+/** Token Manager. */
+public class ASTParserTokenManager implements ASTParserConstants
+{
+
+  /** Debug output. */
+  public  java.io.PrintStream debugStream = System.out;
+  /** Set debug output. */
+  public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
+private final int jjStopStringLiteralDfa_0(int pos, long active0, long active1, long active2)
+{
+   switch (pos)
+   {
+      case 0:
+         if ((active0 & 0xfffffffffffff000L) != 0L || (active1 & 0x1L) != 0L)
+         {
+            jjmatchedKind = 78;
+            return 43;
+         }
+         if ((active0 & 0x100L) != 0L || (active1 & 0x20100000000000L) != 0L)
+            return 45;
+         if ((active1 & 0x2000000002000000L) != 0L)
+            return 1;
+         return -1;
+      case 1:
+         if ((active0 & 0x803000000L) != 0L)
+            return 43;
+         if ((active0 & 0xfffffff7fcfff000L) != 0L || (active1 & 0x1L) != 0L)
+         {
+            if (jjmatchedPos != 1)
+            {
+               jjmatchedKind = 78;
+               jjmatchedPos = 1;
+            }
+            return 43;
+         }
+         if ((active0 & 0x100L) != 0L)
+            return 50;
+         return -1;
+      case 2:
+         if ((active0 & 0x2000098200000000L) != 0L)
+            return 43;
+         if ((active0 & 0xdffff675fefff000L) != 0L || (active1 & 0x1L) != 0L)
+         {
+            if (jjmatchedPos != 2)
+            {
+               jjmatchedKind = 78;
+               jjmatchedPos = 2;
+            }
+            return 43;
+         }
+         return -1;
+      case 3:
+         if ((active0 & 0x8effe571f2f4f000L) != 0L || (active1 & 0x1L) != 0L)
+         {
+            jjmatchedKind = 78;
+            jjmatchedPos = 3;
+            return 43;
+         }
+         if ((active0 & 0x510012040c0b0000L) != 0L)
+            return 43;
+         return -1;
+      case 4:
+         if ((active0 & 0x88dbe57012c07000L) != 0L)
+         {
+            if (jjmatchedPos != 4)
+            {
+               jjmatchedKind = 78;
+               jjmatchedPos = 4;
+            }
+            return 43;
+         }
+         if ((active0 & 0x6240001e0348000L) != 0L || (active1 & 0x1L) != 0L)
+            return 43;
+         return -1;
+      case 5:
+         if ((active0 & 0x44b042002002000L) != 0L)
+            return 43;
+         if ((active0 & 0x8890e15090c05000L) != 0L)
+         {
+            jjmatchedKind = 78;
+            jjmatchedPos = 5;
+            return 43;
+         }
+         return -1;
+      case 6:
+         if ((active0 & 0x600090804000L) != 0L)
+            return 43;
+         if ((active0 & 0x8890815000401000L) != 0L)
+         {
+            jjmatchedKind = 78;
+            jjmatchedPos = 6;
+            return 43;
+         }
+         return -1;
+      case 7:
+         if ((active0 & 0x880815000000000L) != 0L)
+         {
+            jjmatchedKind = 78;
+            jjmatchedPos = 7;
+            return 43;
+         }
+         if ((active0 & 0x8010000000401000L) != 0L)
+            return 43;
+         return -1;
+      case 8:
+         if ((active0 & 0x800810000000000L) != 0L)
+            return 43;
+         if ((active0 & 0x80005000000000L) != 0L)
+         {
+            jjmatchedKind = 78;
+            jjmatchedPos = 8;
+            return 43;
+         }
+         return -1;
+      case 9:
+         if ((active0 & 0x5000000000L) != 0L)
+            return 43;
+         if ((active0 & 0x80000000000000L) != 0L)
+         {
+            jjmatchedKind = 78;
+            jjmatchedPos = 9;
+            return 43;
+         }
+         return -1;
+      case 10:
+         if ((active0 & 0x80000000000000L) != 0L)
+         {
+            jjmatchedKind = 78;
+            jjmatchedPos = 10;
+            return 43;
+         }
+         return -1;
+      default :
+         return -1;
+   }
+}
+private final int jjStartNfa_0(int pos, long active0, long active1, long active2)
+{
+   return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1, active2), pos + 1);
+}
+private int jjStopAtPos(int pos, int kind)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   return pos + 1;
+}
+private int jjMoveStringLiteralDfa0_0()
+{
+   switch(curChar)
+   {
+      case 26:
+         return jjStopAtPos(0, 131);
+      case 33:
+         jjmatchedKind = 93;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x1000000000L, 0x0L);
+      case 37:
+         jjmatchedKind = 112;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x200000000000000L, 0x0L);
+      case 38:
+         jjmatchedKind = 109;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x40004000000000L, 0x0L);
+      case 40:
+         return jjStopAtPos(0, 81);
+      case 41:
+         return jjStopAtPos(0, 82);
+      case 42:
+         jjmatchedKind = 107;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x10000000000000L, 0x0L);
+      case 43:
+         jjmatchedKind = 105;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x4008000000000L, 0x0L);
+      case 44:
+         return jjStopAtPos(0, 88);
+      case 45:
+         jjmatchedKind = 106;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x4008010000000000L, 0x0L);
+      case 46:
+         jjmatchedKind = 89;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x2000000000000000L, 0x0L);
+      case 47:
+         jjmatchedKind = 108;
+         return jjMoveStringLiteralDfa1_0(0x100L, 0x20000000000000L, 0x0L);
+      case 58:
+         jjmatchedKind = 96;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x8000000000000000L, 0x0L);
+      case 59:
+         return jjStopAtPos(0, 87);
+      case 60:
+         jjmatchedKind = 92;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x402000400000000L, 0x10L);
+      case 61:
+         jjmatchedKind = 91;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x200000000L, 0x0L);
+      case 62:
+         jjmatchedKind = 130;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x1800000800000000L, 0x3L);
+      case 63:
+         return jjStopAtPos(0, 95);
+      case 64:
+         return jjStopAtPos(0, 90);
+      case 91:
+         return jjStopAtPos(0, 85);
+      case 93:
+         return jjStopAtPos(0, 86);
+      case 94:
+         jjmatchedKind = 111;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x100000000000000L, 0x0L);
+      case 97:
+         return jjMoveStringLiteralDfa1_0(0x3000L, 0x0L, 0x0L);
+      case 98:
+         return jjMoveStringLiteralDfa1_0(0x1c000L, 0x0L, 0x0L);
+      case 99:
+         return jjMoveStringLiteralDfa1_0(0x7e0000L, 0x0L, 0x0L);
+      case 100:
+         return jjMoveStringLiteralDfa1_0(0x3800000L, 0x0L, 0x0L);
+      case 101:
+         return jjMoveStringLiteralDfa1_0(0x1c000000L, 0x0L, 0x0L);
+      case 102:
+         return jjMoveStringLiteralDfa1_0(0x3e0000000L, 0x0L, 0x0L);
+      case 103:
+         return jjMoveStringLiteralDfa1_0(0x400000000L, 0x0L, 0x0L);
+      case 105:
+         return jjMoveStringLiteralDfa1_0(0x1f800000000L, 0x0L, 0x0L);
+      case 108:
+         return jjMoveStringLiteralDfa1_0(0x20000000000L, 0x0L, 0x0L);
+      case 110:
+         return jjMoveStringLiteralDfa1_0(0x1c0000000000L, 0x0L, 0x0L);
+      case 112:
+         return jjMoveStringLiteralDfa1_0(0x1e00000000000L, 0x0L, 0x0L);
+      case 114:
+         return jjMoveStringLiteralDfa1_0(0x2000000000000L, 0x0L, 0x0L);
+      case 115:
+         return jjMoveStringLiteralDfa1_0(0xfc000000000000L, 0x0L, 0x0L);
+      case 116:
+         return jjMoveStringLiteralDfa1_0(0x3f00000000000000L, 0x0L, 0x0L);
+      case 118:
+         return jjMoveStringLiteralDfa1_0(0xc000000000000000L, 0x0L, 0x0L);
+      case 119:
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x1L, 0x0L);
+      case 123:
+         return jjStopAtPos(0, 83);
+      case 124:
+         jjmatchedKind = 110;
+         return jjMoveStringLiteralDfa1_0(0x0L, 0x80002000000000L, 0x0L);
+      case 125:
+         return jjStopAtPos(0, 84);
+      case 126:
+         return jjStopAtPos(0, 94);
+      default :
+         return jjMoveNfa_0(0, 0);
+   }
+}
+private int jjMoveStringLiteralDfa1_0(long active0, long active1, long active2)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(0, active0, active1, active2);
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 38:
+         if ((active1 & 0x4000000000L) != 0L)
+            return jjStopAtPos(1, 102);
+         break;
+      case 42:
+         if ((active0 & 0x100L) != 0L)
+            return jjStartNfaWithStates_0(1, 8, 50);
+         break;
+      case 43:
+         if ((active1 & 0x8000000000L) != 0L)
+            return jjStopAtPos(1, 103);
+         break;
+      case 45:
+         if ((active1 & 0x10000000000L) != 0L)
+            return jjStopAtPos(1, 104);
+         break;
+      case 46:
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x2000000000000000L, active2, 0L);
+      case 58:
+         if ((active1 & 0x8000000000000000L) != 0L)
+            return jjStopAtPos(1, 127);
+         break;
+      case 60:
+         if ((active1 & 0x2000000000000L) != 0L)
+         {
+            jjmatchedKind = 113;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x400000000000000L, active2, 0L);
+      case 61:
+         if ((active1 & 0x200000000L) != 0L)
+            return jjStopAtPos(1, 97);
+         else if ((active1 & 0x400000000L) != 0L)
+            return jjStopAtPos(1, 98);
+         else if ((active1 & 0x800000000L) != 0L)
+            return jjStopAtPos(1, 99);
+         else if ((active1 & 0x1000000000L) != 0L)
+            return jjStopAtPos(1, 100);
+         else if ((active1 & 0x4000000000000L) != 0L)
+            return jjStopAtPos(1, 114);
+         else if ((active1 & 0x8000000000000L) != 0L)
+            return jjStopAtPos(1, 115);
+         else if ((active1 & 0x10000000000000L) != 0L)
+            return jjStopAtPos(1, 116);
+         else if ((active1 & 0x20000000000000L) != 0L)
+            return jjStopAtPos(1, 117);
+         else if ((active1 & 0x40000000000000L) != 0L)
+            return jjStopAtPos(1, 118);
+         else if ((active1 & 0x80000000000000L) != 0L)
+            return jjStopAtPos(1, 119);
+         else if ((active1 & 0x100000000000000L) != 0L)
+            return jjStopAtPos(1, 120);
+         else if ((active1 & 0x200000000000000L) != 0L)
+            return jjStopAtPos(1, 121);
+         break;
+      case 62:
+         if ((active1 & 0x4000000000000000L) != 0L)
+            return jjStopAtPos(1, 126);
+         else if ((active2 & 0x2L) != 0L)
+         {
+            jjmatchedKind = 129;
+            jjmatchedPos = 1;
+         }
+         else if ((active2 & 0x10L) != 0L)
+            return jjStopAtPos(1, 132);
+         return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x1800000000000000L, active2, 0x1L);
+      case 97:
+         return jjMoveStringLiteralDfa2_0(active0, 0x240020060000L, active1, 0L, active2, 0L);
+      case 98:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1000L, active1, 0L, active2, 0L);
+      case 101:
+         return jjMoveStringLiteralDfa2_0(active0, 0x2080000800000L, active1, 0L, active2, 0L);
+      case 102:
+         if ((active0 & 0x800000000L) != 0L)
+            return jjStartNfaWithStates_0(1, 35, 43);
+         break;
+      case 104:
+         return jjMoveStringLiteralDfa2_0(active0, 0x704000000080000L, active1, 0x1L, active2, 0L);
+      case 105:
+         return jjMoveStringLiteralDfa2_0(active0, 0xc0000000L, active1, 0L, active2, 0L);
+      case 108:
+         return jjMoveStringLiteralDfa2_0(active0, 0x104100000L, active1, 0L, active2, 0L);
+      case 109:
+         return jjMoveStringLiteralDfa2_0(active0, 0x3000000000L, active1, 0L, active2, 0L);
+      case 110:
+         return jjMoveStringLiteralDfa2_0(active0, 0x1c008000000L, active1, 0L, active2, 0L);
+      case 111:
+         if ((active0 & 0x1000000L) != 0L)
+         {
+            jjmatchedKind = 24;
+            jjmatchedPos = 1;
+         }
+         return jjMoveStringLiteralDfa2_0(active0, 0xc000020602604000L, active1, 0L, active2, 0L);
+      case 114:
+         return jjMoveStringLiteralDfa2_0(active0, 0x3800c00000008000L, active1, 0L, active2, 0L);
+      case 115:
+         return jjMoveStringLiteralDfa2_0(active0, 0x2000L, active1, 0L, active2, 0L);
+      case 116:
+         return jjMoveStringLiteralDfa2_0(active0, 0x18000000000000L, active1, 0L, active2, 0L);
+      case 117:
+         return jjMoveStringLiteralDfa2_0(active0, 0x21100000000000L, active1, 0L, active2, 0L);
+      case 119:
+         return jjMoveStringLiteralDfa2_0(active0, 0x40000000000000L, active1, 0L, active2, 0L);
+      case 120:
+         return jjMoveStringLiteralDfa2_0(active0, 0x10000000L, active1, 0L, active2, 0L);
+      case 121:
+         return jjMoveStringLiteralDfa2_0(active0, 0x80000000010000L, active1, 0L, active2, 0L);
+      case 124:
+         if ((active1 & 0x2000000000L) != 0L)
+            return jjStopAtPos(1, 101);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(0, active0, active1, active2);
+}
+private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1, long old2, long active2)
+{
+   if (((active0 &= old0) | (active1 &= old1) | (active2 &= old2)) == 0L)
+      return jjStartNfa_0(0, old0, old1, old2);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(1, active0, active1, active2);
+      return 2;
+   }
+   switch(curChar)
+   {
+      case 46:
+         if ((active1 & 0x2000000000000000L) != 0L)
+            return jjStopAtPos(2, 125);
+         break;
+      case 61:
+         if ((active1 & 0x400000000000000L) != 0L)
+            return jjStopAtPos(2, 122);
+         else if ((active1 & 0x800000000000000L) != 0L)
+            return jjStopAtPos(2, 123);
+         break;
+      case 62:
+         if ((active2 & 0x1L) != 0L)
+         {
+            jjmatchedKind = 128;
+            jjmatchedPos = 2;
+         }
+         return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x1000000000000000L, active2, 0L);
+      case 97:
+         return jjMoveStringLiteralDfa3_0(active0, 0x808000000180000L, active1, 0L, active2, 0L);
+      case 98:
+         return jjMoveStringLiteralDfa3_0(active0, 0x1000000000000L, active1, 0L, active2, 0L);
+      case 99:
+         return jjMoveStringLiteralDfa3_0(active0, 0x200000000000L, active1, 0L, active2, 0L);
+      case 101:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8000L, active1, 0L, active2, 0L);
+      case 102:
+         return jjMoveStringLiteralDfa3_0(active0, 0x800000L, active1, 0L, active2, 0L);
+      case 105:
+         return jjMoveStringLiteralDfa3_0(active0, 0x4140400000000000L, active1, 0x1L, active2, 0L);
+      case 108:
+         return jjMoveStringLiteralDfa3_0(active0, 0x8000100020000000L, active1, 0L, active2, 0L);
+      case 110:
+         return jjMoveStringLiteralDfa3_0(active0, 0x800200c0600000L, active1, 0L, active2, 0L);
+      case 111:
+         return jjMoveStringLiteralDfa3_0(active0, 0x4800100004000L, active1, 0L, active2, 0L);
+      case 112:
+         return jjMoveStringLiteralDfa3_0(active0, 0x20003000000000L, active1, 0L, active2, 0L);
+      case 114:
+         if ((active0 & 0x200000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 33, 43);
+         return jjMoveStringLiteralDfa3_0(active0, 0x610000000000000L, active1, 0L, active2, 0L);
+      case 115:
+         return jjMoveStringLiteralDfa3_0(active0, 0x4004023000L, active1, 0L, active2, 0L);
+      case 116:
+         if ((active0 & 0x8000000000L) != 0L)
+         {
+            jjmatchedKind = 39;
+            jjmatchedPos = 2;
+         }
+         return jjMoveStringLiteralDfa3_0(active0, 0x2050410050000L, active1, 0L, active2, 0L);
+      case 117:
+         return jjMoveStringLiteralDfa3_0(active0, 0x100000000a000000L, active1, 0L, active2, 0L);
+      case 119:
+         if ((active0 & 0x80000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 43, 43);
+         break;
+      case 121:
+         if ((active0 & 0x2000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(2, 61, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(1, active0, active1, active2);
+}
+private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1, long old2, long active2)
+{
+   if (((active0 &= old0) | (active1 &= old1) | (active2 &= old2)) == 0L)
+      return jjStartNfa_0(1, old0, old1, old2);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(2, active0, active1, 0L);
+      return 3;
+   }
+   switch(curChar)
+   {
+      case 61:
+         if ((active1 & 0x1000000000000000L) != 0L)
+            return jjStopAtPos(3, 124);
+         break;
+      case 97:
+         return jjMoveStringLiteralDfa4_0(active0, 0x80000001c0808000L, active1, 0L);
+      case 98:
+         return jjMoveStringLiteralDfa4_0(active0, 0x2000000L, active1, 0L);
+      case 99:
+         return jjMoveStringLiteralDfa4_0(active0, 0x80000000040000L, active1, 0L);
+      case 100:
+         if ((active0 & 0x4000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 62, 43);
+         break;
+      case 101:
+         if ((active0 & 0x10000L) != 0L)
+            return jjStartNfaWithStates_0(3, 16, 43);
+         else if ((active0 & 0x20000L) != 0L)
+            return jjStartNfaWithStates_0(3, 17, 43);
+         else if ((active0 & 0x4000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 26, 43);
+         else if ((active0 & 0x1000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 60, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x20010010002000L, active1, 0L);
+      case 103:
+         if ((active0 & 0x20000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 41, 43);
+         break;
+      case 105:
+         return jjMoveStringLiteralDfa4_0(active0, 0x10040000000000L, active1, 0L);
+      case 107:
+         return jjMoveStringLiteralDfa4_0(active0, 0x200000000000L, active1, 0L);
+      case 108:
+         if ((active0 & 0x100000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 44, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x1001000004000L, active1, 0x1L);
+      case 109:
+         if ((active0 & 0x8000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 27, 43);
+         break;
+      case 110:
+         return jjMoveStringLiteralDfa4_0(active0, 0x800000000000000L, active1, 0L);
+      case 111:
+         if ((active0 & 0x400000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 34, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x600002000000000L, active1, 0L);
+      case 114:
+         if ((active0 & 0x80000L) != 0L)
+            return jjStartNfaWithStates_0(3, 19, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x4000000000000L, active1, 0L);
+      case 115:
+         if ((active0 & 0x100000000000000L) != 0L)
+            return jjStartNfaWithStates_0(3, 56, 43);
+         return jjMoveStringLiteralDfa4_0(active0, 0x20300000L, active1, 0L);
+      case 116:
+         return jjMoveStringLiteralDfa4_0(active0, 0x48804000401000L, active1, 0L);
+      case 117:
+         return jjMoveStringLiteralDfa4_0(active0, 0x2000000000000L, active1, 0L);
+      case 118:
+         return jjMoveStringLiteralDfa4_0(active0, 0x400000000000L, active1, 0L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(2, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1)
+{
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(2, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(3, active0, active1, 0L);
+      return 4;
+   }
+   switch(curChar)
+   {
+      case 97:
+         return jjMoveStringLiteralDfa5_0(active0, 0x604000000000L, active1, 0L);
+      case 99:
+         return jjMoveStringLiteralDfa5_0(active0, 0x50000000000000L, active1, 0L);
+      case 101:
+         if ((active0 & 0x20000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 29, 43);
+         else if ((active1 & 0x1L) != 0L)
+            return jjStartNfaWithStates_0(4, 64, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0x801000004000L, active1, 0L);
+      case 104:
+         if ((active0 & 0x40000L) != 0L)
+            return jjStartNfaWithStates_0(4, 18, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0x80000000000000L, active1, 0L);
+      case 105:
+         return jjMoveStringLiteralDfa5_0(active0, 0x9000000400000L, active1, 0L);
+      case 107:
+         if ((active0 & 0x8000L) != 0L)
+            return jjStartNfaWithStates_0(4, 15, 43);
+         break;
+      case 108:
+         if ((active0 & 0x40000000L) != 0L)
+         {
+            jjmatchedKind = 30;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x82000000L, active1, 0L);
+      case 110:
+         return jjMoveStringLiteralDfa5_0(active0, 0x10000000L, active1, 0L);
+      case 114:
+         if ((active0 & 0x20000000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 53, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0x2012000003000L, active1, 0L);
+      case 115:
+         if ((active0 & 0x100000L) != 0L)
+            return jjStartNfaWithStates_0(4, 20, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0x800000000000000L, active1, 0L);
+      case 116:
+         if ((active0 & 0x200000L) != 0L)
+            return jjStartNfaWithStates_0(4, 21, 43);
+         else if ((active0 & 0x100000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 32, 43);
+         else if ((active0 & 0x4000000000000L) != 0L)
+            return jjStartNfaWithStates_0(4, 50, 43);
+         return jjMoveStringLiteralDfa5_0(active0, 0x8000000000000000L, active1, 0L);
+      case 117:
+         return jjMoveStringLiteralDfa5_0(active0, 0x800000L, active1, 0L);
+      case 118:
+         return jjMoveStringLiteralDfa5_0(active0, 0x40000000000L, active1, 0L);
+      case 119:
+         if ((active0 & 0x200000000000000L) != 0L)
+         {
+            jjmatchedKind = 57;
+            jjmatchedPos = 4;
+         }
+         return jjMoveStringLiteralDfa5_0(active0, 0x400000000000000L, active1, 0L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(3, active0, active1, 0L);
+}
+private int jjMoveStringLiteralDfa5_0(long old0, long active0, long old1, long active1)
+{
+   if (((active0 &= old0) | (active1 &= old1)) == 0L)
+      return jjStartNfa_0(3, old0, old1, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(4, active0, 0L, 0L);
+      return 5;
+   }
+   switch(curChar)
+   {
+      case 97:
+         return jjMoveStringLiteralDfa6_0(active0, 0x5000L);
+      case 99:
+         if ((active0 & 0x1000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 48, 43);
+         else if ((active0 & 0x8000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 51, 43);
+         return jjMoveStringLiteralDfa6_0(active0, 0x800000000000L);
+      case 100:
+         return jjMoveStringLiteralDfa6_0(active0, 0x10000000L);
+      case 101:
+         if ((active0 & 0x2000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 25, 43);
+         else if ((active0 & 0x40000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 42, 43);
+         break;
+      case 102:
+         return jjMoveStringLiteralDfa6_0(active0, 0x10000000000L);
+      case 103:
+         return jjMoveStringLiteralDfa6_0(active0, 0x200000000000L);
+      case 104:
+         if ((active0 & 0x40000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 54, 43);
+         break;
+      case 105:
+         return jjMoveStringLiteralDfa6_0(active0, 0x8800000000000000L);
+      case 108:
+         return jjMoveStringLiteralDfa6_0(active0, 0x80800000L);
+      case 109:
+         return jjMoveStringLiteralDfa6_0(active0, 0x1000000000L);
+      case 110:
+         if ((active0 & 0x2000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 49, 43);
+         return jjMoveStringLiteralDfa6_0(active0, 0x4000400000L);
+      case 114:
+         return jjMoveStringLiteralDfa6_0(active0, 0x80000000000000L);
+      case 115:
+         if ((active0 & 0x400000000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 58, 43);
+         break;
+      case 116:
+         if ((active0 & 0x2000L) != 0L)
+            return jjStartNfaWithStates_0(5, 13, 43);
+         else if ((active0 & 0x2000000000L) != 0L)
+            return jjStartNfaWithStates_0(5, 37, 43);
+         return jjMoveStringLiteralDfa6_0(active0, 0x10400000000000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(4, active0, 0L, 0L);
+}
+private int jjMoveStringLiteralDfa6_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(4, old0, 0L, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(5, active0, 0L, 0L);
+      return 6;
+   }
+   switch(curChar)
+   {
+      case 97:
+         return jjMoveStringLiteralDfa7_0(active0, 0x10000000000L);
+      case 99:
+         return jjMoveStringLiteralDfa7_0(active0, 0x4000001000L);
+      case 101:
+         if ((active0 & 0x200000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 45, 43);
+         else if ((active0 & 0x400000000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 46, 43);
+         return jjMoveStringLiteralDfa7_0(active0, 0x800001000000000L);
+      case 102:
+         return jjMoveStringLiteralDfa7_0(active0, 0x10000000000000L);
+      case 108:
+         return jjMoveStringLiteralDfa7_0(active0, 0x8000000000000000L);
+      case 110:
+         if ((active0 & 0x4000L) != 0L)
+            return jjStartNfaWithStates_0(6, 14, 43);
+         break;
+      case 111:
+         return jjMoveStringLiteralDfa7_0(active0, 0x80000000000000L);
+      case 115:
+         if ((active0 & 0x10000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 28, 43);
+         break;
+      case 116:
+         if ((active0 & 0x800000L) != 0L)
+            return jjStartNfaWithStates_0(6, 23, 43);
+         return jjMoveStringLiteralDfa7_0(active0, 0x800000000000L);
+      case 117:
+         return jjMoveStringLiteralDfa7_0(active0, 0x400000L);
+      case 121:
+         if ((active0 & 0x80000000L) != 0L)
+            return jjStartNfaWithStates_0(6, 31, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(5, active0, 0L, 0L);
+}
+private int jjMoveStringLiteralDfa7_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(5, old0, 0L, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(6, active0, 0L, 0L);
+      return 7;
+   }
+   switch(curChar)
+   {
+      case 99:
+         return jjMoveStringLiteralDfa8_0(active0, 0x10000000000L);
+      case 101:
+         if ((active0 & 0x400000L) != 0L)
+            return jjStartNfaWithStates_0(7, 22, 43);
+         else if ((active0 & 0x8000000000000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 63, 43);
+         return jjMoveStringLiteralDfa8_0(active0, 0x804000000000L);
+      case 110:
+         return jjMoveStringLiteralDfa8_0(active0, 0x880001000000000L);
+      case 112:
+         if ((active0 & 0x10000000000000L) != 0L)
+            return jjStartNfaWithStates_0(7, 52, 43);
+         break;
+      case 116:
+         if ((active0 & 0x1000L) != 0L)
+            return jjStartNfaWithStates_0(7, 12, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(6, active0, 0L, 0L);
+}
+private int jjMoveStringLiteralDfa8_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(6, old0, 0L, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(7, active0, 0L, 0L);
+      return 8;
+   }
+   switch(curChar)
+   {
+      case 100:
+         if ((active0 & 0x800000000000L) != 0L)
+            return jjStartNfaWithStates_0(8, 47, 43);
+         break;
+      case 101:
+         if ((active0 & 0x10000000000L) != 0L)
+            return jjStartNfaWithStates_0(8, 40, 43);
+         break;
+      case 105:
+         return jjMoveStringLiteralDfa9_0(active0, 0x80000000000000L);
+      case 111:
+         return jjMoveStringLiteralDfa9_0(active0, 0x4000000000L);
+      case 116:
+         if ((active0 & 0x800000000000000L) != 0L)
+            return jjStartNfaWithStates_0(8, 59, 43);
+         return jjMoveStringLiteralDfa9_0(active0, 0x1000000000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(7, active0, 0L, 0L);
+}
+private int jjMoveStringLiteralDfa9_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(7, old0, 0L, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(8, active0, 0L, 0L);
+      return 9;
+   }
+   switch(curChar)
+   {
+      case 102:
+         if ((active0 & 0x4000000000L) != 0L)
+            return jjStartNfaWithStates_0(9, 38, 43);
+         break;
+      case 115:
+         if ((active0 & 0x1000000000L) != 0L)
+            return jjStartNfaWithStates_0(9, 36, 43);
+         break;
+      case 122:
+         return jjMoveStringLiteralDfa10_0(active0, 0x80000000000000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(8, active0, 0L, 0L);
+}
+private int jjMoveStringLiteralDfa10_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(8, old0, 0L, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(9, active0, 0L, 0L);
+      return 10;
+   }
+   switch(curChar)
+   {
+      case 101:
+         return jjMoveStringLiteralDfa11_0(active0, 0x80000000000000L);
+      default :
+         break;
+   }
+   return jjStartNfa_0(9, active0, 0L, 0L);
+}
+private int jjMoveStringLiteralDfa11_0(long old0, long active0)
+{
+   if (((active0 &= old0)) == 0L)
+      return jjStartNfa_0(9, old0, 0L, 0L);
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      jjStopStringLiteralDfa_0(10, active0, 0L, 0L);
+      return 11;
+   }
+   switch(curChar)
+   {
+      case 100:
+         if ((active0 & 0x80000000000000L) != 0L)
+            return jjStartNfaWithStates_0(11, 55, 43);
+         break;
+      default :
+         break;
+   }
+   return jjStartNfa_0(10, active0, 0L, 0L);
+}
+private int jjStartNfaWithStates_0(int pos, int kind, int state)
+{
+   jjmatchedKind = kind;
+   jjmatchedPos = pos;
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) { return pos + 1; }
+   return jjMoveNfa_0(state, pos + 1);
+}
+static final long[] jjbitVec0 = {
+   0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec2 = {
+   0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec3 = {
+   0xfff0000000200002L, 0xffffffffffffdfffL, 0xfffff00f7fffffffL, 0x12000000007fffffL
+};
+static final long[] jjbitVec4 = {
+   0x0L, 0x0L, 0x420043c00000000L, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec5 = {
+   0x7fffffffffffffL, 0xffffffffffff0000L, 0xffffffffffffffffL, 0x401f0003ffc3L
+};
+static final long[] jjbitVec6 = {
+   0x0L, 0x400000000000000L, 0xfffffffbffffd740L, 0xfbfffffffff7fffL
+};
+static final long[] jjbitVec7 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffffffc03L, 0x33fffffffff7fffL
+};
+static final long[] jjbitVec8 = {
+   0xfffe00000000ffffL, 0xfffffffe027fffffL, 0xffL, 0x707ffffff0000L
+};
+static final long[] jjbitVec9 = {
+   0x7fffffe00000000L, 0xfffec000000007ffL, 0xffffffffffffffffL, 0x9c00c060002fffffL
+};
+static final long[] jjbitVec10 = {
+   0xfffffffd0000L, 0xe000L, 0x2003fffffffffL, 0x0L
+};
+static final long[] jjbitVec11 = {
+   0x23fffffffffffff0L, 0x3ff010000L, 0x23c5fdfffff99fe0L, 0xf0003b0000000L
+};
+static final long[] jjbitVec12 = {
+   0x36dfdfffff987e0L, 0x1c00005e000000L, 0x23edfdfffffbbfe0L, 0x2000300010000L
+};
+static final long[] jjbitVec13 = {
+   0x23edfdfffff99fe0L, 0x20003b0000000L, 0x3bfc718d63dc7e8L, 0x200000000000000L
+};
+static final long[] jjbitVec14 = {
+   0x3effdfffffddfe0L, 0x300000000L, 0x23effdfffffddfe0L, 0x340000000L
+};
+static final long[] jjbitVec15 = {
+   0x3fffdfffffddfe0L, 0x300000000L, 0x2ffbfffffc7fffe0L, 0x7fL
+};
+static final long[] jjbitVec16 = {
+   0x800dfffffffffffeL, 0x7fL, 0x200decaefef02596L, 0x3000005fL
+};
+static final long[] jjbitVec17 = {
+   0x1L, 0x7fffffffeffL, 0xf00L, 0x0L
+};
+static final long[] jjbitVec18 = {
+   0x6fbffffffffL, 0x3f0000L, 0xffffffff00000000L, 0x1ffffffffff003fL
+};
+static final long[] jjbitVec19 = {
+   0xffffffffffffffffL, 0xffffffff83ffffffL, 0xffffff07ffffffffL, 0x3ffffffffffffffL
+};
+static final long[] jjbitVec20 = {
+   0xffffffffffffff7fL, 0xffffffff3d7f3d7fL, 0x7f3d7fffffff3d7fL, 0xffff7fffff7f7f3dL
+};
+static final long[] jjbitVec21 = {
+   0xffffffff7f3d7fffL, 0x7ffff7fL, 0xffffffff00000000L, 0x1fffffffffffffL
+};
+static final long[] jjbitVec22 = {
+   0xffffffffffffffffL, 0x7f9fffffffffffL, 0xffffffff07fffffeL, 0x1c7ffffffffffL
+};
+static final long[] jjbitVec23 = {
+   0x3ffff0003dfffL, 0x1dfff0003ffffL, 0xfffffffffffffL, 0x18800000L
+};
+static final long[] jjbitVec24 = {
+   0xffffffff00000000L, 0xffffffffffffffL, 0x1ffffffffffL, 0x0L
+};
+static final long[] jjbitVec25 = {
+   0x1fffffffL, 0x1f3fffffff0000L, 0x0L, 0x0L
+};
+static final long[] jjbitVec26 = {
+   0xffffffffffffffffL, 0xfffffffffffL, 0x0L, 0x0L
+};
+static final long[] jjbitVec27 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffff0fffffffL, 0x3ffffffffffffffL
+};
+static final long[] jjbitVec28 = {
+   0xffffffff3f3fffffL, 0x3fffffffaaff3f3fL, 0x5fdfffffffffffffL, 0x1fdc1fff0fcf1fdcL
+};
+static final long[] jjbitVec29 = {
+   0x8000000000000000L, 0x8002000000100001L, 0x3ffff00000000L, 0x0L
+};
+static final long[] jjbitVec30 = {
+   0xe3fbbd503e2ffc84L, 0xffffffff000003e0L, 0xfL, 0x0L
+};
+static final long[] jjbitVec31 = {
+   0x1f3e03fe000000e0L, 0xfffffffffffffffeL, 0xfffffffee07fffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec32 = {
+   0xfffe1fffffffffe0L, 0xffffffffffffffffL, 0xffffff00007fffL, 0xffff000000000000L
+};
+static final long[] jjbitVec33 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffffffL, 0x0L
+};
+static final long[] jjbitVec34 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffL, 0x0L
+};
+static final long[] jjbitVec35 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0x1fffL, 0x0L
+};
+static final long[] jjbitVec36 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffL, 0x0L
+};
+static final long[] jjbitVec37 = {
+   0x6L, 0x0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec38 = {
+   0xffff3fffffffffffL, 0x7ffffffffffL, 0x0L, 0x0L
+};
+static final long[] jjbitVec39 = {
+   0x5f7ffdffa0f8007fL, 0xffffffffffffffdbL, 0x3ffffffffffffL, 0xfffffffffff80000L
+};
+static final long[] jjbitVec40 = {
+   0x3fffffffffffffffL, 0xffffffffffff0000L, 0xfffffffffffcffffL, 0x1fff0000000000ffL
+};
+static final long[] jjbitVec41 = {
+   0x18000000000000L, 0xffdf02000000e000L, 0xffffffffffffffffL, 0x1fffffffffffffffL
+};
+static final long[] jjbitVec42 = {
+   0x87fffffe00000010L, 0xffffffe007fffffeL, 0x7fffffffffffffffL, 0x631cfcfcfcL
+};
+static final long[] jjbitVec43 = {
+   0x0L, 0x0L, 0x420243cffffffffL, 0xff7fffffff7fffffL
+};
+static final long[] jjbitVec44 = {
+   0xffffffffffffffffL, 0x400ffffe0ffffffL, 0xfffffffbffffd740L, 0xfbfffffffff7fffL
+};
+static final long[] jjbitVec45 = {
+   0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffffffc7bL, 0x33fffffffff7fffL
+};
+static final long[] jjbitVec46 = {
+   0xfffe00000000ffffL, 0xfffffffe027fffffL, 0xbbfffffbfffe00ffL, 0x707ffffff0016L
+};
+static final long[] jjbitVec47 = {
+   0x7fffffe003f000fL, 0xffffc3ff01ffffffL, 0xffffffffffffffffL, 0x9ffffdffbfefffffL
+};
+static final long[] jjbitVec48 = {
+   0xffffffffffff8000L, 0xe7ffL, 0x3ffffffffffffL, 0x0L
+};
+static final long[] jjbitVec49 = {
+   0xf3fffffffffffffeL, 0xffcfff1f3fffL, 0xf3c5fdfffff99feeL, 0xfffcfb080399fL
+};
+static final long[] jjbitVec50 = {
+   0xd36dfdfffff987eeL, 0x1fffc05e003987L, 0xf3edfdfffffbbfeeL, 0x2ffcf00013bbfL
+};
+static final long[] jjbitVec51 = {
+   0xf3edfdfffff99feeL, 0x2ffc3b0c0398fL, 0xc3bfc718d63dc7ecL, 0x200ff8000803dc7L
+};
+static final long[] jjbitVec52 = {
+   0xc3effdfffffddfeeL, 0xffc300603ddfL, 0xf3effdfffffddfecL, 0xffc340603ddfL
+};
+static final long[] jjbitVec53 = {
+   0xc3fffdfffffddfecL, 0xffc300803dcfL, 0x2ffbfffffc7fffecL, 0xc0000ff5f847fL
+};
+static final long[] jjbitVec54 = {
+   0x87fffffffffffffeL, 0x3ff7fffL, 0x3bffecaefef02596L, 0x33ff3f5fL
+};
+static final long[] jjbitVec55 = {
+   0xc2a003ff03000001L, 0xfffe07fffffffeffL, 0x1ffffffffeff0fdfL, 0x40L
+};
+static final long[] jjbitVec56 = {
+   0x3c7f6fbffffffffL, 0x3ff03ffL, 0xffffffff00000000L, 0x1ffffffffff003fL
+};
+static final long[] jjbitVec57 = {
+   0xffffffff7f3d7fffL, 0x3fe0007ffff7fL, 0xffffffff00000000L, 0x1fffffffffffffL
+};
+static final long[] jjbitVec58 = {
+   0x1fffff001fdfffL, 0xddfff000fffffL, 0xffffffffffffffffL, 0x3ff388fffffL
+};
+static final long[] jjbitVec59 = {
+   0xffffffff03ff3800L, 0xffffffffffffffL, 0x3ffffffffffL, 0x0L
+};
+static final long[] jjbitVec60 = {
+   0xfff0fff1fffffffL, 0x1f3fffffffffc0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec61 = {
+   0x80007c000000f000L, 0x8002fc0f00100001L, 0x3ffff00000000L, 0x7e21fff0000L
+};
+static final long[] jjbitVec62 = {
+   0x1f3efffe000000e0L, 0xfffffffffffffffeL, 0xfffffffee67fffffL, 0xffffffffffffffffL
+};
+static final long[] jjbitVec63 = {
+   0x10000000000006L, 0x0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec64 = {
+   0x3L, 0x0L, 0x0L, 0x0L
+};
+static final long[] jjbitVec65 = {
+   0x0L, 0x800000000000000L, 0x0L, 0x0L
+};
+static final long[] jjbitVec66 = {
+   0x5f7ffdffe0f8007fL, 0xffffffffffffffdbL, 0x3ffffffffffffL, 0xfffffffffff80000L
+};
+static final long[] jjbitVec67 = {
+   0x18000f0000ffffL, 0xffdf02000000e000L, 0xffffffffffffffffL, 0x9fffffffffffffffL
+};
+static final long[] jjbitVec68 = {
+   0x87fffffe03ff0010L, 0xffffffe007fffffeL, 0x7fffffffffffffffL, 0xe0000631cfcfcfcL
+};
+private int jjMoveNfa_0(int startState, int curPos)
+{
+   int startsAt = 0;
+   jjnewStateCnt = 130;
+   int i = 1;
+   jjstateSet[0] = startState;
+   int kind = 0x7fffffff;
+   for (;;)
+   {
+      if (++jjround == 0x7fffffff)
+         ReInitRounds();
+      if (curChar < 64)
+      {
+         long l = 1L << curChar;
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 45:
+                  if (curChar == 42)
+                     jjstateSet[jjnewStateCnt++] = 50;
+                  else if (curChar == 47)
+                  {
+                     if (kind > 6)
+                        kind = 6;
+                     jjCheckNAddStates(0, 2);
+                  }
+                  break;
+               case 0:
+                  if ((0x3ff000000000000L & l) != 0L)
+                  {
+                     if (kind > 66)
+                        kind = 66;
+                     jjCheckNAddStates(3, 17);
+                  }
+                  else if (curChar == 47)
+                     jjAddStates(18, 19);
+                  else if (curChar == 36)
+                  {
+                     if (kind > 78)
+                        kind = 78;
+                     jjCheckNAdd(43);
+                  }
+                  else if (curChar == 34)
+                     jjCheckNAddStates(20, 23);
+                  else if (curChar == 39)
+                     jjAddStates(24, 26);
+                  else if (curChar == 46)
+                     jjCheckNAdd(1);
+                  if (curChar == 48)
+                     jjAddStates(27, 34);
+                  break;
+               case 1:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(35, 38);
+                  break;
+               case 2:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(2, 3);
+                  break;
+               case 3:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(39, 41);
+                  break;
+               case 5:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(6);
+                  break;
+               case 6:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(42, 44);
+                  break;
+               case 7:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(7, 8);
+                  break;
+               case 8:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddTwoStates(6, 9);
+                  break;
+               case 10:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(45, 48);
+                  break;
+               case 11:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(49, 53);
+                  break;
+               case 12:
+                  if (curChar == 39)
+                     jjAddStates(24, 26);
+                  break;
+               case 13:
+                  if ((0xffffff7fffffdbffL & l) != 0L)
+                     jjCheckNAdd(14);
+                  break;
+               case 14:
+                  if (curChar == 39 && kind > 76)
+                     kind = 76;
+                  break;
+               case 16:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAdd(14);
+                  break;
+               case 17:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(18, 14);
+                  break;
+               case 18:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAdd(14);
+                  break;
+               case 19:
+                  if ((0xf000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 20;
+                  break;
+               case 20:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAdd(18);
+                  break;
+               case 22:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 23;
+                  break;
+               case 23:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 24;
+                  break;
+               case 24:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 25;
+                  break;
+               case 25:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAdd(14);
+                  break;
+               case 27:
+                  if (curChar == 34)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 28:
+                  if ((0xfffffffbffffdbffL & l) != 0L)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 30:
+                  if ((0x8400000000L & l) != 0L)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 32:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 33;
+                  break;
+               case 33:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 34;
+                  break;
+               case 34:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 35;
+                  break;
+               case 35:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 37:
+                  if (curChar == 34 && kind > 77)
+                     kind = 77;
+                  break;
+               case 38:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAddStates(54, 58);
+                  break;
+               case 39:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 40:
+                  if ((0xf000000000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 41;
+                  break;
+               case 41:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAdd(39);
+                  break;
+               case 42:
+                  if (curChar != 36)
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(43);
+                  break;
+               case 43:
+                  if ((0x3ff00100fffc1ffL & l) == 0L)
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(43);
+                  break;
+               case 44:
+                  if (curChar == 47)
+                     jjAddStates(18, 19);
+                  break;
+               case 46:
+                  if ((0xffffffffffffdbffL & l) == 0L)
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjCheckNAddStates(0, 2);
+                  break;
+               case 47:
+                  if ((0x2400L & l) != 0L && kind > 6)
+                     kind = 6;
+                  break;
+               case 48:
+                  if (curChar == 10 && kind > 6)
+                     kind = 6;
+                  break;
+               case 49:
+                  if (curChar == 13)
+                     jjstateSet[jjnewStateCnt++] = 48;
+                  break;
+               case 50:
+                  if (curChar == 42)
+                     jjstateSet[jjnewStateCnt++] = 51;
+                  break;
+               case 51:
+                  if ((0xffff7fffffffffffL & l) != 0L && kind > 7)
+                     kind = 7;
+                  break;
+               case 52:
+                  if (curChar == 42)
+                     jjstateSet[jjnewStateCnt++] = 50;
+                  break;
+               case 53:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 66)
+                     kind = 66;
+                  jjCheckNAddStates(3, 17);
+                  break;
+               case 54:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(54, 55);
+                  break;
+               case 55:
+               case 98:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAdd(56);
+                  break;
+               case 57:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(57, 58);
+                  break;
+               case 58:
+               case 109:
+                  if ((0x3ff000000000000L & l) != 0L && kind > 66)
+                     kind = 66;
+                  break;
+               case 59:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(59, 60);
+                  break;
+               case 60:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(59, 61);
+                  break;
+               case 61:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(62, 65);
+                  break;
+               case 63:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(64);
+                  break;
+               case 64:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(66, 68);
+                  break;
+               case 65:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(65, 66);
+                  break;
+               case 66:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(64, 9);
+                  break;
+               case 67:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(69, 72);
+                  break;
+               case 68:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(73, 77);
+                  break;
+               case 69:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(69, 70);
+                  break;
+               case 70:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(71, 72);
+                  break;
+               case 71:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(78, 80);
+                  break;
+               case 73:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(74);
+                  break;
+               case 74:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(81, 83);
+                  break;
+               case 75:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(75, 76);
+                  break;
+               case 76:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddTwoStates(74, 9);
+                  break;
+               case 77:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(84, 87);
+                  break;
+               case 78:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(88, 91);
+                  break;
+               case 79:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(79, 80);
+                  break;
+               case 80:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(81, 82);
+                  break;
+               case 81:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(92, 94);
+                  break;
+               case 82:
+                  if (curChar != 46)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(95, 97);
+                  break;
+               case 83:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(98, 101);
+                  break;
+               case 84:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(84, 85);
+                  break;
+               case 85:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(95, 97);
+                  break;
+               case 87:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(88);
+                  break;
+               case 88:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(102, 104);
+                  break;
+               case 89:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(89, 90);
+                  break;
+               case 90:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddTwoStates(88, 9);
+                  break;
+               case 91:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(105, 108);
+                  break;
+               case 92:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddStates(109, 113);
+                  break;
+               case 93:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(114, 117);
+                  break;
+               case 94:
+                  if (curChar == 48)
+                     jjAddStates(27, 34);
+                  break;
+               case 96:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(118, 120);
+                  break;
+               case 97:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(97, 98);
+                  break;
+               case 99:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAddStates(121, 123);
+                  break;
+               case 100:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(100, 101);
+                  break;
+               case 101:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAdd(56);
+                  break;
+               case 103:
+                  if ((0x3000000000000L & l) != 0L)
+                     jjCheckNAddStates(124, 126);
+                  break;
+               case 104:
+                  if ((0x3000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(104, 105);
+                  break;
+               case 105:
+                  if ((0x3000000000000L & l) != 0L)
+                     jjCheckNAdd(56);
+                  break;
+               case 107:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 66)
+                     kind = 66;
+                  jjCheckNAddTwoStates(108, 109);
+                  break;
+               case 108:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(108, 109);
+                  break;
+               case 110:
+                  if ((0xff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 66)
+                     kind = 66;
+                  jjCheckNAddTwoStates(111, 112);
+                  break;
+               case 111:
+                  if ((0xff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(111, 112);
+                  break;
+               case 112:
+                  if ((0xff000000000000L & l) != 0L && kind > 66)
+                     kind = 66;
+                  break;
+               case 114:
+                  if ((0x3000000000000L & l) == 0L)
+                     break;
+                  if (kind > 66)
+                     kind = 66;
+                  jjCheckNAddTwoStates(115, 116);
+                  break;
+               case 115:
+                  if ((0x3000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(115, 116);
+                  break;
+               case 116:
+                  if ((0x3000000000000L & l) != 0L && kind > 66)
+                     kind = 66;
+                  break;
+               case 118:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjAddStates(127, 128);
+                  break;
+               case 119:
+                  if (curChar == 46)
+                     jjCheckNAdd(120);
+                  break;
+               case 120:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddTwoStates(120, 121);
+                  break;
+               case 122:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(123);
+                  break;
+               case 123:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddTwoStates(123, 9);
+                  break;
+               case 125:
+                  if ((0x3ff000000000000L & l) != 0L)
+                     jjCheckNAddStates(129, 131);
+                  break;
+               case 126:
+                  if (curChar == 46)
+                     jjCheckNAdd(127);
+                  break;
+               case 128:
+                  if ((0x280000000000L & l) != 0L)
+                     jjCheckNAdd(129);
+                  break;
+               case 129:
+                  if ((0x3ff000000000000L & l) == 0L)
+                     break;
+                  if (kind > 71)
+                     kind = 71;
+                  jjCheckNAddTwoStates(129, 9);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else if (curChar < 128)
+      {
+         long l = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if ((0x7fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(43);
+                  break;
+               case 2:
+                  if (curChar == 95)
+                     jjAddStates(132, 133);
+                  break;
+               case 4:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(134, 135);
+                  break;
+               case 7:
+                  if (curChar == 95)
+                     jjAddStates(136, 137);
+                  break;
+               case 9:
+                  if ((0x5000000050L & l) != 0L && kind > 71)
+                     kind = 71;
+                  break;
+               case 13:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAdd(14);
+                  break;
+               case 15:
+                  if (curChar == 92)
+                     jjAddStates(138, 140);
+                  break;
+               case 16:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAdd(14);
+                  break;
+               case 21:
+                  if (curChar == 117)
+                     jjstateSet[jjnewStateCnt++] = 22;
+                  break;
+               case 22:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 23;
+                  break;
+               case 23:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 24;
+                  break;
+               case 24:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 25;
+                  break;
+               case 25:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAdd(14);
+                  break;
+               case 26:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 21;
+                  break;
+               case 28:
+                  if ((0xffffffffefffffffL & l) != 0L)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 29:
+                  if (curChar == 92)
+                     jjAddStates(141, 143);
+                  break;
+               case 30:
+                  if ((0x14404410000000L & l) != 0L)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 31:
+                  if (curChar == 117)
+                     jjstateSet[jjnewStateCnt++] = 32;
+                  break;
+               case 32:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 33;
+                  break;
+               case 33:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 34;
+                  break;
+               case 34:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 35;
+                  break;
+               case 35:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAddStates(20, 23);
+                  break;
+               case 36:
+                  if (curChar == 92)
+                     jjstateSet[jjnewStateCnt++] = 31;
+                  break;
+               case 43:
+                  if ((0x87fffffe87fffffeL & l) == 0L)
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(43);
+                  break;
+               case 46:
+                  if (kind > 6)
+                     kind = 6;
+                  jjAddStates(0, 2);
+                  break;
+               case 51:
+                  if (kind > 7)
+                     kind = 7;
+                  break;
+               case 54:
+                  if (curChar == 95)
+                     jjAddStates(144, 145);
+                  break;
+               case 56:
+                  if ((0x100000001000L & l) != 0L && kind > 65)
+                     kind = 65;
+                  break;
+               case 57:
+                  if (curChar == 95)
+                     jjAddStates(146, 147);
+                  break;
+               case 59:
+                  if (curChar == 95)
+                     jjAddStates(148, 149);
+                  break;
+               case 62:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(150, 151);
+                  break;
+               case 65:
+                  if (curChar == 95)
+                     jjAddStates(152, 153);
+                  break;
+               case 69:
+                  if (curChar == 95)
+                     jjAddStates(154, 155);
+                  break;
+               case 72:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(156, 157);
+                  break;
+               case 75:
+                  if (curChar == 95)
+                     jjAddStates(158, 159);
+                  break;
+               case 79:
+                  if (curChar == 95)
+                     jjAddStates(160, 161);
+                  break;
+               case 84:
+                  if (curChar == 95)
+                     jjAddStates(162, 163);
+                  break;
+               case 86:
+                  if ((0x2000000020L & l) != 0L)
+                     jjAddStates(164, 165);
+                  break;
+               case 89:
+                  if (curChar == 95)
+                     jjAddStates(166, 167);
+                  break;
+               case 95:
+                  if ((0x100000001000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 96;
+                  break;
+               case 96:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAddStates(118, 120);
+                  break;
+               case 97:
+                  if ((0x7e8000007eL & l) != 0L)
+                     jjCheckNAddTwoStates(97, 98);
+                  break;
+               case 98:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAdd(56);
+                  break;
+               case 100:
+                  if (curChar == 95)
+                     jjAddStates(168, 169);
+                  break;
+               case 102:
+                  if ((0x400000004L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 103;
+                  break;
+               case 104:
+                  if (curChar == 95)
+                     jjAddStates(170, 171);
+                  break;
+               case 106:
+                  if ((0x100000001000000L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 107;
+                  break;
+               case 107:
+                  if ((0x7e0000007eL & l) == 0L)
+                     break;
+                  if (kind > 66)
+                     kind = 66;
+                  jjCheckNAddTwoStates(108, 109);
+                  break;
+               case 108:
+                  if ((0x7e8000007eL & l) != 0L)
+                     jjCheckNAddTwoStates(108, 109);
+                  break;
+               case 109:
+                  if ((0x7e0000007eL & l) != 0L && kind > 66)
+                     kind = 66;
+                  break;
+               case 111:
+                  if (curChar == 95)
+                     jjAddStates(172, 173);
+                  break;
+               case 113:
+                  if ((0x400000004L & l) != 0L)
+                     jjstateSet[jjnewStateCnt++] = 114;
+                  break;
+               case 115:
+                  if (curChar == 95)
+                     jjAddStates(174, 175);
+                  break;
+               case 117:
+                  if ((0x100000001000000L & l) != 0L)
+                     jjCheckNAddTwoStates(118, 119);
+                  break;
+               case 118:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAddTwoStates(118, 119);
+                  break;
+               case 120:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjAddStates(176, 177);
+                  break;
+               case 121:
+                  if ((0x1000000010000L & l) != 0L)
+                     jjAddStates(178, 179);
+                  break;
+               case 124:
+                  if ((0x100000001000000L & l) != 0L)
+                     jjCheckNAdd(125);
+                  break;
+               case 125:
+                  if ((0x7e0000007eL & l) != 0L)
+                     jjCheckNAddStates(129, 131);
+                  break;
+               case 127:
+                  if ((0x1000000010000L & l) != 0L)
+                     jjAddStates(180, 181);
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      else
+      {
+         int hiByte = (int)(curChar >> 8);
+         int i1 = hiByte >> 6;
+         long l1 = 1L << (hiByte & 077);
+         int i2 = (curChar & 0xff) >> 6;
+         long l2 = 1L << (curChar & 077);
+         do
+         {
+            switch(jjstateSet[--i])
+            {
+               case 0:
+                  if (!jjCanMove_1(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(43);
+                  break;
+               case 13:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjstateSet[jjnewStateCnt++] = 14;
+                  break;
+               case 28:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     jjAddStates(20, 23);
+                  break;
+               case 43:
+                  if (!jjCanMove_2(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 78)
+                     kind = 78;
+                  jjCheckNAdd(43);
+                  break;
+               case 46:
+                  if (!jjCanMove_0(hiByte, i1, i2, l1, l2))
+                     break;
+                  if (kind > 6)
+                     kind = 6;
+                  jjAddStates(0, 2);
+                  break;
+               case 51:
+                  if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 7)
+                     kind = 7;
+                  break;
+               default : break;
+            }
+         } while(i != startsAt);
+      }
+      if (kind != 0x7fffffff)
+      {
+         jjmatchedKind = kind;
+         jjmatchedPos = curPos;
+         kind = 0x7fffffff;
+      }
+      ++curPos;
+      if ((i = jjnewStateCnt) == (startsAt = 130 - (jjnewStateCnt = startsAt)))
+         return curPos;
+      try { curChar = input_stream.readChar(); }
+      catch(java.io.IOException e) { return curPos; }
+   }
+}
+private int jjMoveStringLiteralDfa0_2()
+{
+   switch(curChar)
+   {
+      case 42:
+         return jjMoveStringLiteralDfa1_2(0x400L);
+      default :
+         return 1;
+   }
+}
+private int jjMoveStringLiteralDfa1_2(long active0)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 47:
+         if ((active0 & 0x400L) != 0L)
+            return jjStopAtPos(1, 10);
+         break;
+      default :
+         return 2;
+   }
+   return 2;
+}
+private int jjMoveStringLiteralDfa0_1()
+{
+   switch(curChar)
+   {
+      case 42:
+         return jjMoveStringLiteralDfa1_1(0x200L);
+      default :
+         return 1;
+   }
+}
+private int jjMoveStringLiteralDfa1_1(long active0)
+{
+   try { curChar = input_stream.readChar(); }
+   catch(java.io.IOException e) {
+      return 1;
+   }
+   switch(curChar)
+   {
+      case 47:
+         if ((active0 & 0x200L) != 0L)
+            return jjStopAtPos(1, 9);
+         break;
+      default :
+         return 2;
+   }
+   return 2;
+}
+static final int[] jjnextStates = {
+   46, 47, 49, 54, 55, 56, 57, 58, 59, 62, 9, 69, 72, 79, 82, 93, 
+   78, 68, 45, 52, 28, 29, 36, 37, 13, 15, 26, 95, 99, 102, 106, 110, 
+   113, 117, 124, 2, 4, 9, 11, 1, 4, 9, 7, 9, 10, 6, 7, 9, 
+   10, 1, 2, 4, 9, 11, 28, 29, 39, 36, 37, 61, 62, 9, 59, 62, 
+   9, 68, 65, 9, 67, 64, 65, 9, 67, 61, 59, 62, 9, 68, 69, 72, 
+   78, 75, 9, 77, 74, 75, 9, 77, 71, 69, 72, 78, 79, 82, 93, 83, 
+   86, 9, 84, 86, 9, 92, 89, 9, 91, 88, 89, 9, 91, 83, 84, 86, 
+   9, 92, 81, 79, 82, 93, 97, 98, 56, 100, 101, 56, 104, 105, 56, 118, 
+   119, 125, 126, 127, 2, 3, 5, 6, 7, 8, 16, 17, 19, 30, 38, 40, 
+   54, 55, 57, 58, 59, 60, 63, 64, 65, 66, 69, 70, 73, 74, 75, 76, 
+   79, 80, 84, 85, 87, 88, 89, 90, 100, 101, 104, 105, 111, 112, 115, 116, 
+   120, 121, 122, 123, 128, 129, 
+};
+private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec2[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec0[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+private static final boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec4[i2] & l2) != 0L);
+      case 2:
+         return ((jjbitVec5[i2] & l2) != 0L);
+      case 3:
+         return ((jjbitVec6[i2] & l2) != 0L);
+      case 4:
+         return ((jjbitVec7[i2] & l2) != 0L);
+      case 5:
+         return ((jjbitVec8[i2] & l2) != 0L);
+      case 6:
+         return ((jjbitVec9[i2] & l2) != 0L);
+      case 7:
+         return ((jjbitVec10[i2] & l2) != 0L);
+      case 9:
+         return ((jjbitVec11[i2] & l2) != 0L);
+      case 10:
+         return ((jjbitVec12[i2] & l2) != 0L);
+      case 11:
+         return ((jjbitVec13[i2] & l2) != 0L);
+      case 12:
+         return ((jjbitVec14[i2] & l2) != 0L);
+      case 13:
+         return ((jjbitVec15[i2] & l2) != 0L);
+      case 14:
+         return ((jjbitVec16[i2] & l2) != 0L);
+      case 15:
+         return ((jjbitVec17[i2] & l2) != 0L);
+      case 16:
+         return ((jjbitVec18[i2] & l2) != 0L);
+      case 17:
+         return ((jjbitVec19[i2] & l2) != 0L);
+      case 18:
+         return ((jjbitVec20[i2] & l2) != 0L);
+      case 19:
+         return ((jjbitVec21[i2] & l2) != 0L);
+      case 20:
+         return ((jjbitVec0[i2] & l2) != 0L);
+      case 22:
+         return ((jjbitVec22[i2] & l2) != 0L);
+      case 23:
+         return ((jjbitVec23[i2] & l2) != 0L);
+      case 24:
+         return ((jjbitVec24[i2] & l2) != 0L);
+      case 25:
+         return ((jjbitVec25[i2] & l2) != 0L);
+      case 29:
+         return ((jjbitVec26[i2] & l2) != 0L);
+      case 30:
+         return ((jjbitVec27[i2] & l2) != 0L);
+      case 31:
+         return ((jjbitVec28[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec29[i2] & l2) != 0L);
+      case 33:
+         return ((jjbitVec30[i2] & l2) != 0L);
+      case 48:
+         return ((jjbitVec31[i2] & l2) != 0L);
+      case 49:
+         return ((jjbitVec32[i2] & l2) != 0L);
+      case 77:
+         return ((jjbitVec33[i2] & l2) != 0L);
+      case 159:
+         return ((jjbitVec34[i2] & l2) != 0L);
+      case 164:
+         return ((jjbitVec35[i2] & l2) != 0L);
+      case 215:
+         return ((jjbitVec36[i2] & l2) != 0L);
+      case 216:
+         return ((jjbitVec37[i2] & l2) != 0L);
+      case 250:
+         return ((jjbitVec38[i2] & l2) != 0L);
+      case 251:
+         return ((jjbitVec39[i2] & l2) != 0L);
+      case 253:
+         return ((jjbitVec40[i2] & l2) != 0L);
+      case 254:
+         return ((jjbitVec41[i2] & l2) != 0L);
+      case 255:
+         return ((jjbitVec42[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec3[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+private static final boolean jjCanMove_2(int hiByte, int i1, int i2, long l1, long l2)
+{
+   switch(hiByte)
+   {
+      case 0:
+         return ((jjbitVec43[i2] & l2) != 0L);
+      case 2:
+         return ((jjbitVec5[i2] & l2) != 0L);
+      case 3:
+         return ((jjbitVec44[i2] & l2) != 0L);
+      case 4:
+         return ((jjbitVec45[i2] & l2) != 0L);
+      case 5:
+         return ((jjbitVec46[i2] & l2) != 0L);
+      case 6:
+         return ((jjbitVec47[i2] & l2) != 0L);
+      case 7:
+         return ((jjbitVec48[i2] & l2) != 0L);
+      case 9:
+         return ((jjbitVec49[i2] & l2) != 0L);
+      case 10:
+         return ((jjbitVec50[i2] & l2) != 0L);
+      case 11:
+         return ((jjbitVec51[i2] & l2) != 0L);
+      case 12:
+         return ((jjbitVec52[i2] & l2) != 0L);
+      case 13:
+         return ((jjbitVec53[i2] & l2) != 0L);
+      case 14:
+         return ((jjbitVec54[i2] & l2) != 0L);
+      case 15:
+         return ((jjbitVec55[i2] & l2) != 0L);
+      case 16:
+         return ((jjbitVec56[i2] & l2) != 0L);
+      case 17:
+         return ((jjbitVec19[i2] & l2) != 0L);
+      case 18:
+         return ((jjbitVec20[i2] & l2) != 0L);
+      case 19:
+         return ((jjbitVec57[i2] & l2) != 0L);
+      case 20:
+         return ((jjbitVec0[i2] & l2) != 0L);
+      case 22:
+         return ((jjbitVec22[i2] & l2) != 0L);
+      case 23:
+         return ((jjbitVec58[i2] & l2) != 0L);
+      case 24:
+         return ((jjbitVec59[i2] & l2) != 0L);
+      case 25:
+         return ((jjbitVec60[i2] & l2) != 0L);
+      case 29:
+         return ((jjbitVec26[i2] & l2) != 0L);
+      case 30:
+         return ((jjbitVec27[i2] & l2) != 0L);
+      case 31:
+         return ((jjbitVec28[i2] & l2) != 0L);
+      case 32:
+         return ((jjbitVec61[i2] & l2) != 0L);
+      case 33:
+         return ((jjbitVec30[i2] & l2) != 0L);
+      case 48:
+         return ((jjbitVec62[i2] & l2) != 0L);
+      case 49:
+         return ((jjbitVec32[i2] & l2) != 0L);
+      case 77:
+         return ((jjbitVec33[i2] & l2) != 0L);
+      case 159:
+         return ((jjbitVec34[i2] & l2) != 0L);
+      case 164:
+         return ((jjbitVec35[i2] & l2) != 0L);
+      case 215:
+         return ((jjbitVec36[i2] & l2) != 0L);
+      case 216:
+         return ((jjbitVec63[i2] & l2) != 0L);
+      case 220:
+         return ((jjbitVec64[i2] & l2) != 0L);
+      case 221:
+         return ((jjbitVec65[i2] & l2) != 0L);
+      case 250:
+         return ((jjbitVec38[i2] & l2) != 0L);
+      case 251:
+         return ((jjbitVec66[i2] & l2) != 0L);
+      case 253:
+         return ((jjbitVec40[i2] & l2) != 0L);
+      case 254:
+         return ((jjbitVec67[i2] & l2) != 0L);
+      case 255:
+         return ((jjbitVec68[i2] & l2) != 0L);
+      default :
+         if ((jjbitVec3[i1] & l1) != 0L)
+            return true;
+         return false;
+   }
+}
+
+/** Token literal values. */
+public static final String[] jjstrLiteralImages = {
+"", null, null, null, null, null, null, null, null, null, null, null, 
+"\141\142\163\164\162\141\143\164", "\141\163\163\145\162\164", "\142\157\157\154\145\141\156", 
+"\142\162\145\141\153", "\142\171\164\145", "\143\141\163\145", "\143\141\164\143\150", 
+"\143\150\141\162", "\143\154\141\163\163", "\143\157\156\163\164", 
+"\143\157\156\164\151\156\165\145", "\144\145\146\141\165\154\164", "\144\157", "\144\157\165\142\154\145", 
+"\145\154\163\145", "\145\156\165\155", "\145\170\164\145\156\144\163", "\146\141\154\163\145", 
+"\146\151\156\141\154", "\146\151\156\141\154\154\171", "\146\154\157\141\164", "\146\157\162", 
+"\147\157\164\157", "\151\146", "\151\155\160\154\145\155\145\156\164\163", 
+"\151\155\160\157\162\164", "\151\156\163\164\141\156\143\145\157\146", "\151\156\164", 
+"\151\156\164\145\162\146\141\143\145", "\154\157\156\147", "\156\141\164\151\166\145", "\156\145\167", 
+"\156\165\154\154", "\160\141\143\153\141\147\145", "\160\162\151\166\141\164\145", 
+"\160\162\157\164\145\143\164\145\144", "\160\165\142\154\151\143", "\162\145\164\165\162\156", 
+"\163\150\157\162\164", "\163\164\141\164\151\143", "\163\164\162\151\143\164\146\160", 
+"\163\165\160\145\162", "\163\167\151\164\143\150", 
+"\163\171\156\143\150\162\157\156\151\172\145\144", "\164\150\151\163", "\164\150\162\157\167", "\164\150\162\157\167\163", 
+"\164\162\141\156\163\151\145\156\164", "\164\162\165\145", "\164\162\171", "\166\157\151\144", 
+"\166\157\154\141\164\151\154\145", "\167\150\151\154\145", null, null, null, null, null, null, null, null, null, 
+null, null, null, null, null, null, null, "\50", "\51", "\173", "\175", "\133", 
+"\135", "\73", "\54", "\56", "\100", "\75", "\74", "\41", "\176", "\77", "\72", 
+"\75\75", "\74\75", "\76\75", "\41\75", "\174\174", "\46\46", "\53\53", "\55\55", "\53", 
+"\55", "\52", "\57", "\46", "\174", "\136", "\45", "\74\74", "\53\75", "\55\75", 
+"\52\75", "\57\75", "\46\75", "\174\75", "\136\75", "\45\75", "\74\74\75", "\76\76\75", 
+"\76\76\76\75", "\56\56\56", "\55\76", "\72\72", "\76\76\76", "\76\76", "\76", "\32", 
+"\74\76", };
+
+/** Lexer state names. */
+public static final String[] lexStateNames = {
+   "DEFAULT",
+   "IN_JAVA_DOC_COMMENT",
+   "IN_MULTI_LINE_COMMENT",
+};
+
+/** Lex State array. */
+public static final int[] jjnewLexState = {
+   -1, -1, -1, -1, -1, -1, -1, 1, 2, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
+   -1, -1, -1, -1, -1, -1, -1, -1, 
+};
+static final long[] jjtoToken = {
+   0xfffffffffffff001L, 0xfffffffffffe7087L, 0x1fL, 
+};
+static final long[] jjtoSkip = {
+   0x67eL, 0x0L, 0x0L, 
+};
+static final long[] jjtoSpecial = {
+   0x640L, 0x0L, 0x0L, 
+};
+static final long[] jjtoMore = {
+   0x980L, 0x0L, 0x0L, 
+};
+protected JavaCharStream input_stream;
+private final int[] jjrounds = new int[130];
+private final int[] jjstateSet = new int[260];
+private final StringBuilder jjimage = new StringBuilder();
+private StringBuilder image = jjimage;
+private int jjimageLen;
+private int lengthOfMatch;
+protected char curChar;
+/** Constructor. */
+public ASTParserTokenManager(JavaCharStream stream){
+   if (JavaCharStream.staticFlag)
+      throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+   input_stream = stream;
+}
+
+/** Constructor. */
+public ASTParserTokenManager(JavaCharStream stream, int lexState){
+   this(stream);
+   SwitchTo(lexState);
+}
+
+/** Reinitialise parser. */
+public void ReInit(JavaCharStream stream)
+{
+   jjmatchedPos = jjnewStateCnt = 0;
+   curLexState = defaultLexState;
+   input_stream = stream;
+   ReInitRounds();
+}
+private void ReInitRounds()
+{
+   int i;
+   jjround = 0x80000001;
+   for (i = 130; i-- > 0;)
+      jjrounds[i] = 0x80000000;
+}
+
+/** Reinitialise parser. */
+public void ReInit(JavaCharStream stream, int lexState)
+{
+   ReInit(stream);
+   SwitchTo(lexState);
+}
+
+/** Switch to specified lex state. */
+public void SwitchTo(int lexState)
+{
+   if (lexState >= 3 || lexState < 0)
+      throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
+   else
+      curLexState = lexState;
+}
+
+protected Token jjFillToken()
+{
+   final Token t;
+   final String curTokenImage;
+   final int beginLine;
+   final int endLine;
+   final int beginColumn;
+   final int endColumn;
+   String im = jjstrLiteralImages[jjmatchedKind];
+   curTokenImage = (im == null) ? input_stream.GetImage() : im;
+   beginLine = input_stream.getBeginLine();
+   beginColumn = input_stream.getBeginColumn();
+   endLine = input_stream.getEndLine();
+   endColumn = input_stream.getEndColumn();
+   t = ASTParser.GTToken.newToken(jjmatchedKind, curTokenImage);
+
+   t.beginLine = beginLine;
+   t.endLine = endLine;
+   t.beginColumn = beginColumn;
+   t.endColumn = endColumn;
+
+   return t;
+}
+
+int curLexState = 0;
+int defaultLexState = 0;
+int jjnewStateCnt;
+int jjround;
+int jjmatchedPos;
+int jjmatchedKind;
+
+/** Get the next Token. */
+public Token getNextToken() 
+{
+  Token specialToken = null;
+  Token matchedToken;
+  int curPos = 0;
+
+  EOFLoop :
+  for (;;)
+  {
+   try
+   {
+      curChar = input_stream.BeginToken();
+   }
+   catch(java.io.IOException e)
+   {
+      jjmatchedKind = 0;
+      matchedToken = jjFillToken();
+      matchedToken.specialToken = specialToken;
+      return matchedToken;
+   }
+   image = jjimage;
+   image.setLength(0);
+   jjimageLen = 0;
+
+   for (;;)
+   {
+     switch(curLexState)
+     {
+       case 0:
+         try { input_stream.backup(0);
+            while (curChar <= 32 && (0x100003600L & (1L << curChar)) != 0L)
+               curChar = input_stream.BeginToken();
+         }
+         catch (java.io.IOException e1) { continue EOFLoop; }
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_0();
+         break;
+       case 1:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_1();
+         if (jjmatchedPos == 0 && jjmatchedKind > 11)
+         {
+            jjmatchedKind = 11;
+         }
+         break;
+       case 2:
+         jjmatchedKind = 0x7fffffff;
+         jjmatchedPos = 0;
+         curPos = jjMoveStringLiteralDfa0_2();
+         if (jjmatchedPos == 0 && jjmatchedKind > 11)
+         {
+            jjmatchedKind = 11;
+         }
+         break;
+     }
+     if (jjmatchedKind != 0x7fffffff)
+     {
+        if (jjmatchedPos + 1 < curPos)
+           input_stream.backup(curPos - jjmatchedPos - 1);
+        if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           matchedToken = jjFillToken();
+           matchedToken.specialToken = specialToken;
+           TokenLexicalActions(matchedToken);
+       if (jjnewLexState[jjmatchedKind] != -1)
+         curLexState = jjnewLexState[jjmatchedKind];
+           return matchedToken;
+        }
+        else if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+        {
+           if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L)
+           {
+              matchedToken = jjFillToken();
+              if (specialToken == null)
+                 specialToken = matchedToken;
+              else
+              {
+                 matchedToken.specialToken = specialToken;
+                 specialToken = (specialToken.next = matchedToken);
+              }
+              SkipLexicalActions(matchedToken);
+           }
+           else
+              SkipLexicalActions(null);
+         if (jjnewLexState[jjmatchedKind] != -1)
+           curLexState = jjnewLexState[jjmatchedKind];
+           continue EOFLoop;
+        }
+        MoreLexicalActions();
+      if (jjnewLexState[jjmatchedKind] != -1)
+        curLexState = jjnewLexState[jjmatchedKind];
+        curPos = 0;
+        jjmatchedKind = 0x7fffffff;
+        try {
+           curChar = input_stream.readChar();
+           continue;
+        }
+        catch (java.io.IOException e1) { }
+     }
+     int error_line = input_stream.getEndLine();
+     int error_column = input_stream.getEndColumn();
+     String error_after = null;
+     boolean EOFSeen = false;
+     try { input_stream.readChar(); input_stream.backup(1); }
+     catch (java.io.IOException e1) {
+        EOFSeen = true;
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+        if (curChar == '\n' || curChar == '\r') {
+           error_line++;
+           error_column = 0;
+        }
+        else
+           error_column++;
+     }
+     if (!EOFSeen) {
+        input_stream.backup(1);
+        error_after = curPos <= 1 ? "" : input_stream.GetImage();
+     }
+     throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
+   }
+  }
+}
+
+void SkipLexicalActions(Token matchedToken)
+{
+   switch(jjmatchedKind)
+   {
+      default :
+         break;
+   }
+}
+void MoreLexicalActions()
+{
+   jjimageLen += (lengthOfMatch = jjmatchedPos + 1);
+   switch(jjmatchedKind)
+   {
+      case 7 :
+         image.append(input_stream.GetSuffix(jjimageLen));
+         jjimageLen = 0;
+                   input_stream.backup(1);
+         break;
+      default :
+         break;
+   }
+}
+void TokenLexicalActions(Token matchedToken)
+{
+   switch(jjmatchedKind)
+   {
+      case 128 :
+        image.append(jjstrLiteralImages[128]);
+        lengthOfMatch = jjstrLiteralImages[128].length();
+     matchedToken.kind = GT;
+     ((ASTParser.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT;
+     input_stream.backup(2);
+         break;
+      case 129 :
+        image.append(jjstrLiteralImages[129]);
+        lengthOfMatch = jjstrLiteralImages[129].length();
+     matchedToken.kind = GT;
+     ((ASTParser.GTToken)matchedToken).realKind = RSIGNEDSHIFT;
+     input_stream.backup(1);
+         break;
+      default :
+         break;
+   }
+}
+private void jjCheckNAdd(int state)
+{
+   if (jjrounds[state] != jjround)
+   {
+      jjstateSet[jjnewStateCnt++] = state;
+      jjrounds[state] = jjround;
+   }
+}
+private void jjAddStates(int start, int end)
+{
+   do {
+      jjstateSet[jjnewStateCnt++] = jjnextStates[start];
+   } while (start++ != end);
+}
+private void jjCheckNAddTwoStates(int state1, int state2)
+{
+   jjCheckNAdd(state1);
+   jjCheckNAdd(state2);
+}
+
+private void jjCheckNAddStates(int start, int end)
+{
+   do {
+      jjCheckNAdd(jjnextStates[start]);
+   } while (start++ != end);
+}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/JavaCharStream.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/JavaCharStream.java
new file mode 100644
index 0000000..62a6544
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/JavaCharStream.java
@@ -0,0 +1,629 @@
+/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 5.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (with java-like unicode escape processing).
+ */
+
+public
+class JavaCharStream
+{
+  /** Whether parser is static. */
+  public static final boolean staticFlag = false;
+
+  static final int hexval(char c) throws java.io.IOException {
+    switch(c)
+    {
+       case '0' :
+          return 0;
+       case '1' :
+          return 1;
+       case '2' :
+          return 2;
+       case '3' :
+          return 3;
+       case '4' :
+          return 4;
+       case '5' :
+          return 5;
+       case '6' :
+          return 6;
+       case '7' :
+          return 7;
+       case '8' :
+          return 8;
+       case '9' :
+          return 9;
+
+       case 'a' :
+       case 'A' :
+          return 10;
+       case 'b' :
+       case 'B' :
+          return 11;
+       case 'c' :
+       case 'C' :
+          return 12;
+       case 'd' :
+       case 'D' :
+          return 13;
+       case 'e' :
+       case 'E' :
+          return 14;
+       case 'f' :
+       case 'F' :
+          return 15;
+    }
+
+    throw new java.io.IOException(); // Should never come here
+  }
+
+/** Position in buffer. */
+  public int bufpos = -1;
+  int bufsize;
+  int available;
+  int tokenBegin;
+  protected int bufline[];
+  protected int bufcolumn[];
+
+  protected int column = 0;
+  protected int line = 1;
+
+  protected boolean prevCharIsCR = false;
+  protected boolean prevCharIsLF = false;
+
+  protected java.io.Reader inputStream;
+
+  protected char[] nextCharBuf;
+  protected char[] buffer;
+  protected int maxNextCharInd = 0;
+  protected int nextCharInd = -1;
+  protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
+
+  protected void ExpandBuff(boolean wrapAround)
+  {
+    char[] newbuffer = new char[bufsize + 2048];
+    int newbufline[] = new int[bufsize + 2048];
+    int newbufcolumn[] = new int[bufsize + 2048];
+
+    try
+    {
+      if (wrapAround)
+      {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+        bufcolumn = newbufcolumn;
+
+        bufpos += (bufsize - tokenBegin);
+    }
+    else
+    {
+        System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+        buffer = newbuffer;
+
+        System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+        bufline = newbufline;
+
+        System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+        bufcolumn = newbufcolumn;
+
+        bufpos -= tokenBegin;
+      }
+    }
+    catch (Throwable t)
+    {
+      throw new Error(t.getMessage());
+    }
+
+    available = (bufsize += 2048);
+    tokenBegin = 0;
+  }
+
+  protected void FillBuff() throws java.io.IOException
+  {
+    int i;
+    if (maxNextCharInd == 4096)
+      maxNextCharInd = nextCharInd = 0;
+
+    try {
+      if ((i = inputStream.read(nextCharBuf, maxNextCharInd,
+                                          4096 - maxNextCharInd)) == -1)
+      {
+        inputStream.close();
+        throw new java.io.IOException();
+      }
+      else
+         maxNextCharInd += i;
+      return;
+    }
+    catch(java.io.IOException e) {
+      if (bufpos != 0)
+      {
+        --bufpos;
+        backup(0);
+      }
+      else
+      {
+        bufline[bufpos] = line;
+        bufcolumn[bufpos] = column;
+      }
+      throw e;
+    }
+  }
+
+  protected char ReadByte() throws java.io.IOException
+  {
+    if (++nextCharInd >= maxNextCharInd)
+      FillBuff();
+
+    return nextCharBuf[nextCharInd];
+  }
+
+/** @return starting character for token. */
+  public char BeginToken() throws java.io.IOException
+  {
+    if (inBuf > 0)
+    {
+      --inBuf;
+
+      if (++bufpos == bufsize)
+        bufpos = 0;
+
+      tokenBegin = bufpos;
+      return buffer[bufpos];
+    }
+
+    tokenBegin = 0;
+    bufpos = -1;
+
+    return readChar();
+  }
+
+  protected void AdjustBuffSize()
+  {
+    if (available == bufsize)
+    {
+      if (tokenBegin > 2048)
+      {
+        bufpos = 0;
+        available = tokenBegin;
+      }
+      else
+        ExpandBuff(false);
+    }
+    else if (available > tokenBegin)
+      available = bufsize;
+    else if ((tokenBegin - available) < 2048)
+      ExpandBuff(true);
+    else
+      available = tokenBegin;
+  }
+
+  protected void UpdateLineColumn(char c)
+  {
+    column++;
+
+    if (prevCharIsLF)
+    {
+      prevCharIsLF = false;
+      line += (column = 1);
+    }
+    else if (prevCharIsCR)
+    {
+      prevCharIsCR = false;
+      if (c == '\n')
+      {
+        prevCharIsLF = true;
+      }
+      else
+        line += (column = 1);
+    }
+
+    switch (c)
+    {
+      case '\r' :
+        prevCharIsCR = true;
+        break;
+      case '\n' :
+        prevCharIsLF = true;
+        break;
+      case '\t' :
+        column--;
+        column += (tabSize - (column % tabSize));
+        break;
+      default :
+        break;
+    }
+
+    bufline[bufpos] = line;
+    bufcolumn[bufpos] = column;
+  }
+
+/** Read a character. */
+  public char readChar() throws java.io.IOException
+  {
+    if (inBuf > 0)
+    {
+      --inBuf;
+
+      if (++bufpos == bufsize)
+        bufpos = 0;
+
+      return buffer[bufpos];
+    }
+
+    char c;
+
+    if (++bufpos == available)
+      AdjustBuffSize();
+
+    if ((buffer[bufpos] = c = ReadByte()) == '\\')
+    {
+      UpdateLineColumn(c);
+
+      int backSlashCnt = 1;
+
+      for (;;) // Read all the backslashes
+      {
+        if (++bufpos == available)
+          AdjustBuffSize();
+
+        try
+        {
+          if ((buffer[bufpos] = c = ReadByte()) != '\\')
+          {
+            UpdateLineColumn(c);
+            // found a non-backslash char.
+            if ((c == 'u') && ((backSlashCnt & 1) == 1))
+            {
+              if (--bufpos < 0)
+                bufpos = bufsize - 1;
+
+              break;
+            }
+
+            backup(backSlashCnt);
+            return '\\';
+          }
+        }
+        catch(java.io.IOException e)
+        {
+	  // We are returning one backslash so we should only backup (count-1)
+          if (backSlashCnt > 1)
+            backup(backSlashCnt-1);
+
+          return '\\';
+        }
+
+        UpdateLineColumn(c);
+        backSlashCnt++;
+      }
+
+      // Here, we have seen an odd number of backslash's followed by a 'u'
+      try
+      {
+        while ((c = ReadByte()) == 'u')
+          ++column;
+
+        buffer[bufpos] = c = (char)(hexval(c) << 12 |
+                                    hexval(ReadByte()) << 8 |
+                                    hexval(ReadByte()) << 4 |
+                                    hexval(ReadByte()));
+
+        column += 4;
+      }
+      catch(java.io.IOException e)
+      {
+        throw new Error("Invalid escape character at line " + line +
+                                         " column " + column + ".");
+      }
+
+      if (backSlashCnt == 1)
+        return c;
+      else
+      {
+        backup(backSlashCnt - 1);
+        return '\\';
+      }
+    }
+    else
+    {
+      UpdateLineColumn(c);
+      return c;
+    }
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndColumn
+   */
+  public int getColumn() {
+    return bufcolumn[bufpos];
+  }
+
+  @Deprecated
+  /**
+   * @deprecated
+   * @see #getEndLine
+   */
+  public int getLine() {
+    return bufline[bufpos];
+  }
+
+/** Get end column. */
+  public int getEndColumn() {
+    return bufcolumn[bufpos];
+  }
+
+/** Get end line. */
+  public int getEndLine() {
+    return bufline[bufpos];
+  }
+
+/** @return column of token start */
+  public int getBeginColumn() {
+    return bufcolumn[tokenBegin];
+  }
+
+/** @return line number of token start */
+  public int getBeginLine() {
+    return bufline[tokenBegin];
+  }
+
+/** Retreat. */
+  public void backup(int amount) {
+
+    inBuf += amount;
+    if ((bufpos -= amount) < 0)
+      bufpos += bufsize;
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.Reader dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    available = bufsize = buffersize;
+    buffer = new char[buffersize];
+    bufline = new int[buffersize];
+    bufcolumn = new int[buffersize];
+    nextCharBuf = new char[4096];
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.Reader dstream,
+                                        int startline, int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.Reader dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+/** Reinitialise. */
+  public void ReInit(java.io.Reader dstream,
+                 int startline, int startcolumn, int buffersize)
+  {
+    inputStream = dstream;
+    line = startline;
+    column = startcolumn - 1;
+
+    if (buffer == null || buffersize != buffer.length)
+    {
+      available = bufsize = buffersize;
+      buffer = new char[buffersize];
+      bufline = new int[buffersize];
+      bufcolumn = new int[buffersize];
+      nextCharBuf = new char[4096];
+    }
+    prevCharIsLF = prevCharIsCR = false;
+    tokenBegin = inBuf = maxNextCharInd = 0;
+    nextCharInd = bufpos = -1;
+  }
+
+/** Reinitialise. */
+  public void ReInit(java.io.Reader dstream,
+                                        int startline, int startcolumn)
+  {
+    ReInit(dstream, startline, startcolumn, 4096);
+  }
+
+/** Reinitialise. */
+  public void ReInit(java.io.Reader dstream)
+  {
+    ReInit(dstream, 1, 1, 4096);
+  }
+/** Constructor. */
+  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+    this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+                        int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.InputStream dstream, int startline,
+                        int startcolumn)
+  {
+    this(dstream, startline, startcolumn, 4096);
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+    this(dstream, encoding, 1, 1, 4096);
+  }
+
+/** Constructor. */
+  public JavaCharStream(java.io.InputStream dstream)
+  {
+    this(dstream, 1, 1, 4096);
+  }
+
+/** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+    ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
+/** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, int startline,
+  int startcolumn, int buffersize)
+  {
+    ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+/** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                     int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+    ReInit(dstream, encoding, startline, startcolumn, 4096);
+  }
+/** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, int startline,
+                     int startcolumn)
+  {
+    ReInit(dstream, startline, startcolumn, 4096);
+  }
+/** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+    ReInit(dstream, encoding, 1, 1, 4096);
+  }
+
+/** Reinitialise. */
+  public void ReInit(java.io.InputStream dstream)
+  {
+    ReInit(dstream, 1, 1, 4096);
+  }
+
+  /** @return token image as String */
+  public String GetImage()
+  {
+    if (bufpos >= tokenBegin)
+      return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+    else
+      return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+                              new String(buffer, 0, bufpos + 1);
+  }
+
+  /** @return suffix */
+  public char[] GetSuffix(int len)
+  {
+    char[] ret = new char[len];
+
+    if ((bufpos + 1) >= len)
+      System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+    else
+    {
+      System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+                                                        len - bufpos - 1);
+      System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+    }
+
+    return ret;
+  }
+
+  /** Set buffers back to null when finished. */
+  public void Done()
+  {
+    nextCharBuf = null;
+    buffer = null;
+    bufline = null;
+    bufcolumn = null;
+  }
+
+  /**
+   * Method to adjust line and column numbers for the start of a token.
+   */
+  public void adjustBeginLineColumn(int newLine, int newCol)
+  {
+    int start = tokenBegin;
+    int len;
+
+    if (bufpos >= tokenBegin)
+    {
+      len = bufpos - tokenBegin + inBuf + 1;
+    }
+    else
+    {
+      len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+    }
+
+    int i = 0, j = 0, k = 0;
+    int nextColDiff = 0, columnDiff = 0;
+
+    while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
+    {
+      bufline[j] = newLine;
+      nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+      bufcolumn[j] = newCol + columnDiff;
+      columnDiff = nextColDiff;
+      i++;
+    }
+
+    if (i < len)
+    {
+      bufline[j] = newLine++;
+      bufcolumn[j] = newCol + columnDiff;
+
+      while (i++ < len)
+      {
+        if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+          bufline[j] = newLine++;
+        else
+          bufline[j] = newLine;
+      }
+    }
+
+    line = bufline[j];
+    column = bufcolumn[j];
+  }
+
+}
+/* JavaCC - OriginalChecksum=5111a95355f2f1cc405246f828703097 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ParseException.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ParseException.java
new file mode 100644
index 0000000..31d07cd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/ParseException.java
@@ -0,0 +1,199 @@
+/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
+/* JavaCCOptions:KEEP_LINE_COL=null */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/**
+ * This exception is thrown when parse errors are encountered.
+ * You can explicitly create objects of this exception type by
+ * calling the method generateParseException in the generated
+ * parser.
+ *
+ * You can modify this class to customize your error reporting
+ * mechanisms so long as you retain the public fields.
+ */
+public class ParseException extends Exception {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * This constructor is used by the method "generateParseException"
+   * in the generated parser.  Calling this constructor generates
+   * a new object of this type with the fields "currentToken",
+   * "expectedTokenSequences", and "tokenImage" set.
+   */
+  public ParseException(Token currentTokenVal,
+                        int[][] expectedTokenSequencesVal,
+                        String[] tokenImageVal
+                       )
+  {
+    super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
+    currentToken = currentTokenVal;
+    expectedTokenSequences = expectedTokenSequencesVal;
+    tokenImage = tokenImageVal;
+  }
+
+  /**
+   * The following constructors are for use by you for whatever
+   * purpose you can think of.  Constructing the exception in this
+   * manner makes the exception behave in the normal way - i.e., as
+   * documented in the class "Throwable".  The fields "errorToken",
+   * "expectedTokenSequences", and "tokenImage" do not contain
+   * relevant information.  The JavaCC generated code does not use
+   * these constructors.
+   */
+
+  public ParseException() {
+    super();
+  }
+
+  /** Constructor with message. */
+  public ParseException(String message) {
+    super(message);
+  }
+
+
+  /**
+   * This is the last token that has been consumed successfully.  If
+   * this object has been created due to a parse error, the token
+   * followng this token will (therefore) be the first error token.
+   */
+  public Token currentToken;
+
+  /**
+   * Each entry in this array is an array of integers.  Each array
+   * of integers represents a sequence of tokens (by their ordinal
+   * values) that is expected at this point of the parse.
+   */
+  public int[][] expectedTokenSequences;
+
+  /**
+   * This is a reference to the "tokenImage" array of the generated
+   * parser within which the parse error occurred.  This array is
+   * defined in the generated ...Constants interface.
+   */
+  public String[] tokenImage;
+
+  /**
+   * It uses "currentToken" and "expectedTokenSequences" to generate a parse
+   * error message and returns it.  If this object has been created
+   * due to a parse error, and you do not catch it (it gets thrown
+   * from the parser) the correct error message
+   * gets displayed.
+   */
+  private static String initialise(Token currentToken,
+                           int[][] expectedTokenSequences,
+                           String[] tokenImage) {
+    String eol = System.getProperty("line.separator", "\n");
+    StringBuffer expected = new StringBuffer();
+    int maxSize = 0;
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
+      if (maxSize < expectedTokenSequences[i].length) {
+        maxSize = expectedTokenSequences[i].length;
+      }
+      for (int j = 0; j < expectedTokenSequences[i].length; j++) {
+        expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
+      }
+      if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
+        expected.append("...");
+      }
+      expected.append(eol).append("    ");
+    }
+    String retval = "Encountered \"";
+    Token tok = currentToken.next;
+    for (int i = 0; i < maxSize; i++) {
+      if (i != 0) retval += " ";
+      if (tok.kind == 0) {
+        retval += tokenImage[0];
+        break;
+      }
+      retval += " " + tokenImage[tok.kind];
+      retval += " \"";
+      retval += add_escapes(tok.image);
+      retval += " \"";
+      tok = tok.next;
+    }
+    retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
+    retval += "." + eol;
+    if (expectedTokenSequences.length == 1) {
+      retval += "Was expecting:" + eol + "    ";
+    } else {
+      retval += "Was expecting one of:" + eol + "    ";
+    }
+    retval += expected.toString();
+    return retval;
+  }
+
+  /**
+   * The end of line string for this machine.
+   */
+  protected String eol = System.getProperty("line.separator", "\n");
+
+  /**
+   * Used to convert raw characters to their escaped version
+   * when these raw version cannot be used as part of an ASCII
+   * string literal.
+   */
+  static String add_escapes(String str) {
+      StringBuffer retval = new StringBuffer();
+      char ch;
+      for (int i = 0; i < str.length(); i++) {
+        switch (str.charAt(i))
+        {
+           case 0 :
+              continue;
+           case '\b':
+              retval.append("\\b");
+              continue;
+           case '\t':
+              retval.append("\\t");
+              continue;
+           case '\n':
+              retval.append("\\n");
+              continue;
+           case '\f':
+              retval.append("\\f");
+              continue;
+           case '\r':
+              retval.append("\\r");
+              continue;
+           case '\"':
+              retval.append("\\\"");
+              continue;
+           case '\'':
+              retval.append("\\\'");
+              continue;
+           case '\\':
+              retval.append("\\\\");
+              continue;
+           default:
+              if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+                 String s = "0000" + Integer.toString(ch, 16);
+                 retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+              } else {
+                 retval.append(ch);
+              }
+              continue;
+        }
+      }
+      return retval.toString();
+   }
+
+}
+/* JavaCC - OriginalChecksum=62ba72b2159703420d5ce7232a0226fb (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/Token.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/Token.java
new file mode 100644
index 0000000..8aa85f4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/Token.java
@@ -0,0 +1,143 @@
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
+/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token implements java.io.Serializable {
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * An integer that describes the kind of this token.  This numbering
+   * system is determined by JavaCCParser, and a table of these numbers is
+   * stored in the file ...Constants.java.
+   */
+  public int kind;
+
+  /** The line number of the first character of this Token. */
+  public int beginLine;
+  /** The column number of the first character of this Token. */
+  public int beginColumn;
+  /** The line number of the last character of this Token. */
+  public int endLine;
+  /** The column number of the last character of this Token. */
+  public int endColumn;
+
+  /**
+   * The string image of the token.
+   */
+  public String image;
+
+  /**
+   * A reference to the next regular (non-special) token from the input
+   * stream.  If this is the last token from the input stream, or if the
+   * token manager has not read tokens beyond this one, this field is
+   * set to null.  This is true only if this token is also a regular
+   * token.  Otherwise, see below for a description of the contents of
+   * this field.
+   */
+  public Token next;
+
+  /**
+   * This field is used to access special tokens that occur prior to this
+   * token, but after the immediately preceding regular (non-special) token.
+   * If there are no such special tokens, this field is set to null.
+   * When there are more than one such special token, this field refers
+   * to the last of these special tokens, which in turn refers to the next
+   * previous special token through its specialToken field, and so on
+   * until the first special token (whose specialToken field is null).
+   * The next fields of special tokens refer to other special tokens that
+   * immediately follow it (without an intervening regular token).  If there
+   * is no such token, this field is null.
+   */
+  public Token specialToken;
+
+  /**
+   * An optional attribute value of the Token.
+   * Tokens which are not used as syntactic sugar will often contain
+   * meaningful values that will be used later on by the compiler or
+   * interpreter. This attribute value is often different from the image.
+   * Any subclass of Token that actually wants to return a non-null value can
+   * override this method as appropriate.
+   */
+  public Object getValue() {
+    return null;
+  }
+
+  /**
+   * No-argument constructor
+   */
+  public Token() {}
+
+  /**
+   * Constructs a new token for the specified Image.
+   */
+  public Token(int kind)
+  {
+    this(kind, null);
+  }
+
+  /**
+   * Constructs a new token for the specified Image and Kind.
+   */
+  public Token(int kind, String image)
+  {
+    this.kind = kind;
+    this.image = image;
+  }
+
+  /**
+   * Returns the image.
+   */
+  public String toString()
+  {
+    return image;
+  }
+
+  /**
+   * Returns a new Token object, by default. However, if you want, you
+   * can create and return subclass objects based on the value of ofKind.
+   * Simply add the cases to the switch for all those special cases.
+   * For example, if you have a subclass of Token called IDToken that
+   * you want to create if ofKind is ID, simply add something like :
+   *
+   *    case MyParserConstants.ID : return new IDToken(ofKind, image);
+   *
+   * to the following switch statement. Then you can cast matchedToken
+   * variable to the appropriate type and use sit in your lexical actions.
+   */
+  public static Token newToken(int ofKind, String image)
+  {
+    switch(ofKind)
+    {
+      default : return new Token(ofKind, image);
+    }
+  }
+
+  public static Token newToken(int ofKind)
+  {
+    return newToken(ofKind, null);
+  }
+
+}
+/* JavaCC - OriginalChecksum=a2058282d76ebf324ed236272a3341cb (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/TokenMgrError.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/TokenMgrError.java
new file mode 100644
index 0000000..09197e8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/generated/com/github/javaparser/TokenMgrError.java
@@ -0,0 +1,159 @@
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
+/* JavaCCOptions: */
+/*
+ *
+ * This file is part of Java 1.8 parser and Abstract Syntax Tree.
+ *
+ * Java 1.8 parser and Abstract Syntax Tree is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Java 1.8 parser and Abstract Syntax Tree.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.github.javaparser;
+
+/** Token Manager Error. */
+public class TokenMgrError extends Error
+{
+
+  /**
+   * The version identifier for this Serializable class.
+   * Increment only if the <i>serialized</i> form of the
+   * class changes.
+   */
+  private static final long serialVersionUID = 1L;
+
+  /*
+   * Ordinals for various reasons why an Error of this type can be thrown.
+   */
+
+  /**
+   * Lexical error occurred.
+   */
+  static final int LEXICAL_ERROR = 0;
+
+  /**
+   * An attempt was made to create a second instance of a static token manager.
+   */
+  static final int STATIC_LEXER_ERROR = 1;
+
+  /**
+   * Tried to change to an invalid lexical state.
+   */
+  static final int INVALID_LEXICAL_STATE = 2;
+
+  /**
+   * Detected (and bailed out of) an infinite loop in the token manager.
+   */
+  static final int LOOP_DETECTED = 3;
+
+  /**
+   * Indicates the reason why the exception is thrown. It will have
+   * one of the above 4 values.
+   */
+  int errorCode;
+
+  /**
+   * Replaces unprintable characters by their escaped (or unicode escaped)
+   * equivalents in the given string
+   */
+  protected static final String addEscapes(String str) {
+    StringBuffer retval = new StringBuffer();
+    char ch;
+    for (int i = 0; i < str.length(); i++) {
+      switch (str.charAt(i))
+      {
+        case 0 :
+          continue;
+        case '\b':
+          retval.append("\\b");
+          continue;
+        case '\t':
+          retval.append("\\t");
+          continue;
+        case '\n':
+          retval.append("\\n");
+          continue;
+        case '\f':
+          retval.append("\\f");
+          continue;
+        case '\r':
+          retval.append("\\r");
+          continue;
+        case '\"':
+          retval.append("\\\"");
+          continue;
+        case '\'':
+          retval.append("\\\'");
+          continue;
+        case '\\':
+          retval.append("\\\\");
+          continue;
+        default:
+          if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+            String s = "0000" + Integer.toString(ch, 16);
+            retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+          } else {
+            retval.append(ch);
+          }
+          continue;
+      }
+    }
+    return retval.toString();
+  }
+
+  /**
+   * Returns a detailed message for the Error when it is thrown by the
+   * token manager to indicate a lexical error.
+   * Parameters :
+   *    EOFSeen     : indicates if EOF caused the lexical error
+   *    curLexState : lexical state in which this error occurred
+   *    errorLine   : line number when the error occurred
+   *    errorColumn : column number when the error occurred
+   *    errorAfter  : prefix that was seen before this error occurred
+   *    curchar     : the offending character
+   * Note: You can customize the lexical error message by modifying this method.
+   */
+  protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
+    return("Lexical error at line " +
+          errorLine + ", column " +
+          errorColumn + ".  Encountered: " +
+          (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
+          "after : \"" + addEscapes(errorAfter) + "\"");
+  }
+
+  /**
+   * You can also modify the body of this method to customize your error messages.
+   * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+   * of end-users concern, so you can return something like :
+   *
+   *     "Internal Error : Please file a bug report .... "
+   *
+   * from this method for such cases in the release version of your parser.
+   */
+  public String getMessage() {
+    return super.getMessage();
+  }
+
+  /*
+   * Constructors of various flavors follow.
+   */
+
+  /** No arg constructor. */
+  public TokenMgrError() {
+  }
+
+  /** Constructor with message and reason. */
+  public TokenMgrError(String message, int reason) {
+    super(message);
+    errorCode = reason;
+  }
+
+  /** Full Constructor. */
+  public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
+    this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+  }
+}
+/* JavaCC - OriginalChecksum=f06c7e964b5c13a732337c2f3fb4f836 (do not edit this line) */
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ASTHelper.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ASTHelper.java
new file mode 100644
index 0000000..7e706cd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ASTHelper.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.QualifiedNameExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.ast.type.ReferenceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.VoidType;
+import com.github.javaparser.ast.type.PrimitiveType.Primitive;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class helps to construct new nodes.
+ * 
+ * @author Júlio Vilmar Gesser
+ */
+public final class ASTHelper {
+
+    public static final PrimitiveType BYTE_TYPE = new PrimitiveType(Primitive.Byte);
+
+    public static final PrimitiveType SHORT_TYPE = new PrimitiveType(Primitive.Short);
+
+    public static final PrimitiveType INT_TYPE = new PrimitiveType(Primitive.Int);
+
+    public static final PrimitiveType LONG_TYPE = new PrimitiveType(Primitive.Long);
+
+    public static final PrimitiveType FLOAT_TYPE = new PrimitiveType(Primitive.Float);
+
+    public static final PrimitiveType DOUBLE_TYPE = new PrimitiveType(Primitive.Double);
+
+    public static final PrimitiveType BOOLEAN_TYPE = new PrimitiveType(Primitive.Boolean);
+
+    public static final PrimitiveType CHAR_TYPE = new PrimitiveType(Primitive.Char);
+
+    public static final VoidType VOID_TYPE = new VoidType();
+
+    private ASTHelper() {
+        // nop
+    }
+
+    /**
+     * Creates a new {@link NameExpr} from a qualified name.<br>
+     * The qualified name can contains "." (dot) characters.
+     * 
+     * @param qualifiedName
+     *            qualified name
+     * @return instanceof {@link NameExpr}
+     */
+    public static NameExpr createNameExpr(String qualifiedName) {
+        String[] split = qualifiedName.split("\\.");
+        NameExpr ret = new NameExpr(split[0]);
+        for (int i = 1; i < split.length; i++) {
+            ret = new QualifiedNameExpr(ret, split[i]);
+        }
+        return ret;
+    }
+
+    /**
+     * Creates a new {@link Parameter}.
+     * 
+     * @param type
+     *            type of the parameter
+     * @param name
+     *            name of the parameter
+     * @return instance of {@link Parameter}
+     */
+    public static Parameter createParameter(Type type, String name) {
+        return new Parameter(type, new VariableDeclaratorId(name));
+    }
+
+    /**
+     * Creates a {@link FieldDeclaration}.
+     * 
+     * @param modifiers
+     *            modifiers
+     * @param type
+     *            type
+     * @param variable
+     *            variable declarator
+     * @return instance of {@link FieldDeclaration}
+     */
+    public static FieldDeclaration createFieldDeclaration(int modifiers, Type type, VariableDeclarator variable) {
+        List<VariableDeclarator> variables = new ArrayList<VariableDeclarator>();
+        variables.add(variable);
+        FieldDeclaration ret = new FieldDeclaration(modifiers, type, variables);
+        return ret;
+    }
+
+    /**
+     * Creates a {@link FieldDeclaration}.
+     * 
+     * @param modifiers
+     *            modifiers
+     * @param type
+     *            type
+     * @param name
+     *            field name
+     * @return instance of {@link FieldDeclaration}
+     */
+    public static FieldDeclaration createFieldDeclaration(int modifiers, Type type, String name) {
+        VariableDeclaratorId id = new VariableDeclaratorId(name);
+        VariableDeclarator variable = new VariableDeclarator(id);
+        return createFieldDeclaration(modifiers, type, variable);
+    }
+
+    /**
+     * Creates a {@link VariableDeclarationExpr}.
+     * 
+     * @param type
+     *            type
+     * @param name
+     *            name
+     * @return instance of {@link VariableDeclarationExpr}
+     */
+    public static VariableDeclarationExpr createVariableDeclarationExpr(Type type, String name) {
+        List<VariableDeclarator> vars = new ArrayList<VariableDeclarator>();
+        vars.add(new VariableDeclarator(new VariableDeclaratorId(name)));
+        return new VariableDeclarationExpr(type, vars);
+    }
+
+    /**
+     * Adds the given parameter to the method. The list of parameters will be
+     * initialized if it is <code>null</code>.
+     * 
+     * @param method
+     *            method
+     * @param parameter
+     *            parameter
+     */
+    public static void addParameter(MethodDeclaration method, Parameter parameter) {
+        List<Parameter> parameters = method.getParameters();
+        if (parameters == null) {
+            parameters = new ArrayList<Parameter>();
+            method.setParameters(parameters);
+        }
+        parameters.add(parameter);
+    }
+
+    /**
+     * Adds the given argument to the method call. The list of arguments will be
+     * initialized if it is <code>null</code>.
+     * 
+     * @param call
+     *            method call
+     * @param arg
+     *            argument value
+     */
+    public static void addArgument(MethodCallExpr call, Expression arg) {
+        List<Expression> args = call.getArgs();
+        if (args == null) {
+            args = new ArrayList<Expression>();
+            call.setArgs(args);
+        }
+        args.add(arg);
+    }
+
+    /**
+     * Adds the given type declaration to the compilation unit. The list of
+     * types will be initialized if it is <code>null</code>.
+     * 
+     * @param cu
+     *            compilation unit
+     * @param type
+     *            type declaration
+     */
+    public static void addTypeDeclaration(CompilationUnit cu, TypeDeclaration type) {
+        List<TypeDeclaration> types = cu.getTypes();
+        if (types == null) {
+            types = new ArrayList<TypeDeclaration>();
+            cu.setTypes(types);
+        }
+        types.add(type);
+
+    }
+
+    /**
+     * Creates a new {@link ReferenceType} for a class or interface.
+     * 
+     * @param name
+     *            name of the class or interface
+     * @param arrayCount
+     *            number of arrays or <code>0</code> if is not a array.
+     * @return instanceof {@link ReferenceType}
+     */
+    public static ReferenceType createReferenceType(String name, int arrayCount) {
+        return new ReferenceType(new ClassOrInterfaceType(name), arrayCount);
+    }
+
+    /**
+     * Creates a new {@link ReferenceType} for the given primitive type.
+     * 
+     * @param type
+     *            primitive type
+     * @param arrayCount
+     *            number of arrays or <code>0</code> if is not a array.
+     * @return instanceof {@link ReferenceType}
+     */
+    public static ReferenceType createReferenceType(PrimitiveType type, int arrayCount) {
+        return new ReferenceType(type, arrayCount);
+    }
+
+    /**
+     * Adds the given statement to the specified block. The list of statements
+     * will be initialized if it is <code>null</code>.
+     * 
+     * @param block to have expression added to
+     * @param stmt to be added
+     */
+    public static void addStmt(BlockStmt block, Statement stmt) {
+        List<Statement> stmts = block.getStmts();
+        if (stmts == null) {
+            stmts = new ArrayList<Statement>();
+            block.setStmts(stmts);
+        }
+        stmts.add(stmt);
+    }
+
+    /**
+     * Adds the given expression to the specified block. The list of statements
+     * will be initialized if it is <code>null</code>.
+     * 
+     * @param block to have expression added to
+     * @param expr to be added
+     */
+    public static void addStmt(BlockStmt block, Expression expr) {
+        addStmt(block, new ExpressionStmt(expr));
+    }
+
+    /**
+     * Adds the given declaration to the specified type. The list of members
+     * will be initialized if it is <code>null</code>.
+     * 
+     * @param type
+     *            type declaration
+     * @param decl
+     *            member declaration
+     */
+    public static void addMember(TypeDeclaration type, BodyDeclaration decl) {
+        List<BodyDeclaration> members = type.getMembers();
+        if (members == null) {
+            members = new ArrayList<BodyDeclaration>();
+            type.setMembers(members);
+        }
+        members.add(decl);
+    }
+
+    public static <N extends Node> List<N> getNodesByType(Node container, Class<N> clazz) {
+        List<N> nodes = new ArrayList<N>();
+        for (Node child : container.getChildrenNodes()) {
+            if (clazz.isInstance(child)) {
+                nodes.add(clazz.cast(child));
+            }
+            nodes.addAll(getNodesByType(child, clazz));
+        }
+        return nodes;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/JavaParser.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/JavaParser.java
new file mode 100644
index 0000000..4312550
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/JavaParser.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser;
+
+import static com.github.javaparser.PositionUtils.areInOrder;
+import static com.github.javaparser.PositionUtils.sortByBeginPosition;
+
+import com.github.javaparser.ASTParser;
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.CommentsCollection;
+import com.github.javaparser.ast.comments.CommentsParser;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+// FIXME this file does not seem to be generated by javacc. Is the doc wrong, or the javacc config?
+/**
+ * <p>
+ * This class was generated automatically by javacc, do not edit.
+ * </p>
+ * <p>
+ * Parse Java 1.5 source code and creates Abstract Syntax Tree classes.
+ * </p>
+ *
+ * @author Júlio Vilmar Gesser
+ */
+public final class JavaParser {
+    private JavaParser() {
+        // hide the constructor
+    }
+
+    private static boolean _doNotAssignCommentsPreceedingEmptyLines = true;
+
+    private static boolean _doNotConsiderAnnotationsAsNodeStartForCodeAttribution = false;
+
+    public static boolean getDoNotConsiderAnnotationsAsNodeStartForCodeAttribution()
+    {
+        return _doNotConsiderAnnotationsAsNodeStartForCodeAttribution;
+    }
+
+    public static void setDoNotConsiderAnnotationsAsNodeStartForCodeAttribution(boolean doNotConsiderAnnotationsAsNodeStartForCodeAttribution) {
+        _doNotConsiderAnnotationsAsNodeStartForCodeAttribution = doNotConsiderAnnotationsAsNodeStartForCodeAttribution;
+    }
+
+    public static boolean getDoNotAssignCommentsPreceedingEmptyLines()
+    {
+        return _doNotAssignCommentsPreceedingEmptyLines;
+    }
+
+    public static void setDoNotAssignCommentsPreceedingEmptyLines(boolean doNotAssignCommentsPreceedingEmptyLines)
+    {
+        _doNotAssignCommentsPreceedingEmptyLines = doNotAssignCommentsPreceedingEmptyLines;
+    }
+
+    public static CompilationUnit parse(final InputStream in,
+                                        final String encoding) {
+        return parse(in,encoding,true);
+    }
+
+    /**
+     * Parses the Java code contained in the {@link InputStream} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param in
+     *            {@link InputStream} containing Java source code
+     * @param encoding
+     *            encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static CompilationUnit parse(final InputStream in,
+                                        final String encoding, boolean considerComments) {
+        try {
+            String code = SourcesHelper.streamToString(in, encoding);
+            InputStream in1 = SourcesHelper.stringToStream(code, encoding);
+            CompilationUnit cu = new ASTParser(in1, encoding).CompilationUnit();
+            if (considerComments){
+                insertComments(cu,code);
+            }
+            return cu;
+        } catch (IOException ioe){
+            throw new ParseException(ioe.getMessage());
+        }
+    }
+
+    /**
+     * Parses the Java code contained in the {@link InputStream} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param in
+     *            {@link InputStream} containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static CompilationUnit parse(final InputStream in)
+            {
+        return parse(in, null,true);
+    }
+
+    public static CompilationUnit parse(final File file, final String encoding)
+            throws ParseException, IOException {
+        return parse(file,encoding,true);
+    }
+
+    /**
+     * Parses the Java code contained in a {@link File} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param file
+     *            {@link File} containing Java source code
+     * @param encoding
+     *            encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseException
+     *             if the source code has parser errors
+     * @throws IOException
+     */
+    public static CompilationUnit parse(final File file, final String encoding, boolean considerComments)
+            throws ParseException, IOException {
+        final FileInputStream in = new FileInputStream(file);
+        try {
+            return parse(in, encoding, considerComments);
+        } finally {
+            in.close();
+        }
+    }
+
+    /**
+     * Parses the Java code contained in a {@link File} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param file
+     *            {@link File} containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseException
+     *             if the source code has parser errors
+     * @throws IOException
+     */
+    public static CompilationUnit parse(final File file) throws ParseException,
+            IOException {
+        return parse(file, null,true);
+    }
+
+    public static CompilationUnit parse(final Reader reader, boolean considerComments)
+            {
+        try {
+            String code = SourcesHelper.readerToString(reader);
+            Reader reader1 = SourcesHelper.stringToReader(code);
+            CompilationUnit cu = new ASTParser(reader1).CompilationUnit();
+            if (considerComments){
+                insertComments(cu,code);
+            }
+            return cu;
+        } catch (IOException ioe){
+            throw new ParseException(ioe.getMessage());
+        }
+    }
+
+    /**
+     * Parses the Java block contained in a {@link String} and returns a
+     * {@link BlockStmt} that represents it.
+     *
+     * @param blockStatement
+     *            {@link String} containing Java block code
+     * @return BlockStmt representing the Java block
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static BlockStmt parseBlock(final String blockStatement)
+            {
+        StringReader sr = new StringReader(blockStatement);
+        BlockStmt result = new ASTParser(sr).Block();
+        sr.close();
+        return result;
+    }
+
+    /**
+     * Parses the Java statement contained in a {@link String} and returns a
+     * {@link Statement} that represents it.
+     *
+     * @param statement
+     *            {@link String} containing Java statement code
+     * @return Statement representing the Java statement
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static Statement parseStatement(final String statement) {
+        StringReader sr = new StringReader(statement);
+        Statement stmt = new ASTParser(sr).Statement();
+        sr.close();
+        return stmt;
+    }
+
+    /**
+     * Parses the Java import contained in a {@link String} and returns a
+     * {@link ImportDeclaration} that represents it.
+     *
+     * @param importDeclaration
+     *            {@link String} containing Java import code
+     * @return ImportDeclaration representing the Java import declaration
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static ImportDeclaration parseImport(final String importDeclaration) {
+        StringReader sr = new StringReader(importDeclaration);
+        ImportDeclaration id = new ASTParser(sr).ImportDeclaration();
+        sr.close();
+        return id;
+    }
+
+    /**
+     * Parses the Java expression contained in a {@link String} and returns a
+     * {@link Expression} that represents it.
+     *
+     * @param expression
+     *            {@link String} containing Java expression
+     * @return Expression representing the Java expression
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static Expression parseExpression(final String expression) {
+        StringReader sr = new StringReader(expression);
+        Expression e = new ASTParser(sr).Expression();
+        sr.close();
+        return e;
+    }
+
+    /**
+     * Parses the Java annotation contained in a {@link String} and returns a
+     * {@link AnnotationExpr} that represents it.
+     *
+     * @param annotation
+     *            {@link String} containing Java annotation
+     * @return AnnotationExpr representing the Java annotation
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static AnnotationExpr parseAnnotation(final String annotation) {
+        StringReader sr = new StringReader(annotation);
+        AnnotationExpr ae = new ASTParser(sr).Annotation();
+        sr.close();
+        return ae;
+    }
+
+    /**
+     * Parses the Java body declaration(e.g fields or methods) contained in a
+     * {@link String} and returns a {@link BodyDeclaration} that represents it.
+     *
+     * @param body
+     *            {@link String} containing Java body declaration
+     * @return BodyDeclaration representing the Java annotation
+     * @throws ParseException
+     *             if the source code has parser errors
+     */
+    public static BodyDeclaration parseBodyDeclaration(final String body) {
+        StringReader sr = new StringReader(body);
+        BodyDeclaration bd = new ASTParser(sr).AnnotationBodyDeclaration();
+        sr.close();
+        return bd;
+    }
+
+    /**
+     * Comments are attributed to the thing the comment and are removed from
+     * allComments.
+     */
+    private static void insertCommentsInCu(CompilationUnit cu, CommentsCollection commentsCollection){
+        if (commentsCollection.size()==0) return;
+
+        // I should sort all the direct children and the comments, if a comment is the first thing then it
+        // a comment to the CompilationUnit
+        // FIXME if there is no package it could be also a comment to the following class...
+        // so I could use some heuristics in these cases to distinguish the two cases
+
+        List<Comment> comments = commentsCollection.getAll();
+        PositionUtils.sortByBeginPosition(comments);
+        List<Node> children = cu.getChildrenNodes();
+        PositionUtils.sortByBeginPosition(children);
+
+        if (cu.getPackage()!=null && (children.size()==0 || PositionUtils.areInOrder(comments.get(0), children.get(0)))){
+            cu.setComment(comments.get(0));
+            comments.remove(0);
+        }
+
+        insertCommentsInNode(cu,comments);
+    }
+
+    private static boolean attributeLineCommentToNodeOrChild(Node node, LineComment lineComment)
+    {
+        // The node start and end at the same line as the comment,
+        // let's give to it the comment
+        if (node.getBeginLine()==lineComment.getBeginLine() && !node.hasComment())
+        {
+            node.setComment(lineComment);
+            return true;
+        } else {
+            // try with all the children, sorted by reverse position (so the
+            // first one is the nearest to the comment
+            List<Node> children = new LinkedList<Node>();
+            children.addAll(node.getChildrenNodes());
+            PositionUtils.sortByBeginPosition(children);
+            Collections.reverse(children);
+
+            for (Node child : children)
+            {
+                if (attributeLineCommentToNodeOrChild(child, lineComment))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+    }
+
+    /**
+     * This method try to attributes the nodes received to child of the node.
+     * It returns the node that were not attributed.
+     */
+    private static void insertCommentsInNode(Node node, List<Comment> commentsToAttribute){
+        if (commentsToAttribute.size()==0) return;
+
+        // the comments can:
+        // 1) Inside one of the child, then it is the child that have to associate them
+        // 2) If they are not inside a child they could be preceeding nothing, a comment or a child
+        //    if they preceed a child they are assigned to it, otherweise they remain "orphans"
+
+        List<Node> children = node.getChildrenNodes();
+        PositionUtils.sortByBeginPosition(children);
+
+        for (Node child : children){
+            List<Comment> commentsInsideChild = new LinkedList<Comment>();
+            for (Comment c : commentsToAttribute){
+                if (PositionUtils.nodeContains(child, c, _doNotConsiderAnnotationsAsNodeStartForCodeAttribution)){
+                    commentsInsideChild.add(c);
+                }
+            }
+            commentsToAttribute.removeAll(commentsInsideChild);
+            insertCommentsInNode(child,commentsInsideChild);
+        }
+
+        // I can attribute in line comments to elements preceeding them, if there
+        // is something contained in their line
+        List<Comment> attributedComments = new LinkedList<Comment>();
+        for (Comment comment : commentsToAttribute)
+        {
+            if (comment.isLineComment())
+            {
+                for (Node child : children)
+                {
+                    if (child.getEndLine()==comment.getBeginLine())
+                    {
+                        if (attributeLineCommentToNodeOrChild(child, comment.asLineComment()))
+                        {
+                            attributedComments.add(comment);
+                        }
+                    }
+                }
+            }
+        }
+
+        // at this point I create an ordered list of all remaining comments and children
+        Comment previousComment = null;
+        attributedComments = new LinkedList<Comment>();
+        List<Node> childrenAndComments = new LinkedList<Node>();
+        childrenAndComments.addAll(children);
+        childrenAndComments.addAll(commentsToAttribute);
+        PositionUtils.sortByBeginPosition(childrenAndComments, _doNotConsiderAnnotationsAsNodeStartForCodeAttribution);
+
+        for (Node thing : childrenAndComments){
+            if (thing instanceof Comment){
+                previousComment = (Comment)thing;
+                if (!previousComment.isOrphan())
+                {
+                    previousComment = null;
+                }
+            } else {
+                if (previousComment != null && !thing.hasComment()){
+                    if (!_doNotAssignCommentsPreceedingEmptyLines || !thereAreLinesBetween(previousComment, thing)) {
+                        thing.setComment(previousComment);
+                        attributedComments.add(previousComment);
+                        previousComment = null;
+                    }
+                }
+            }
+        }
+
+        commentsToAttribute.removeAll(attributedComments);
+
+        // all the remaining are orphan nodes
+        for (Comment c : commentsToAttribute){
+            if (c.isOrphan()) {
+                node.addOrphanComment(c);
+            }
+        }
+    }
+
+    private static boolean thereAreLinesBetween(Node a, Node b)
+    {
+        if (!PositionUtils.areInOrder(a, b))
+        {
+            return thereAreLinesBetween(b, a);
+        }
+        int endOfA = a.getEndLine();
+        return b.getBeginLine()>(a.getEndLine()+1);
+    }
+
+    private static void insertComments(CompilationUnit cu, String code) throws IOException {
+        CommentsParser commentsParser = new CommentsParser();
+        CommentsCollection allComments = commentsParser.parse(code);
+
+        insertCommentsInCu(cu,allComments);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/Position.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/Position.java
new file mode 100644
index 0000000..522411c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/Position.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Node;
+
+public class Position {
+    private int line;
+    private int column;
+
+    public static final Position ABSOLUTE_START = new Position(Node.ABSOLUTE_BEGIN_LINE,-1);
+    public static final Position ABSOLUTE_END = new Position(Node.ABSOLUTE_END_LINE,-1);
+
+    public static Position beginOf(Node node){
+        return new Position(node.getBeginLine(),node.getBeginColumn());
+    }
+
+    public static Position endOf(Node node){
+        return new Position(node.getEndLine(),node.getEndColumn());
+    }
+
+    public Position(int line, int column){
+        this.line = line;
+        this.column = column;
+    }
+
+    public int getLine(){
+        return this.line;
+    }
+
+    public int getColumn(){
+        return this.column;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/PositionUtils.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/PositionUtils.java
new file mode 100644
index 0000000..41df817
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/PositionUtils.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.AnnotableNode;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+
+import java.lang.Override;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
+
+import static java.lang.Integer.signum;
+
+public final class PositionUtils {
+
+    private PositionUtils() {
+        // prevent instantiation
+    }
+
+    public static <T extends Node> void sortByBeginPosition(List<T> nodes){
+        sortByBeginPosition(nodes, false);
+    }
+
+    public static <T extends Node> void sortByBeginPosition(List<T> nodes, final boolean ignoringAnnotations){
+        Collections.sort(nodes, new Comparator<Node>() {
+            @Override
+            public int compare(Node o1, Node o2) {
+                return PositionUtils.compare(o1, o2, ignoringAnnotations);
+            }
+        });
+    }
+
+    public static boolean areInOrder(Node a, Node b){
+        return areInOrder(a, b, false);
+    }
+
+    public static boolean areInOrder(Node a, Node b, boolean ignoringAnnotations){
+        return compare(a, b, ignoringAnnotations) <= 0;
+    }
+
+    private static int compare(Node a, Node b, boolean ignoringAnnotations) {
+        if (ignoringAnnotations) {
+            int signLine = signum(beginLineWithoutConsideringAnnotation(a) - beginLineWithoutConsideringAnnotation(b));
+            if (signLine == 0) {
+                return signum(beginColumnWithoutConsideringAnnotation(a) - beginColumnWithoutConsideringAnnotation(b));
+            } else {
+                return signLine;
+            }
+        }
+
+        int signLine = signum( a.getBeginLine() - b.getBeginLine() );
+        if (signLine == 0) {
+            return signum(a.getBeginColumn() - b.getBeginColumn());
+        } else {
+            return signLine;
+        }
+    }
+
+    public static AnnotationExpr getLastAnnotation(Node node) {
+        if (node instanceof AnnotableNode){
+            List<AnnotationExpr> annotations = new LinkedList<AnnotationExpr>();
+            annotations.addAll(((AnnotableNode) node).getAnnotations());
+            if (annotations.size()==0){
+                return null;
+            }
+            sortByBeginPosition(annotations);
+            return annotations.get(annotations.size()-1);
+        } else {
+            return null;
+        }
+    }
+
+    private static int beginLineWithoutConsideringAnnotation(Node node) {
+        return beginNodeWithoutConsideringAnnotations(node).getBeginLine();
+    }
+
+
+    private static int beginColumnWithoutConsideringAnnotation(Node node) {
+        return beginNodeWithoutConsideringAnnotations(node).getBeginColumn();
+    }
+
+    private static Node beginNodeWithoutConsideringAnnotations(Node node) {
+        if (node instanceof MethodDeclaration) {
+            MethodDeclaration casted = (MethodDeclaration) node;
+            return casted.getType();
+        } else if (node instanceof FieldDeclaration) {
+            FieldDeclaration casted = (FieldDeclaration) node;
+            return casted.getType();
+        } else if (node instanceof ClassOrInterfaceDeclaration) {
+            ClassOrInterfaceDeclaration casted = (ClassOrInterfaceDeclaration) node;
+            return casted.getNameExpr();
+        }  else {
+            return node;
+        }
+    }
+
+    public static boolean nodeContains(Node container, Node contained, boolean ignoringAnnotations){
+        if (!ignoringAnnotations || PositionUtils.getLastAnnotation(container)==null){
+            return container.contains(contained);
+        }
+        if (!container.contains(contained)){
+            return false;
+        }
+        // if the node is contained, but it comes immediately after the annotations,
+        // let's not consider it contained
+        if (container instanceof AnnotableNode){
+            int bl = beginLineWithoutConsideringAnnotation(container);
+            int bc = beginColumnWithoutConsideringAnnotation(container);
+            if (bl>contained.getBeginLine()) return false;
+            if (bl==contained.getBeginLine() && bc>contained.getBeginColumn()) return false;
+            if (container.getEndLine()<contained.getEndLine()) return false;
+            if (container.getEndLine()==contained.getEndLine() && container.getEndColumn()<contained.getEndColumn()) return false;
+            return true;
+        }
+        return true;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/SourcesHelper.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/SourcesHelper.java
new file mode 100644
index 0000000..87f83f0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/SourcesHelper.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser;
+
+import java.io.*;
+
+public class SourcesHelper {
+
+    static String streamToString(InputStream in, String encoding){
+        if (encoding == null) {
+            return streamToString(in);
+        } else {
+            java.util.Scanner s = new java.util.Scanner(in, encoding).useDelimiter("\\A");
+            return s.hasNext() ? s.next() : "";
+        }
+    }
+
+    static String streamToString(InputStream in){
+        java.util.Scanner s = new java.util.Scanner(in).useDelimiter("\\A");
+        return s.hasNext() ? s.next() : "";
+    }
+
+    static InputStream stringToStream(String s, String encoding) throws UnsupportedEncodingException {
+        byte[] rawData = encoding != null ? s.getBytes(encoding) : s.getBytes();
+        return new ByteArrayInputStream(rawData);
+    }
+
+    static String readerToString(Reader reader) throws IOException {
+        char[] arr = new char[8*1024]; // 8K at a time
+        StringBuilder buf = new StringBuilder();
+        int numChars;
+
+        while ((numChars = reader.read(arr, 0, arr.length)) > 0) {
+            buf.append(arr, 0, numChars);
+        }
+
+        return buf.toString();
+    }
+
+    static Reader stringToReader(String s){
+        return new StringReader(s);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/AccessSpecifier.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/AccessSpecifier.java
new file mode 100644
index 0000000..5eafdac
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/AccessSpecifier.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+/**
+ * Access specifier. Represents one of the possible levels of
+ * access permitted by the language.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public enum AccessSpecifier {
+
+    PUBLIC("public"),
+    PRIVATE("private"),
+    PROTECTED("protected"),
+    DEFAULT("");
+
+    private String codeRepresenation;
+
+    private AccessSpecifier(String codeRepresentation) {
+        this.codeRepresenation = codeRepresentation;
+    }
+
+    public String getCodeRepresenation(){
+        return this.codeRepresenation;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/CompilationUnit.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/CompilationUnit.java
new file mode 100644
index 0000000..f3db302
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/CompilationUnit.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * <p>
+ * This class represents the entire compilation unit. Each java file denotes a
+ * compilation unit.
+ * </p>
+ * The CompilationUnit is constructed following the syntax:<br>
+ * <pre>
+ * {@code
+ * CompilationUnit ::=  ( }{@link PackageDeclaration}{@code )?
+ *                      ( }{@link ImportDeclaration}{@code )*
+ *                      ( }{@link TypeDeclaration}{@code )*
+ * }
+ * </pre>
+ * @author Julio Vilmar Gesser
+ */
+public final class CompilationUnit extends Node {
+
+    private PackageDeclaration pakage;
+
+    private List<ImportDeclaration> imports;
+
+    private List<TypeDeclaration> types;
+
+    public CompilationUnit() {
+    }
+
+    public CompilationUnit(PackageDeclaration pakage, List<ImportDeclaration> imports, List<TypeDeclaration> types) {
+        setPackage(pakage);
+        setImports(imports);
+        setTypes(types);
+    }
+
+    public CompilationUnit(int beginLine, int beginColumn, int endLine, int endColumn, PackageDeclaration pakage, List<ImportDeclaration> imports, List<TypeDeclaration> types) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setPackage(pakage);
+        setImports(imports);
+        setTypes(types);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return a list containing all comments declared in this compilation unit.
+     * Including javadocs, line comments and block comments of all types,
+     * inner-classes and other members.<br>
+     * If there is no comment, <code>null</code> is returned.
+     * 
+     * @return list with all comments of this compilation unit or
+     *         <code>null</code>
+     * @see JavadocComment
+     * @see com.github.javaparser.ast.comments.LineComment
+     * @see com.github.javaparser.ast.comments.BlockComment
+     */
+    public List<Comment> getComments() {
+        return this.getAllContainedComments();
+    }
+
+    /**
+     * Retrieves the list of imports declared in this compilation unit or
+     * <code>null</code> if there is no import.
+     * 
+     * @return the list of imports or <code>null</code> if there is no import
+     */
+    public List<ImportDeclaration> getImports() {
+        return imports;
+    }
+
+    /**
+     * Retrieves the package declaration of this compilation unit.<br>
+     * If this compilation unit has no package declaration (default package),
+     * <code>null</code> is returned.
+     * 
+     * @return the package declaration or <code>null</code>
+     */
+    public PackageDeclaration getPackage() {
+        return pakage;
+    }
+
+    /**
+     * Return the list of types declared in this compilation unit.<br>
+     * If there is no types declared, <code>null</code> is returned.
+     * 
+     * @return the list of types or <code>null</code> null if there is no type
+     * @see AnnotationDeclaration
+     * @see ClassOrInterfaceDeclaration
+     * @see EmptyTypeDeclaration
+     * @see EnumDeclaration
+     */
+    public List<TypeDeclaration> getTypes() {
+        return types;
+    }
+
+    /**
+     * Sets the list of comments of this compilation unit.
+     * 
+     * @param comments
+     *            the list of comments
+     */
+    public void setComments(List<Comment> comments) {
+        throw new RuntimeException("Not implemented!");
+    }
+
+    /**
+     * Sets the list of imports of this compilation unit. The list is initially
+     * <code>null</code>.
+     * 
+     * @param imports
+     *            the list of imports
+     */
+    public void setImports(List<ImportDeclaration> imports) {
+        this.imports = imports;
+		setAsParentNodeOf(this.imports);
+    }
+
+    /**
+     * Sets or clear the package declarations of this compilation unit.
+     * 
+     * @param pakage
+     *            the pakage declaration to set or <code>null</code> to default
+     *            package
+     */
+    public void setPackage(PackageDeclaration pakage) {
+        this.pakage = pakage;
+		setAsParentNodeOf(this.pakage);
+    }
+
+    /**
+     * Sets the list of types declared in this compilation unit.
+     * 
+     * @param types
+     *            the lis of types
+     */
+    public void setTypes(List<TypeDeclaration> types) {
+        this.types = types;
+		setAsParentNodeOf(this.types);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/DocumentableNode.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/DocumentableNode.java
new file mode 100644
index 0000000..0038831
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/DocumentableNode.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.comments.JavadocComment;
+
+/**
+ * Node which can be documented through a Javadoc comment.
+ */
+public interface DocumentableNode {
+
+    public JavadocComment getJavaDoc();
+    public void setJavaDoc(JavadocComment javadocComment);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/ImportDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/ImportDeclaration.java
new file mode 100644
index 0000000..da249e2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/ImportDeclaration.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * <p>
+ * This class represents a import declaration. Imports are optional for the
+ * {@link CompilationUnit}.
+ * </p>
+ * The ImportDeclaration is constructed following the syntax:<br>
+ * <pre>
+ * {@code
+ * ImportDeclaration ::= "import" ( "static" )? }{@link NameExpr}{@code ( "." "*" )? ";"
+ * }
+ * </pre>
+ * @author Julio Vilmar Gesser
+ */
+public final class ImportDeclaration extends Node {
+
+    private NameExpr name;
+
+    private boolean static_;
+
+    private boolean asterisk;
+
+    public ImportDeclaration() {
+    }
+
+    public ImportDeclaration(NameExpr name, boolean isStatic, boolean isAsterisk) {
+        setAsterisk(isAsterisk);
+        setName(name);
+        setStatic(isStatic);
+    }
+
+    public ImportDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, NameExpr name, boolean isStatic, boolean isAsterisk) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setAsterisk(isAsterisk);
+        setName(name);
+        setStatic(isStatic);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Retrieves the name of the import.
+     * 
+     * @return the name of the import
+     */
+    public NameExpr getName() {
+        return name;
+    }
+
+    /**
+     * Return if the import ends with "*".
+     * 
+     * @return <code>true</code> if the import ends with "*", <code>false</code>
+     *         otherwise
+     */
+    public boolean isAsterisk() {
+        return asterisk;
+    }
+
+    /**
+     * Return if the import is static.
+     * 
+     * @return <code>true</code> if the import is static, <code>false</code>
+     *         otherwise
+     */
+    public boolean isStatic() {
+        return static_;
+    }
+
+    /**
+     * Sets if this import is asterisk.
+     * 
+     * @param asterisk
+     *            <code>true</code> if this import is asterisk
+     */
+    public void setAsterisk(boolean asterisk) {
+        this.asterisk = asterisk;
+    }
+
+    /**
+     * Sets the name this import.
+     * 
+     * @param name
+     *            the name to set
+     */
+    public void setName(NameExpr name) {
+        this.name = name;
+        setAsParentNodeOf(this.name);
+    }
+
+    /**
+     * Sets if this import is static.
+     * 
+     * @param static_
+     *            <code>true</code> if this import is static
+     */
+    public void setStatic(boolean static_) {
+        this.static_ = static_;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/NamedNode.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/NamedNode.java
new file mode 100644
index 0000000..7885d71
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/NamedNode.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+/**
+ * A node having a name.
+ *  
+ * The main reason for this interface is to permit users to manipulate homogeneously all nodes with a getName method.
+ * 
+ * @since 2.0.1 
+ */
+public interface NamedNode {
+    String getName();
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/Node.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/Node.java
new file mode 100644
index 0000000..f5f9cb2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/Node.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.visitor.*;
+
+/**
+ * Abstract class for all nodes of the AST.
+ *
+ * Each Node can have one associated comment which describe it and
+ * a number of "orphan comments" which it contains but are not specifically
+ * associated to any element.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Node implements Cloneable {
+
+    private int beginLine;
+
+    private int beginColumn;
+
+    private int endLine;
+
+    private int endColumn;
+
+    private Node parentNode;
+
+    private List<Node> childrenNodes = new LinkedList<Node>();
+    private List<Comment> orphanComments = new LinkedList<Comment>();
+
+    /**
+     * This attribute can store additional information from semantic analysis.
+     */
+    private Object data;
+
+    private Comment comment;
+
+    public Node() {
+    }
+
+    public Node(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+        this.beginLine = beginLine;
+        this.beginColumn = beginColumn;
+        this.endLine = endLine;
+        this.endColumn = endColumn;
+    }
+
+    /**
+     * Accept method for visitor support.
+     * 
+     * @param <R>
+     *            the type the return value of the visitor
+     * @param <A>
+     *            the type the argument passed to the visitor
+     * @param v
+     *            the visitor implementation
+     * @param arg
+     *            the argument passed to the visitor
+     * @return the result of the visit
+     */
+    public abstract <R, A> R accept(GenericVisitor<R, A> v, A arg);
+
+    /**
+     * Accept method for visitor support.
+     * 
+     * @param <A>
+     *            the type the argument passed for the visitor
+     * @param v
+     *            the visitor implementation
+     * @param arg
+     *            any value relevant for the visitor
+     */
+    public abstract <A> void accept(VoidVisitor<A> v, A arg);
+
+    /**
+     * Return the begin column of this node.
+     * 
+     * @return the begin column of this node
+     */
+    public final int getBeginColumn() {
+        return beginColumn;
+    }
+
+    /**
+     * Return the begin line of this node.
+     * 
+     * @return the begin line of this node
+     */
+    public final int getBeginLine() {
+        return beginLine;
+    }
+
+    /**
+     * This is a comment associated with this node.
+     *
+     * @return comment property
+     */
+    public final Comment getComment() {
+        return comment;
+    }
+
+    /**
+     * Use this to retrieve additional information associated to this node.
+     *
+     * @return data property
+     */
+    public final Object getData() {
+        return data;
+    }
+
+    /**
+     * Return the end column of this node.
+     * 
+     * @return the end column of this node
+     */
+    public final int getEndColumn() {
+        return endColumn;
+    }
+
+    /**
+     * Return the end line of this node.
+     * 
+     * @return the end line of this node
+     */
+    public final int getEndLine() {
+        return endLine;
+    }
+
+    /**
+     * Sets the begin column of this node.
+     * 
+     * @param beginColumn
+     *            the begin column of this node
+     */
+    public final void setBeginColumn(final int beginColumn) {
+        this.beginColumn = beginColumn;
+    }
+
+    /**
+     * Sets the begin line of this node.
+     * 
+     * @param beginLine
+     *            the begin line of this node
+     */
+    public final void setBeginLine(final int beginLine) {
+        this.beginLine = beginLine;
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param comment to be set
+     */
+    public final void setComment(final Comment comment) {
+        if (comment != null && (this instanceof Comment)) {
+            throw new RuntimeException("A comment can not be commented");
+        }
+        if (this.comment != null)
+        {
+            this.comment.setCommentedNode(null);
+        }
+        this.comment = comment;
+        if (comment != null) {
+            this.comment.setCommentedNode(this);
+        }
+    }
+
+    /**
+     * Use this to store additional information to this node.
+     *
+     * @param data to be set
+     */
+    public final void setData(final Object data) {
+        this.data = data;
+    }
+
+    /**
+     * Sets the end column of this node.
+     * 
+     * @param endColumn
+     *            the end column of this node
+     */
+    public final void setEndColumn(final int endColumn) {
+        this.endColumn = endColumn;
+    }
+
+    /**
+     * Sets the end line of this node.
+     * 
+     * @param endLine
+     *            the end line of this node
+     */
+    public final void setEndLine(final int endLine) {
+        this.endLine = endLine;
+    }
+
+    /**
+     * Return the String representation of this node.
+     * 
+     * @return the String representation of this node
+     */
+    @Override
+    public final String toString() {
+        final DumpVisitor visitor = new DumpVisitor();
+        accept(visitor, null);
+        return visitor.getSource();
+    }
+
+    public final String toStringWithoutComments() {
+        final DumpVisitor visitor = new DumpVisitor(false);
+        accept(visitor, null);
+        return visitor.getSource();
+    }
+
+    @Override
+    public final int hashCode() {
+        return toString().hashCode();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (obj == null || !(obj instanceof Node)) {
+            return false;
+        }
+        return EqualsVisitor.equals(this, (Node) obj);
+    }
+
+    @Override
+    public Node clone() {
+        return this.accept(new CloneVisitor(), null);
+    }
+
+    public Node getParentNode() {
+        return parentNode;
+    }
+
+    public List<Node> getChildrenNodes() {
+        return childrenNodes;
+    }
+
+    public boolean contains(Node other) {
+        if (getBeginLine() > other.getBeginLine()) return false;
+        if (getBeginLine() == other.getBeginLine() && getBeginColumn() > other.getBeginColumn()) return false;
+        if (getEndLine() < other.getEndLine()) return false;
+        if (getEndLine() == other.getEndLine() && getEndColumn() < other.getEndColumn()) return false;
+        return true;
+    }
+
+    public void addOrphanComment(Comment comment) {
+        orphanComments.add(comment);
+        comment.setParentNode(this);
+    }
+
+    /**
+     * This is a list of Comment which are inside the node and are not associated
+     * with any meaningful AST Node.
+     *
+     * For example, comments at the end of methods (immediately before the parenthesis)
+     * or at the end of CompilationUnit are orphan comments.
+     *
+     * When more than one comments preceed a statement, the one immediately preceeding it
+     * it is associated with the statements, while the others are "orphan".
+     * @return all comments that cannot be attributed to a concept
+     */
+    public List<Comment> getOrphanComments() {
+        return orphanComments;
+    }
+
+    /**
+     * This is the list of Comment which are contained in the Node either because
+     * they are properly associated to one of its children or because they are floating
+     * around inside the Node
+     * @return all Comments within the node as a list
+     */
+    public List<Comment> getAllContainedComments() {
+        List<Comment> comments = new LinkedList<Comment>();
+        comments.addAll(getOrphanComments());
+
+        for (Node child : getChildrenNodes()) {
+            if (child.getComment() != null) {
+                comments.add(child.getComment());
+            }
+            comments.addAll(child.getAllContainedComments());
+        }
+
+        return comments;
+    }
+
+    /**
+     * Assign a new parent to this node, removing it
+     * from the list of children of the previous parent, if any.
+     *
+     * @param parentNode node to be set as parent
+     */
+    public void setParentNode(Node parentNode) {
+        // remove from old parent, if any
+        if (this.parentNode != null) {
+            this.parentNode.childrenNodes.remove(this);
+        }
+        this.parentNode = parentNode;
+        // add to new parent, if any
+        if (this.parentNode != null) {
+            this.parentNode.childrenNodes.add(this);
+        }
+    }
+
+    protected void setAsParentNodeOf(List<? extends Node> childNodes) {
+        if (childNodes != null) {
+            Iterator<? extends Node> it = childNodes.iterator();
+            while (it.hasNext()) {
+                Node current = it.next();
+                current.setParentNode(this);
+            }
+        }
+    }
+
+    protected void setAsParentNodeOf(Node childNode) {
+        if (childNode != null) {
+            childNode.setParentNode(this);
+        }
+    }
+
+    public static final int ABSOLUTE_BEGIN_LINE = -1;
+    public static final int ABSOLUTE_END_LINE = -2;
+
+    public boolean isPositionedAfter(int line, int column) {
+        if (line == ABSOLUTE_BEGIN_LINE) return true;
+        if (getBeginLine() > line) {
+            return true;
+        } else if (getBeginLine() == line) {
+            return getBeginColumn() > column;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean isPositionedBefore(int line, int column) {
+        if (line == ABSOLUTE_END_LINE) return true;
+        if (getEndLine() < line) {
+            return true;
+        } else if (getEndLine() == line) {
+            return getEndColumn() < column;
+        } else {
+            return false;
+        }
+    }
+
+    public boolean hasComment()
+    {
+        return comment != null;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/PackageDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/PackageDeclaration.java
new file mode 100644
index 0000000..d0aaf5b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/PackageDeclaration.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * <p>
+ * This class represents the package declaration. The package declaration is
+ * optional for the {@link CompilationUnit}.
+ * </p>
+ * The PackageDeclaration is constructed following the syntax:<br>
+ * <pre>
+ * {@code
+ * PackageDeclaration ::= ( }{@link AnnotationExpr}{@code )* "package" }{@link NameExpr}{@code ) ";"
+ * }
+ * </pre>
+ * @author Julio Vilmar Gesser
+ */
+public final class PackageDeclaration extends Node {
+
+    private List<AnnotationExpr> annotations;
+
+    private NameExpr name;
+
+    public PackageDeclaration() {
+    }
+
+    public PackageDeclaration(NameExpr name) {
+        setName(name);
+    }
+
+    public PackageDeclaration(List<AnnotationExpr> annotations, NameExpr name) {
+        setAnnotations(annotations);
+        setName(name);
+    }
+
+    public PackageDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, List<AnnotationExpr> annotations, NameExpr name) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setAnnotations(annotations);
+        setName(name);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Retrieves the list of annotations declared before the package
+     * declaration. Return <code>null</code> if there are no annotations.
+     * 
+     * @return list of annotations or <code>null</code>
+     */
+    public List<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    /**
+     * Return the name of the package.
+     * 
+     * @return the name of the package
+     */
+    public NameExpr getName() {
+        return name;
+    }
+
+    /**
+     * @param annotations
+     *            the annotations to set
+     */
+    public void setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+        setAsParentNodeOf(this.annotations);
+    }
+
+    /**
+     * Sets the name of this package declaration.
+     * 
+     * @param name
+     *            the name to set
+     */
+    public void setName(NameExpr name) {
+        this.name = name;
+        setAsParentNodeOf(this.name);
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/TreeVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/TreeVisitor.java
new file mode 100644
index 0000000..f3b2672
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/TreeVisitor.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+public abstract class TreeVisitor {
+
+    public void visitDepthFirst(Node node){
+        process(node);
+        for (Node child : node.getChildrenNodes()){
+            visitDepthFirst(child);
+        }
+    }
+
+    public abstract void process(Node node);
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/TypeParameter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/TypeParameter.java
new file mode 100644
index 0000000..c43d379
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/TypeParameter.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * <p>
+ * This class represents the declaration of a generics argument.
+ * </p>
+ * The TypeParameter is constructed following the syntax:<br>
+ * <pre>
+ * {@code
+ * TypeParameter ::= <IDENTIFIER> ( "extends" }{@link ClassOrInterfaceType}{@code ( "&" }{@link ClassOrInterfaceType}{@code )* )?
+ * }
+ * </pre>
+ * @author Julio Vilmar Gesser
+ */
+public final class TypeParameter extends Node implements NamedNode {
+
+	private String name;
+
+    private List<AnnotationExpr> annotations;
+
+	private List<ClassOrInterfaceType> typeBound;
+
+	public TypeParameter() {
+	}
+
+	public TypeParameter(final String name, final List<ClassOrInterfaceType> typeBound) {
+		setName(name);
+		setTypeBound(typeBound);
+	}
+
+	public TypeParameter(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String name, final List<ClassOrInterfaceType> typeBound) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setName(name);
+		setTypeBound(typeBound);
+	}
+
+    public TypeParameter(int beginLine, int beginColumn, int endLine,
+                         int endColumn, String name, List<ClassOrInterfaceType> typeBound, List<AnnotationExpr> annotations) {
+        this(beginLine, beginColumn, endLine, endColumn, name, typeBound);
+        setName(name);
+        setTypeBound(typeBound);
+        this.annotations = annotations;
+    }
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	/**
+	 * Return the name of the paramenter.
+	 * 
+	 * @return the name of the paramenter
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Return the list of {@link ClassOrInterfaceType} that this parameter
+	 * extends. Return <code>null</code> null if there are no type.
+	 * 
+	 * @return list of types that this paramente extends or <code>null</code>
+	 */
+	public List<ClassOrInterfaceType> getTypeBound() {
+		return typeBound;
+	}
+
+	/**
+	 * Sets the name of this type parameter.
+	 * 
+	 * @param name
+	 *            the name to set
+	 */
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	/**
+	 * Sets the list o types.
+	 * 
+	 * @param typeBound
+	 *            the typeBound to set
+	 */
+	public void setTypeBound(final List<ClassOrInterfaceType> typeBound) {
+		this.typeBound = typeBound;
+		setAsParentNodeOf(typeBound);
+	}
+
+    public List<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    public void setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotableNode.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotableNode.java
new file mode 100644
index 0000000..47c8c4f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotableNode.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+
+import java.util.List;
+
+/**
+ * An element which can be the target of annotations.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public interface AnnotableNode {
+    public List<AnnotationExpr> getAnnotations();
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotationDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotationDeclaration.java
new file mode 100644
index 0000000..51f2561
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotationDeclaration.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AnnotationDeclaration extends TypeDeclaration implements DocumentableNode {
+
+    public AnnotationDeclaration() {
+    }
+
+    public AnnotationDeclaration(int modifiers, String name) {
+        super(modifiers, name);
+    }
+
+    public AnnotationDeclaration(int modifiers, List<AnnotationExpr> annotations, String name, List<BodyDeclaration> members) {
+        super(annotations, modifiers, name, members);
+    }
+
+    public AnnotationDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, String name, List<BodyDeclaration> members) {
+        super(beginLine, beginColumn, endLine, endColumn, annotations, modifiers, name, members);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java
new file mode 100644
index 0000000..a81e6cc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/AnnotationMemberDeclaration.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AnnotationMemberDeclaration extends BodyDeclaration implements DocumentableNode, NamedNode {
+
+    private int modifiers;
+
+    private Type type;
+
+    private String name;
+
+    private Expression defaultValue;
+
+    public AnnotationMemberDeclaration() {
+    }
+
+    public AnnotationMemberDeclaration(int modifiers, Type type, String name, Expression defaultValue) {
+        setModifiers(modifiers);
+        setType(type);
+        setName(name);
+        setDefaultValue(defaultValue);
+    }
+
+    public AnnotationMemberDeclaration(int modifiers, List<AnnotationExpr> annotations, Type type, String name, Expression defaultValue) {
+        super(annotations);
+        setModifiers(modifiers);
+        setType(type);
+        setName(name);
+        setDefaultValue(defaultValue);
+    }
+
+    public AnnotationMemberDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, Type type, String name, Expression defaultValue) {
+        super(beginLine, beginColumn, endLine, endColumn, annotations);
+        setModifiers(modifiers);
+        setType(type);
+        setName(name);
+        setDefaultValue(defaultValue);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getDefaultValue() {
+        return defaultValue;
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     * 
+     * @see ModifierSet
+     * @return modifiers
+     */
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public void setDefaultValue(Expression defaultValue) {
+        this.defaultValue = defaultValue;
+        setAsParentNodeOf(defaultValue);
+    }
+
+    public void setModifiers(int modifiers) {
+        this.modifiers = modifiers;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+        setAsParentNodeOf(type);
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/BaseParameter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/BaseParameter.java
new file mode 100644
index 0000000..e14deb1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/BaseParameter.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+
+import java.util.List;
+
+public abstract class BaseParameter extends Node {
+    private int modifiers;
+
+    private List<AnnotationExpr> annotations;
+    
+    private VariableDeclaratorId id;
+    
+    public BaseParameter() {
+    }
+    
+    public BaseParameter(VariableDeclaratorId id) {
+        setId(id);
+	}
+
+	public BaseParameter(int modifiers, VariableDeclaratorId id) {
+        setModifiers(modifiers);
+        setId(id);
+	}
+	
+	public BaseParameter(int modifiers, List<AnnotationExpr> annotations, VariableDeclaratorId id) {
+        setModifiers(modifiers);
+        setAnnotations(annotations);
+        setId(id);
+	}
+
+	public BaseParameter(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, VariableDeclaratorId id) {
+	    super(beginLine, beginColumn, endLine, endColumn);
+        setModifiers(modifiers);
+        setAnnotations(annotations);
+        setId(id);
+	}
+
+    public List<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    public VariableDeclaratorId getId() {
+        return id;
+    }
+
+    /**
+     * Return the modifiers of this parameter declaration.
+     * 
+     * @see ModifierSet
+     * @return modifiers
+     */
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public void setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+        setAsParentNodeOf(this.annotations);
+    }
+
+    public void setId(VariableDeclaratorId id) {
+        this.id = id;
+        setAsParentNodeOf(this.id);
+    }
+
+    public void setModifiers(int modifiers) {
+        this.modifiers = modifiers;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/BodyDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/BodyDeclaration.java
new file mode 100644
index 0000000..bbf138b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/BodyDeclaration.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class BodyDeclaration extends Node implements AnnotableNode {
+
+    private List<AnnotationExpr> annotations;
+
+    public BodyDeclaration() {
+    }
+
+    public BodyDeclaration(List<AnnotationExpr> annotations) {
+    	setAnnotations(annotations);
+    }
+
+    public BodyDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, List<AnnotationExpr> annotations) {
+        super(beginLine, beginColumn, endLine, endColumn);
+    	setAnnotations(annotations);
+    }
+
+    public final List<AnnotationExpr> getAnnotations() {
+        if (annotations==null){
+            annotations = new ArrayList<AnnotationExpr>();
+        }
+        return annotations;
+    }
+
+    public final void setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+		setAsParentNodeOf(this.annotations);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java
new file mode 100644
index 0000000..e098f6e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ClassOrInterfaceDeclaration.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassOrInterfaceDeclaration extends TypeDeclaration implements DocumentableNode {
+
+	private boolean interface_;
+
+	private List<TypeParameter> typeParameters;
+
+	// Can contain more than one item if this is an interface
+	private List<ClassOrInterfaceType> extendsList;
+
+	private List<ClassOrInterfaceType> implementsList;
+
+	public ClassOrInterfaceDeclaration() {
+	}
+
+	public ClassOrInterfaceDeclaration(final int modifiers, final boolean isInterface, final String name) {
+		super(modifiers, name);
+		setInterface(isInterface);
+	}
+
+	public ClassOrInterfaceDeclaration(final int modifiers,
+			final List<AnnotationExpr> annotations, final boolean isInterface, final String name,
+			final List<TypeParameter> typeParameters, final List<ClassOrInterfaceType> extendsList,
+			final List<ClassOrInterfaceType> implementsList, final List<BodyDeclaration> members) {
+		super(annotations, modifiers, name, members);
+		setInterface(isInterface);
+		setTypeParameters(typeParameters);
+		setExtends(extendsList);
+		setImplements(implementsList);
+	}
+
+	public ClassOrInterfaceDeclaration(final int beginLine, final int beginColumn, final int endLine,
+			final int endColumn, final int modifiers,
+			final List<AnnotationExpr> annotations, final boolean isInterface, final String name,
+			final List<TypeParameter> typeParameters, final List<ClassOrInterfaceType> extendsList,
+			final List<ClassOrInterfaceType> implementsList, final List<BodyDeclaration> members) {
+		super(beginLine, beginColumn, endLine, endColumn, annotations, modifiers, name, members);
+		setInterface(isInterface);
+		setTypeParameters(typeParameters);
+		setExtends(extendsList);
+		setImplements(implementsList);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<ClassOrInterfaceType> getExtends() {
+		return extendsList;
+	}
+
+	public List<ClassOrInterfaceType> getImplements() {
+		return implementsList;
+	}
+
+	public List<TypeParameter> getTypeParameters() {
+		return typeParameters;
+	}
+
+    public boolean isInterface() {
+		return interface_;
+	}
+
+	public void setExtends(final List<ClassOrInterfaceType> extendsList) {
+		this.extendsList = extendsList;
+		setAsParentNodeOf(this.extendsList);
+	}
+
+	public void setImplements(final List<ClassOrInterfaceType> implementsList) {
+		this.implementsList = implementsList;
+		setAsParentNodeOf(this.implementsList);
+	}
+
+	public void setInterface(final boolean interface_) {
+		this.interface_ = interface_;
+	}
+
+	public void setTypeParameters(final List<TypeParameter> typeParameters) {
+		this.typeParameters = typeParameters;
+		setAsParentNodeOf(this.typeParameters);
+	}
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ConstructorDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ConstructorDeclaration.java
new file mode 100644
index 0000000..892810c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ConstructorDeclaration.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ConstructorDeclaration extends BodyDeclaration implements DocumentableNode, WithDeclaration,
+        NamedNode {
+
+    private int modifiers;
+
+    private List<TypeParameter> typeParameters;
+
+    private NameExpr name;
+
+    private List<Parameter> parameters;
+
+    private List<NameExpr> throws_;
+
+    private BlockStmt block;
+
+    public ConstructorDeclaration() {
+    }
+
+    public ConstructorDeclaration(int modifiers, String name) {
+        setModifiers(modifiers);
+        setName(name);
+    }
+
+    public ConstructorDeclaration(int modifiers, List<AnnotationExpr> annotations, List<TypeParameter> typeParameters,
+                                  String name, List<Parameter> parameters, List<NameExpr> throws_, BlockStmt block) {
+        super(annotations);
+        setModifiers(modifiers);
+        setTypeParameters(typeParameters);
+        setName(name);
+        setParameters(parameters);
+        setThrows(throws_);
+        setBlock(block);
+    }
+
+    public ConstructorDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers,
+                                  List<AnnotationExpr> annotations, List<TypeParameter> typeParameters, String name,
+                                  List<Parameter> parameters, List<NameExpr> throws_, BlockStmt block) {
+        super(beginLine, beginColumn, endLine, endColumn, annotations);
+        setModifiers(modifiers);
+        setTypeParameters(typeParameters);
+        setName(name);
+        setParameters(parameters);
+        setThrows(throws_);
+        setBlock(block);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public BlockStmt getBlock() {
+        return block;
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     * 
+     * @see ModifierSet
+     * @return modifiers
+     */
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public String getName() {
+        return name == null ? null : name.getName();
+    }
+
+    public NameExpr getNameExpr() {
+        return name;
+    }
+
+    public List<Parameter> getParameters() {
+        if (parameters == null) {
+            parameters = new ArrayList<Parameter>();
+        }
+        return parameters;
+    }
+
+    public List<NameExpr> getThrows() {
+        if (throws_ == null) {
+            throws_ = new ArrayList<NameExpr>();
+        }
+        return throws_;
+    }
+
+    public List<TypeParameter> getTypeParameters() {
+        return typeParameters;
+    }
+
+    public void setBlock(BlockStmt block) {
+        this.block = block;
+        setAsParentNodeOf(this.block);
+    }
+
+    public void setModifiers(int modifiers) {
+        this.modifiers = modifiers;
+    }
+
+    public void setName(String name) {
+        this.name = new NameExpr(name);
+    }
+
+    public void setNameExpr(NameExpr name) {
+        this.name = name;
+    }
+
+    public void setParameters(List<Parameter> parameters) {
+        this.parameters = parameters;
+        setAsParentNodeOf(this.parameters);
+    }
+
+    public void setThrows(List<NameExpr> throws_) {
+        this.throws_ = throws_;
+        setAsParentNodeOf(this.throws_);
+    }
+
+    public void setTypeParameters(List<TypeParameter> typeParameters) {
+        this.typeParameters = typeParameters;
+        setAsParentNodeOf(this.typeParameters);
+    }
+
+    /**
+     * The declaration returned has this schema:
+     *
+     * [accessSpecifier] className ([paramType [paramName]])
+     * [throws exceptionsList]
+     */
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows,
+                                         boolean includingParameterName) {
+        StringBuffer sb = new StringBuffer();
+        if (includingModifiers) {
+            AccessSpecifier accessSpecifier = ModifierSet.getAccessSpecifier(getModifiers());
+            sb.append(accessSpecifier.getCodeRepresenation());
+            sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ");
+        }
+        sb.append(getName());
+        sb.append("(");
+        boolean firstParam = true;
+        for (Parameter param : getParameters())
+        {
+            if (firstParam) {
+                firstParam = false;
+            } else {
+                sb.append(", ");
+            }
+            if (includingParameterName) {
+                sb.append(param.toStringWithoutComments());
+            } else {
+                sb.append(param.getType().toStringWithoutComments());
+            }
+        }
+        sb.append(")");
+        if (includingThrows) {
+            boolean firstThrow = true;
+            for (NameExpr thr : getThrows()) {
+                if (firstThrow) {
+                    firstThrow = false;
+                    sb.append(" throws ");
+                } else {
+                    sb.append(", ");
+                }
+                sb.append(thr.toStringWithoutComments());
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows) {
+        return getDeclarationAsString(includingModifiers, includingThrows, true);
+    }
+
+    @Override
+    public String getDeclarationAsString() {
+        return getDeclarationAsString(true, true, true);
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EmptyMemberDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EmptyMemberDeclaration.java
new file mode 100644
index 0000000..1c19d09
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EmptyMemberDeclaration.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EmptyMemberDeclaration extends BodyDeclaration implements DocumentableNode {
+
+    public EmptyMemberDeclaration() {
+        super(null);
+    }
+
+    public EmptyMemberDeclaration(int beginLine, int beginColumn, int endLine, int endColumn) {
+        super(beginLine, beginColumn, endLine, endColumn, null);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EmptyTypeDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EmptyTypeDeclaration.java
new file mode 100644
index 0000000..59e8686
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EmptyTypeDeclaration.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EmptyTypeDeclaration extends TypeDeclaration implements DocumentableNode {
+
+    public EmptyTypeDeclaration() {
+        super(null, 0, null, null);
+    }
+
+    public EmptyTypeDeclaration(int beginLine, int beginColumn, int endLine, int endColumn) {
+        super(beginLine, beginColumn, endLine, endColumn, null, 0, null, null);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EnumConstantDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EnumConstantDeclaration.java
new file mode 100644
index 0000000..d7c425c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EnumConstantDeclaration.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EnumConstantDeclaration extends BodyDeclaration implements DocumentableNode, NamedNode {
+
+    private String name;
+
+    private List<Expression> args;
+
+    private List<BodyDeclaration> classBody;
+
+    public EnumConstantDeclaration() {
+    }
+
+    public EnumConstantDeclaration(String name) {
+        setName(name);
+    }
+
+    public EnumConstantDeclaration(List<AnnotationExpr> annotations, String name, List<Expression> args, List<BodyDeclaration> classBody) {
+        super(annotations);
+        setName(name);
+        setArgs(args);
+        setClassBody(classBody);
+    }
+
+    public EnumConstantDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, List<AnnotationExpr> annotations, String name, List<Expression> args, List<BodyDeclaration> classBody) {
+        super(beginLine, beginColumn, endLine, endColumn, annotations);
+        setName(name);
+        setArgs(args);
+        setClassBody(classBody);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<Expression> getArgs() {
+        return args;
+    }
+
+    public List<BodyDeclaration> getClassBody() {
+        return classBody;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setArgs(List<Expression> args) {
+        this.args = args;
+		setAsParentNodeOf(this.args);
+    }
+
+    public void setClassBody(List<BodyDeclaration> classBody) {
+        this.classBody = classBody;
+		setAsParentNodeOf(this.classBody);
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EnumDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EnumDeclaration.java
new file mode 100644
index 0000000..34b8ee4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/EnumDeclaration.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EnumDeclaration extends TypeDeclaration implements DocumentableNode {
+
+    private List<ClassOrInterfaceType> implementsList;
+
+    private List<EnumConstantDeclaration> entries;
+
+    public EnumDeclaration() {
+    }
+
+    public EnumDeclaration(int modifiers, String name) {
+        super(modifiers, name);
+    }
+
+    public EnumDeclaration(int modifiers, List<AnnotationExpr> annotations, String name, List<ClassOrInterfaceType> implementsList, List<EnumConstantDeclaration> entries, List<BodyDeclaration> members) {
+        super(annotations, modifiers, name, members);
+        setImplements(implementsList);
+        setEntries(entries);
+    }
+
+    public EnumDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, String name, List<ClassOrInterfaceType> implementsList, List<EnumConstantDeclaration> entries, List<BodyDeclaration> members) {
+        super(beginLine, beginColumn, endLine, endColumn, annotations, modifiers, name, members);
+        setImplements(implementsList);
+        setEntries(entries);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<EnumConstantDeclaration> getEntries() {
+        return entries;
+    }
+
+    public List<ClassOrInterfaceType> getImplements() {
+        return implementsList;
+    }
+
+    public void setEntries(List<EnumConstantDeclaration> entries) {
+        this.entries = entries;
+		setAsParentNodeOf(this.entries);
+    }
+
+    public void setImplements(List<ClassOrInterfaceType> implementsList) {
+        this.implementsList = implementsList;
+		setAsParentNodeOf(this.implementsList);
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/FieldDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/FieldDeclaration.java
new file mode 100644
index 0000000..2f48ed8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/FieldDeclaration.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class FieldDeclaration extends BodyDeclaration implements DocumentableNode {
+
+    private int modifiers;
+
+    private Type type;
+
+    private List<VariableDeclarator> variables;
+
+    public FieldDeclaration() {
+    }
+
+    public FieldDeclaration(int modifiers, Type type, VariableDeclarator variable) {
+    	setModifiers(modifiers);
+    	setType(type);
+    	List<VariableDeclarator> aux = new ArrayList<VariableDeclarator>();
+    	aux.add(variable);
+    	setVariables(aux);
+    }
+
+    public FieldDeclaration(int modifiers, Type type, List<VariableDeclarator> variables) {
+    	setModifiers(modifiers);
+    	setType(type);
+    	setVariables(variables);
+    }
+
+    public FieldDeclaration(int modifiers, List<AnnotationExpr> annotations, Type type, List<VariableDeclarator> variables) {
+        super(annotations);
+        setModifiers(modifiers);
+    	setType(type);
+    	setVariables(variables);
+    }
+
+    public FieldDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, Type type, List<VariableDeclarator> variables) {
+        super(beginLine, beginColumn, endLine, endColumn, annotations);
+        setModifiers(modifiers);
+    	setType(type);
+    	setVariables(variables);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    /**
+     * Return the modifiers of this member declaration.
+     * 
+     * @see ModifierSet
+     * @return modifiers
+     */
+    public int getModifiers() {
+        return modifiers;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public List<VariableDeclarator> getVariables() {
+        return variables;
+    }
+
+    public void setModifiers(int modifiers) {
+        this.modifiers = modifiers;
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+    }
+
+    public void setVariables(List<VariableDeclarator> variables) {
+        this.variables = variables;
+		setAsParentNodeOf(this.variables);
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/InitializerDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/InitializerDeclaration.java
new file mode 100644
index 0000000..ea1df9a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/InitializerDeclaration.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class InitializerDeclaration extends BodyDeclaration implements DocumentableNode {
+
+    private boolean isStatic;
+
+    private BlockStmt block;
+
+    public InitializerDeclaration() {
+    }
+
+    public InitializerDeclaration(boolean isStatic, BlockStmt block) {
+        super(null);
+        setStatic(isStatic);
+        setBlock(block);
+    }
+
+    public InitializerDeclaration(int beginLine, int beginColumn, int endLine, int endColumn, boolean isStatic, BlockStmt block) {
+        super(beginLine, beginColumn, endLine, endColumn, null);
+        setStatic(isStatic);
+        setBlock(block);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public BlockStmt getBlock() {
+        return block;
+    }
+
+    public boolean isStatic() {
+        return isStatic;
+    }
+
+    public void setBlock(BlockStmt block) {
+        this.block = block;
+		setAsParentNodeOf(this.block);
+    }
+
+    public void setStatic(boolean isStatic) {
+        this.isStatic = isStatic;
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/MethodDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/MethodDeclaration.java
new file mode 100644
index 0000000..7f9ca0b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/MethodDeclaration.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AccessSpecifier;
+import com.github.javaparser.ast.DocumentableNode;
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MethodDeclaration extends BodyDeclaration implements DocumentableNode, WithDeclaration, NamedNode {
+
+	private int modifiers;
+
+	private List<TypeParameter> typeParameters;
+
+	private Type type;
+
+	private NameExpr name;
+
+	private List<Parameter> parameters;
+
+	private int arrayCount;
+
+	private List<NameExpr> throws_;
+
+	private BlockStmt body;
+
+    private boolean isDefault = false;
+
+    public MethodDeclaration() {
+	}
+
+	public MethodDeclaration(final int modifiers, final Type type, final String name) {
+		setModifiers(modifiers);
+		setType(type);
+		setName(name);
+	}
+
+	public MethodDeclaration(final int modifiers, final Type type, final String name, final List<Parameter> parameters) {
+		setModifiers(modifiers);
+		setType(type);
+		setName(name);
+		setParameters(parameters);
+	}
+
+	public MethodDeclaration(final int modifiers, final List<AnnotationExpr> annotations,
+			final List<TypeParameter> typeParameters, final Type type, final String name,
+			final List<Parameter> parameters, final int arrayCount, final List<NameExpr> throws_, final BlockStmt block) {
+		super(annotations);
+		setModifiers(modifiers);
+		setTypeParameters(typeParameters);
+		setType(type);
+		setName(name);
+		setParameters(parameters);
+		setArrayCount(arrayCount);
+		setThrows(throws_);
+		setBody(block);
+	}
+
+	public MethodDeclaration(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final int modifiers, final List<AnnotationExpr> annotations,
+			final List<TypeParameter> typeParameters, final Type type, final String name,
+			final List<Parameter> parameters, final int arrayCount, final List<NameExpr> throws_, final BlockStmt block) {
+		super(beginLine, beginColumn, endLine, endColumn, annotations);
+		setModifiers(modifiers);
+		setTypeParameters(typeParameters);
+		setType(type);
+		setName(name);
+		setParameters(parameters);
+		setArrayCount(arrayCount);
+		setThrows(throws_);
+		setBody(block);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public int getArrayCount() {
+		return arrayCount;
+	}
+
+	// FIXME this is called "Block" in the constructor. Pick one.
+	public BlockStmt getBody() {
+		return body;
+	}
+
+	/**
+	 * Return the modifiers of this member declaration.
+	 * 
+	 * @see ModifierSet
+	 * @return modifiers
+	 */
+	public int getModifiers() {
+		return modifiers;
+	}
+
+	public String getName() {
+		return name.getName();
+	}
+
+    public NameExpr getNameExpr() {
+        return name;
+    }
+
+	public List<Parameter> getParameters() {
+        if (parameters == null) {
+            parameters = new ArrayList<Parameter>();
+        }
+		return parameters;
+	}
+
+	public List<NameExpr> getThrows() {
+        if (throws_ == null) {
+            throws_ = new ArrayList<NameExpr>();
+        }
+		return throws_;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public List<TypeParameter> getTypeParameters() {
+		return typeParameters;
+	}
+
+	public void setArrayCount(final int arrayCount) {
+		this.arrayCount = arrayCount;
+	}
+
+	public void setBody(final BlockStmt body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+	}
+
+	public void setModifiers(final int modifiers) {
+		this.modifiers = modifiers;
+	}
+
+	public void setName(final String name) {
+		this.name = new NameExpr(name);
+	}
+
+    public void setNameExpr(final NameExpr name) {
+        this.name = name;
+    }
+
+    public void setParameters(final List<Parameter> parameters) {
+		this.parameters = parameters;
+		setAsParentNodeOf(this.parameters);
+	}
+
+	public void setThrows(final List<NameExpr> throws_) {
+		this.throws_ = throws_;
+		setAsParentNodeOf(this.throws_);
+	}
+
+	public void setType(final Type type) {
+		this.type = type;
+		setAsParentNodeOf(this.type);
+	}
+
+	public void setTypeParameters(final List<TypeParameter> typeParameters) {
+		this.typeParameters = typeParameters;
+		setAsParentNodeOf(typeParameters);
+	}
+
+
+    public boolean isDefault() {
+        return isDefault;
+    }
+
+    public void setDefault(boolean isDefault) {
+        this.isDefault = isDefault;
+    }
+
+
+    @Override
+    public String getDeclarationAsString() {
+        return getDeclarationAsString(true, true, true);
+    }
+
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows) {
+        return getDeclarationAsString(includingModifiers, includingThrows, true);
+    }
+    
+    /**
+     * The declaration returned has this schema:
+     *
+     * [accessSpecifier] [static] [abstract] [final] [native]
+     * [synchronized] returnType methodName ([paramType [paramName]])
+     * [throws exceptionsList]
+     * @return method declaration as String
+     */
+    @Override
+    public String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName) {
+        StringBuffer sb = new StringBuffer();
+        if (includingModifiers) {
+            AccessSpecifier accessSpecifier = ModifierSet.getAccessSpecifier(getModifiers());
+            sb.append(accessSpecifier.getCodeRepresenation());
+            sb.append(accessSpecifier == AccessSpecifier.DEFAULT ? "" : " ");
+            if (ModifierSet.isStatic(getModifiers())){
+                sb.append("static ");
+            }
+            if (ModifierSet.isAbstract(getModifiers())){
+                sb.append("abstract ");
+            }
+            if (ModifierSet.isFinal(getModifiers())){
+                sb.append("final ");
+            }
+            if (ModifierSet.isNative(getModifiers())){
+                sb.append("native ");
+            }
+            if (ModifierSet.isSynchronized(getModifiers())){
+                sb.append("synchronized ");
+            }
+        }
+        // TODO verify it does not print comments connected to the type
+        sb.append(getType().toStringWithoutComments());
+        sb.append(" ");
+        sb.append(getName());
+        sb.append("(");
+        boolean firstParam = true;
+        for (Parameter param : getParameters())
+        {
+            if (firstParam) {
+                firstParam = false;
+            } else {
+                sb.append(", ");
+            }
+            if (includingParameterName) {
+                sb.append(param.toStringWithoutComments());
+            } else {
+                sb.append(param.getType().toStringWithoutComments());
+                if (param.isVarArgs()) {
+                	sb.append("...");
+                }
+            }
+        }
+        sb.append(")");
+        if (includingThrows) {
+            boolean firstThrow = true;
+            for (NameExpr thr : getThrows()) {
+                if (firstThrow) {
+                    firstThrow = false;
+                    sb.append(" throws ");
+                } else {
+                    sb.append(", ");
+                }
+                sb.append(thr.toStringWithoutComments());
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public void setJavaDoc(JavadocComment javadocComment) {
+        this.javadocComment = javadocComment;
+    }
+
+    @Override
+    public JavadocComment getJavaDoc() {
+        return javadocComment;
+    }
+
+    private JavadocComment javadocComment;
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ModifierSet.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ModifierSet.java
new file mode 100644
index 0000000..6981ced
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/ModifierSet.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.AccessSpecifier;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Class to hold modifiers.<br>
+ * The modifier constants declared here holds equivalent values to
+ * {@link Modifier} constants.
+ */
+public final class ModifierSet {
+
+    /* Definitions of the bits in the modifiers field.  */
+
+    public static final int PUBLIC = Modifier.PUBLIC;
+
+    public static final int PRIVATE = Modifier.PRIVATE;
+
+    public static final int PROTECTED = Modifier.PROTECTED;
+
+    public static final int STATIC = Modifier.STATIC;
+
+    public static final int FINAL = Modifier.FINAL;
+
+    public static final int SYNCHRONIZED = Modifier.SYNCHRONIZED;
+
+    public static final int VOLATILE = Modifier.VOLATILE;
+
+    public static final int TRANSIENT = Modifier.TRANSIENT;
+
+    public static final int NATIVE = Modifier.NATIVE;
+
+    public static final int ABSTRACT = Modifier.ABSTRACT;
+
+    public static final int STRICTFP = Modifier.STRICT;
+
+    public static AccessSpecifier getAccessSpecifier(int modifiers) {
+        if (isPublic(modifiers)){
+            return AccessSpecifier.PUBLIC;
+        } else if (isProtected(modifiers)){
+            return AccessSpecifier.PROTECTED;
+        } else if (isPrivate(modifiers)){
+            return AccessSpecifier.PRIVATE;
+        } else {
+            return AccessSpecifier.DEFAULT;
+        }
+    }
+
+    public static int addModifier(int modifiers, int mod) {
+        return modifiers | mod;
+    }
+
+    public static boolean hasModifier(int modifiers, int modifier) {
+        return (modifiers & modifier) != 0;
+    }
+
+    public static boolean isAbstract(int modifiers) {
+        return (modifiers & ABSTRACT) != 0;
+    }
+
+    public static boolean isFinal(int modifiers) {
+        return (modifiers & FINAL) != 0;
+    }
+
+    public static boolean isNative(int modifiers) {
+        return (modifiers & NATIVE) != 0;
+    }
+
+    public static boolean isPrivate(int modifiers) {
+        return (modifiers & PRIVATE) != 0;
+    }
+
+    public static boolean isProtected(int modifiers) {
+        return (modifiers & PROTECTED) != 0;
+    }
+
+    /**
+     * Is the element accessible from within the package?
+     * It is the level of access which is applied if no modifiers are chosen,
+     * it is sometimes called "default".
+     * @param modifiers indicator
+     * @return true if modifier denotes package level access
+     */
+    public static boolean hasPackageLevelAccess(int modifiers) {
+        return !isPublic(modifiers) && !isProtected(modifiers) && !isPrivate(modifiers);
+    }
+
+    public static boolean isPublic(int modifiers) {
+        return (modifiers & PUBLIC) != 0;
+    }
+
+    public static boolean isStatic(int modifiers) {
+        return (modifiers & STATIC) != 0;
+    }
+
+    public static boolean isStrictfp(int modifiers) {
+        return (modifiers & STRICTFP) != 0;
+    }
+
+    public static boolean isSynchronized(int modifiers) {
+        return (modifiers & SYNCHRONIZED) != 0;
+    }
+
+    public static boolean isTransient(int modifiers) {
+        return (modifiers & TRANSIENT) != 0;
+    }
+
+    public static boolean isVolatile(int modifiers) {
+        return (modifiers & VOLATILE) != 0;
+    }
+
+    /**
+     * Removes the given modifier.
+     * @param modifiers existing modifiers
+     * @param mod modifier to be removed
+     * @return result for removing modifier
+     */
+    public static int removeModifier(int modifiers, int mod) {
+        return modifiers & ~mod;
+    }
+
+    private ModifierSet() {
+    }
+}
\ No newline at end of file
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/MultiTypeParameter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/MultiTypeParameter.java
new file mode 100644
index 0000000..6dad24c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/MultiTypeParameter.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+public class MultiTypeParameter extends BaseParameter {
+    private List<Type> types;
+	
+    public MultiTypeParameter() {}
+
+    public MultiTypeParameter(int modifiers, List<AnnotationExpr> annotations, List<Type> types, VariableDeclaratorId id) {
+        super(modifiers, annotations, id);
+        this.types = types;
+    }
+
+    public MultiTypeParameter(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, List<Type> types, VariableDeclaratorId id) {
+        super(beginLine, beginColumn, endLine, endColumn, modifiers, annotations, id);
+        this.types = types;
+	}
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+    
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<Type> getTypes() {
+        return types;
+    }
+
+    public void setTypes(List<Type> types) {
+        this.types = types;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/Parameter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/Parameter.java
new file mode 100644
index 0000000..6113d70
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/Parameter.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class Parameter extends BaseParameter {
+    private Type type;
+
+    private boolean isVarArgs;
+
+    public Parameter() {
+    }
+
+    public Parameter(Type type, VariableDeclaratorId id) {
+    	super(id);
+        setType(type);
+    }
+
+    public Parameter(int modifiers, Type type, VariableDeclaratorId id) {
+    	super(modifiers, id);
+        setType(type);
+    }
+
+    public Parameter(int beginLine, int beginColumn, int endLine, int endColumn, int modifiers, List<AnnotationExpr> annotations, Type type, boolean isVarArgs, VariableDeclaratorId id) {
+        super(beginLine, beginColumn, endLine, endColumn, modifiers, annotations, id);
+        setType(type);
+        setVarArgs(isVarArgs);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public boolean isVarArgs() {
+        return isVarArgs;
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+    }
+
+    public void setVarArgs(boolean isVarArgs) {
+        this.isVarArgs = isVarArgs;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/TypeDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/TypeDeclaration.java
new file mode 100644
index 0000000..bd7c093
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/TypeDeclaration.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class TypeDeclaration extends BodyDeclaration implements NamedNode {
+
+	private NameExpr name;
+
+	private int modifiers;
+
+	private List<BodyDeclaration> members;
+
+	public TypeDeclaration() {
+	}
+
+	public TypeDeclaration(int modifiers, String name) {
+		setName(name);
+		setModifiers(modifiers);
+	}
+
+	public TypeDeclaration(List<AnnotationExpr> annotations,
+			int modifiers, String name,
+			List<BodyDeclaration> members) {
+		super(annotations);
+		setName(name);
+		setModifiers(modifiers);
+		setMembers(members);
+	}
+
+	public TypeDeclaration(int beginLine, int beginColumn, int endLine,
+			int endColumn, List<AnnotationExpr> annotations,
+			int modifiers, String name,
+			List<BodyDeclaration> members) {
+		super(beginLine, beginColumn, endLine, endColumn, annotations);
+		setName(name);
+		setModifiers(modifiers);
+		setMembers(members);
+	}
+
+	public final List<BodyDeclaration> getMembers() {
+		return members;
+	}
+
+	/**
+	 * Return the modifiers of this type declaration.
+	 * 
+	 * @see ModifierSet
+	 * @return modifiers
+	 */
+	public final int getModifiers() {
+		return modifiers;
+	}
+
+	public final String getName() {
+		return name.getName();
+	}
+
+	public void setMembers(List<BodyDeclaration> members) {
+		this.members = members;
+		setAsParentNodeOf(this.members);
+	}
+
+	public final void setModifiers(int modifiers) {
+		this.modifiers = modifiers;
+	}
+
+	public final void setName(String name) {
+		this.name = new NameExpr(name);
+	}
+
+    public final void setNameExpr(NameExpr nameExpr) {
+      this.name = nameExpr;
+    }
+
+    public final NameExpr getNameExpr() {
+      return name;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/VariableDeclarator.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/VariableDeclarator.java
new file mode 100644
index 0000000..50097b8
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/VariableDeclarator.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclarator extends Node {
+
+    private VariableDeclaratorId id;
+
+    private Expression init;
+
+    public VariableDeclarator() {
+    }
+
+    public VariableDeclarator(VariableDeclaratorId id) {
+        setId(id);
+    }
+
+    public VariableDeclarator(VariableDeclaratorId id, Expression init) {
+    	setId(id);
+    	setInit(init);
+    }
+
+    public VariableDeclarator(int beginLine, int beginColumn, int endLine, int endColumn, VariableDeclaratorId id, Expression init) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setId(id);
+        setInit(init);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public VariableDeclaratorId getId() {
+        return id;
+    }
+
+    public Expression getInit() {
+        return init;
+    }
+
+    public void setId(VariableDeclaratorId id) {
+        this.id = id;
+		setAsParentNodeOf(this.id);
+    }
+
+    public void setInit(Expression init) {
+        this.init = init;
+		setAsParentNodeOf(this.init);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/VariableDeclaratorId.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/VariableDeclaratorId.java
new file mode 100644
index 0000000..c56bd8e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/VariableDeclaratorId.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclaratorId extends Node implements NamedNode {
+
+    private String name;
+
+    private int arrayCount;
+
+    public VariableDeclaratorId() {
+    }
+
+    public VariableDeclaratorId(String name) {
+       setName(name);
+    }
+
+    public VariableDeclaratorId(int beginLine, int beginColumn, int endLine, int endColumn, String name, int arrayCount) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setName(name);
+        setArrayCount(arrayCount);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public int getArrayCount() {
+        return arrayCount;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setArrayCount(int arrayCount) {
+        this.arrayCount = arrayCount;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/WithDeclaration.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/WithDeclaration.java
new file mode 100644
index 0000000..8f1725c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/body/WithDeclaration.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.body;
+
+/**
+ * Element with a declaration representable as a String.
+ *
+ * @author Federico Tomassetti
+ * @since July 2014
+ */
+public interface WithDeclaration {
+
+    /**
+     * As {@link WithDeclaration#getDeclarationAsString(boolean, boolean, boolean)} including
+     * the modifiers, the throws clause and the parameters with both type and name.
+     * @return String representation of declaration
+     */
+    String getDeclarationAsString();
+
+    /**
+     * As {@link WithDeclaration#getDeclarationAsString(boolean, boolean, boolean)} including
+     * the parameters with both type and name.
+     * @param includingModifiers flag to include the modifiers (if present) in the string produced
+     * @param includingThrows flag to include the throws clause (if present) in the string produced
+     * @return String representation of declaration based on parameter flags
+     */
+    String getDeclarationAsString(boolean includingModifiers, boolean includingThrows);
+
+    /**
+     * A simple representation of the element declaration.
+     * It should fit one string.
+     * @param includingModifiers flag to include the modifiers (if present) in the string produced
+     * @param includingThrows flag to include the throws clause (if present) in the string produced
+     * @param includingParameterName flag to include the parameter name (while the parameter type is always included) in the string produced
+     * @return String representation of declaration based on parameter flags
+     */
+    String getDeclarationAsString(boolean includingModifiers, boolean includingThrows, boolean includingParameterName);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/BlockComment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/BlockComment.java
new file mode 100644
index 0000000..299493b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/BlockComment.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * <p>
+ * AST node that represent block comments.
+ * </p>
+ * Block comments can has multi lines and are delimited by "/&#42;" and
+ * "&#42;/".
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public final class BlockComment extends Comment {
+
+    public BlockComment() {
+    }
+
+    public BlockComment(String content) {
+        super(content);
+    }
+
+    public BlockComment(int beginLine, int beginColumn, int endLine, int endColumn, String content) {
+        super(beginLine, beginColumn, endLine, endColumn, content);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/Comment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/Comment.java
new file mode 100644
index 0000000..135972b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/Comment.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * Abstract class for all AST nodes that represent comments.
+ * 
+ * @see BlockComment
+ * @see LineComment
+ * @see JavadocComment
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Comment extends Node {
+
+    private String content;
+    private Node commentedNode;
+
+    public Comment() {
+    }
+
+    public Comment(String content) {
+        this.content = content;
+    }
+
+    public Comment(int beginLine, int beginColumn, int endLine, int endColumn, String content) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        this.content = content;
+    }
+
+    /**
+     * Return the text of the comment.
+     * 
+     * @return text of the comment
+     */
+    public final String getContent() {
+        return content;
+    }
+
+    /**
+     * Sets the text of the comment.
+     * 
+     * @param content
+     *            the text of the comment to set
+     */
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public boolean isLineComment()
+    {
+        return false;
+    }
+
+    public LineComment asLineComment()
+    {
+        if (isLineComment())
+        {
+            return (LineComment) this;
+        } else {
+            throw new UnsupportedOperationException("Not a line comment");
+        }
+    }
+
+    public Node getCommentedNode()
+    {
+        return this.commentedNode;
+    }
+
+    public void setCommentedNode(Node commentedNode)
+    {
+        if (commentedNode==null)
+        {
+            this.commentedNode = commentedNode;
+            return;
+        }
+        if (commentedNode==this)
+        {
+            throw new IllegalArgumentException();
+        }
+        if (commentedNode instanceof Comment)
+        {
+            throw new IllegalArgumentException();
+        }
+        this.commentedNode = commentedNode;
+    }
+
+    public boolean isOrphan()
+    {
+        return this.commentedNode == null;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/CommentsCollection.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/CommentsCollection.java
new file mode 100644
index 0000000..ac94c61
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/CommentsCollection.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.comments;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Set of comments produced by CommentsParser.
+ */
+public class CommentsCollection {
+    private List<LineComment> lineComments = new LinkedList<LineComment>();
+    private List<BlockComment> blockComments = new LinkedList<BlockComment>();
+    private List<JavadocComment> javadocComments = new LinkedList<JavadocComment>();
+
+    public List<LineComment> getLineComments(){
+        return lineComments;
+    }
+
+    public List<BlockComment> getBlockComments(){
+        return blockComments;
+    }
+
+    public List<JavadocComment> getJavadocComments(){
+        return javadocComments;
+    }
+
+    public void addComment(LineComment lineComment){
+        this.lineComments.add(lineComment);
+    }
+
+    public void addComment(BlockComment blockComment){
+        this.blockComments.add(blockComment);
+    }
+
+    public void addComment(JavadocComment javadocComment){
+        this.javadocComments.add(javadocComment);
+    }
+
+    public boolean contains(Comment comment){
+        for (Comment c : getAll()){
+            // we tollerate a difference of one element in the end column:
+            // it depends how \r and \n are calculated...
+            if ( c.getBeginLine()==comment.getBeginLine() &&
+                 c.getBeginColumn()==comment.getBeginColumn() &&
+                 c.getEndLine()==comment.getEndLine() &&
+                 Math.abs(c.getEndColumn()-comment.getEndColumn())<2 ){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<Comment> getAll(){
+        List<Comment> comments = new LinkedList<Comment>();
+        comments.addAll(lineComments);
+        comments.addAll(blockComments);
+        comments.addAll(javadocComments);
+        return comments;
+    }
+
+    public int size(){
+        return lineComments.size()+blockComments.size()+javadocComments.size();
+    }
+
+    public CommentsCollection minus(CommentsCollection other){
+        CommentsCollection result = new CommentsCollection();
+        for (LineComment comment : lineComments){
+            if (!other.contains(comment)){
+                result.lineComments.add(comment);
+            }
+        }
+        for (BlockComment comment : blockComments){
+            if (!other.contains(comment)){
+                result.blockComments.add(comment);
+            }
+        }
+        for (JavadocComment comment : javadocComments){
+            if (!other.contains(comment)){
+                result.javadocComments.add(comment);
+            }
+        }
+        return result;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/CommentsParser.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/CommentsParser.java
new file mode 100644
index 0000000..3d3a59d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/CommentsParser.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.util.*;
+
+/**
+ * This parser cares exclusively about comments.
+ */
+public class CommentsParser {
+
+    private enum State {
+        CODE,
+        IN_LINE_COMMENT,
+        IN_BLOCK_COMMENT,
+        IN_STRING,
+        IN_CHAR;
+    }
+
+    private static final int COLUMNS_PER_TAB = 4;
+
+    public CommentsCollection parse(final String source) throws IOException, UnsupportedEncodingException {
+        InputStream in = new ByteArrayInputStream(source.getBytes(Charset.defaultCharset()));
+        return parse(in, Charset.defaultCharset().name());
+    }
+
+    public CommentsCollection parse(final InputStream in, final String charsetName) throws IOException, UnsupportedEncodingException {
+        boolean lastWasASlashR = false;
+        BufferedReader br = new BufferedReader(new InputStreamReader(in, charsetName));
+        CommentsCollection comments = new CommentsCollection();
+        int r;
+
+        Deque prevTwoChars = new LinkedList<Character>(Arrays.asList('z','z'));
+
+        State state = State.CODE;
+        LineComment currentLineComment = null;
+        BlockComment currentBlockComment = null;
+        StringBuffer currentContent = null;
+
+        int currLine = 1;
+        int currCol  = 1;
+
+        while ((r=br.read()) != -1){
+            char c = (char)r;
+            if (c=='\r'){
+                lastWasASlashR = true;
+            } else if (c=='\n'&&lastWasASlashR){
+                lastWasASlashR=false;
+                continue;
+            } else {
+                lastWasASlashR=false;
+            }
+            switch (state) {
+                case CODE:
+                    if (prevTwoChars.peekLast().equals('/') && c == '/') {
+                        currentLineComment = new LineComment();
+                        currentLineComment.setBeginLine(currLine);
+                        currentLineComment.setBeginColumn(currCol - 1);
+                        state = State.IN_LINE_COMMENT;
+                        currentContent = new StringBuffer();
+                    } else if (prevTwoChars.peekLast().equals('/') && c == '*') {
+                        currentBlockComment = new BlockComment();
+                        currentBlockComment.setBeginLine(currLine);
+                        currentBlockComment.setBeginColumn(currCol - 1);
+                        state = State.IN_BLOCK_COMMENT;
+                        currentContent = new StringBuffer();
+                    } else if (c == '"') {
+                        state = State.IN_STRING;
+                    } else if (c == '\'') {
+                        state = State.IN_CHAR;
+                    } else {
+                        // nothing to do
+                    }
+                    break;
+                case IN_LINE_COMMENT:
+                    if (c=='\n' || c=='\r'){
+                        currentLineComment.setContent(currentContent.toString());
+                        currentLineComment.setEndLine(currLine);
+                        currentLineComment.setEndColumn(currCol);
+                        comments.addComment(currentLineComment);
+                        state = State.CODE;
+                    } else {
+                        currentContent.append(c);
+                    }
+                    break;
+                case IN_BLOCK_COMMENT:
+                    if (prevTwoChars.peekLast().equals('*') && c=='/' && !prevTwoChars.peekFirst().equals('/')){
+
+                        // delete last character
+                        String content = currentContent.deleteCharAt(currentContent.toString().length()-1).toString();
+
+                        if (content.startsWith("*")){
+                            JavadocComment javadocComment = new JavadocComment();
+                            javadocComment.setContent(content.substring(1));
+                            javadocComment.setBeginLine(currentBlockComment.getBeginLine());
+                            javadocComment.setBeginColumn(currentBlockComment.getBeginColumn());
+                            javadocComment.setEndLine(currLine);
+                            javadocComment.setEndColumn(currCol+1);
+                            comments.addComment(javadocComment);
+                        } else {
+                            currentBlockComment.setContent(content);
+                            currentBlockComment.setEndLine(currLine);
+                            currentBlockComment.setEndColumn(currCol+1);
+                            comments.addComment(currentBlockComment);
+                        }
+                        state = State.CODE;
+                    } else {
+                        currentContent.append(c=='\r'?'\n':c);
+                    }
+                    break;
+                case IN_STRING:
+                    if (!prevTwoChars.peekLast().equals('\\') && c == '"') {
+                        state = State.CODE;
+                    }
+                    break;
+                case IN_CHAR:
+                    if (!prevTwoChars.peekLast().equals('\\') && c == '\'') {
+                        state = State.CODE;
+                    }
+                    break;
+                default:
+                    throw new RuntimeException("Unexpected");
+            }
+            switch (c){
+                case '\n':
+                case '\r':
+                    currLine+=1;
+                    currCol = 1;
+                    break;
+                case '\t':
+                    currCol+=COLUMNS_PER_TAB;
+                    break;
+                default:
+                    currCol+=1;
+            }
+            prevTwoChars.remove();
+            prevTwoChars.add(c);
+        }
+
+        if (state==State.IN_LINE_COMMENT){
+            currentLineComment.setContent(currentContent.toString());
+            currentLineComment.setEndLine(currLine);
+            currentLineComment.setEndColumn(currCol);
+            comments.addComment(currentLineComment);
+        }
+
+        return comments;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/JavadocComment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/JavadocComment.java
new file mode 100644
index 0000000..a070321
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/JavadocComment.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class JavadocComment extends Comment {
+
+    public JavadocComment() {
+    }
+
+    public JavadocComment(String content) {
+        super(content);
+    }
+
+    public JavadocComment(int beginLine, int beginColumn, int endLine, int endColumn, String content) {
+        super(beginLine, beginColumn, endLine, endColumn, content);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/LineComment.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/LineComment.java
new file mode 100644
index 0000000..b3df1df
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/comments/LineComment.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * <p>
+ * AST node that represent line comments.
+ * </p>
+ * Line comments are started with "//" and finish at the end of the line ("\n").
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public final class LineComment extends Comment {
+
+    public LineComment() {
+    }
+
+    public LineComment(String content) {
+        super(content);
+    }
+
+    public LineComment(int beginLine, int beginColumn, int endLine, int endColumn, String content) {
+        super(beginLine, beginColumn, endLine, endColumn, content);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public boolean isLineComment()
+    {
+        return true;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/AnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/AnnotationExpr.java
new file mode 100644
index 0000000..8c65e92
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/AnnotationExpr.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class AnnotationExpr extends Expression {
+
+	protected NameExpr name;
+
+	public AnnotationExpr() {}
+
+	public AnnotationExpr(int beginLine, int beginColumn, int endLine,
+			int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn);
+	}
+
+	public NameExpr getName() {
+		return name;
+	}
+
+	public void setName(NameExpr name) {
+		this.name = name;
+		setAsParentNodeOf(name);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayAccessExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayAccessExpr.java
new file mode 100644
index 0000000..7026d15
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayAccessExpr.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayAccessExpr extends Expression {
+
+    private Expression name;
+
+    private Expression index;
+
+    public ArrayAccessExpr() {
+    }
+
+    public ArrayAccessExpr(Expression name, Expression index) {
+        setName(name);
+        setIndex(index);
+    }
+
+    public ArrayAccessExpr(int beginLine, int beginColumn, int endLine, int endColumn, Expression name, Expression index) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setName(name);
+        setIndex(index);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getIndex() {
+        return index;
+    }
+
+    public Expression getName() {
+        return name;
+    }
+
+    public void setIndex(Expression index) {
+        this.index = index;
+		setAsParentNodeOf(this.index);
+    }
+
+    public void setName(Expression name) {
+        this.name = name;
+		setAsParentNodeOf(this.name);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayCreationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayCreationExpr.java
new file mode 100644
index 0000000..1ca425b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayCreationExpr.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayCreationExpr extends Expression {
+
+    private Type type;
+
+    private int arrayCount;
+
+    private ArrayInitializerExpr initializer;
+
+    private List<Expression> dimensions;
+
+    private List<List<AnnotationExpr>> arraysAnnotations;
+
+    public ArrayCreationExpr() {
+    }
+
+    public ArrayCreationExpr(Type type, int arrayCount, ArrayInitializerExpr initializer) {
+        setType(type);
+        setArrayCount(arrayCount);
+        setInitializer(initializer);
+        setDimensions(null);
+    }
+
+    public ArrayCreationExpr(int beginLine, int beginColumn, int endLine, int endColumn, Type type, int arrayCount, ArrayInitializerExpr initializer) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setType(type);
+        setArrayCount(arrayCount);
+        setInitializer(initializer);
+        setDimensions(null);
+    }
+
+    public ArrayCreationExpr(Type type, List<Expression> dimensions, int arrayCount) {
+        setType(type);
+        setArrayCount(arrayCount);
+        setDimensions(dimensions);
+        setInitializer(null);
+    }
+
+    public ArrayCreationExpr(int beginLine, int beginColumn, int endLine, int endColumn, Type type, List<Expression> dimensions, int arrayCount) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setType(type);
+        setArrayCount(arrayCount);
+        setDimensions(dimensions);
+        setInitializer(null);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public int getArrayCount() {
+        return arrayCount;
+    }
+
+    public List<Expression> getDimensions() {
+        return dimensions;
+    }
+
+    public ArrayInitializerExpr getInitializer() {
+        return initializer;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public void setArrayCount(int arrayCount) {
+        this.arrayCount = arrayCount;
+    }
+
+    public void setDimensions(List<Expression> dimensions) {
+        this.dimensions = dimensions;
+		setAsParentNodeOf(this.dimensions);
+    }
+
+    public void setInitializer(ArrayInitializerExpr initializer) {
+        this.initializer = initializer;
+		setAsParentNodeOf(this.initializer);
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+    }
+
+    public List<List<AnnotationExpr>> getArraysAnnotations() {
+        return arraysAnnotations;
+    }
+
+    public void setArraysAnnotations(
+            List<List<AnnotationExpr>> arraysAnnotations) {
+        this.arraysAnnotations = arraysAnnotations;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayInitializerExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayInitializerExpr.java
new file mode 100644
index 0000000..f7fa424
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ArrayInitializerExpr.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ArrayInitializerExpr extends Expression {
+
+    private List<Expression> values;
+
+    public ArrayInitializerExpr() {
+    }
+
+    public ArrayInitializerExpr(List<Expression> values) {
+       setValues(values);
+    }
+
+    public ArrayInitializerExpr(int beginLine, int beginColumn, int endLine, int endColumn, List<Expression> values) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setValues(values);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public List<Expression> getValues() {
+        return values;
+    }
+
+    public void setValues(List<Expression> values) {
+        this.values = values;
+		setAsParentNodeOf(this.values);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/AssignExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/AssignExpr.java
new file mode 100644
index 0000000..b3d508f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/AssignExpr.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AssignExpr extends Expression {
+
+    public static enum Operator {
+        assign, // =
+        plus, // +=
+        minus, // -=
+        star, // *=
+        slash, // /=
+        and, // &=
+        or, // |=
+        xor, // ^=
+        rem, // %=
+        lShift, // <<=
+        rSignedShift, // >>=
+        rUnsignedShift, // >>>=
+    }
+
+    private Expression target;
+
+    private Expression value;
+
+    private Operator op;
+
+    public AssignExpr() {
+    }
+
+    public AssignExpr(Expression target, Expression value, Operator op) {
+        setTarget(target);
+        setValue(value);
+        setOperator(op);
+    }
+
+    public AssignExpr(int beginLine, int beginColumn, int endLine, int endColumn, Expression target, Expression value, Operator op) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setTarget(target);
+        setValue(value);
+        setOperator(op);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Operator getOperator() {
+        return op;
+    }
+
+    public Expression getTarget() {
+        return target;
+    }
+
+    public Expression getValue() {
+        return value;
+    }
+
+    public void setOperator(Operator op) {
+        this.op = op;
+    }
+
+    public void setTarget(Expression target) {
+        this.target = target;
+		setAsParentNodeOf(this.target);
+    }
+
+    public void setValue(Expression value) {
+        this.value = value;
+		setAsParentNodeOf(this.value);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/BinaryExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/BinaryExpr.java
new file mode 100644
index 0000000..4ace4be
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/BinaryExpr.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BinaryExpr extends Expression {
+
+    public static enum Operator {
+        or, // ||
+        and, // &&
+        binOr, // |
+        binAnd, // &
+        xor, // ^
+        equals, // ==
+        notEquals, // !=
+        less, // <
+        greater, // >
+        lessEquals, // <=
+        greaterEquals, // >=
+        lShift, // <<
+        rSignedShift, // >>
+        rUnsignedShift, // >>>
+        plus, // +
+        minus, // -
+        times, // *
+        divide, // /
+        remainder, // %
+    }
+
+    private Expression left;
+
+    private Expression right;
+
+    private Operator op;
+
+    public BinaryExpr() {
+    }
+
+    public BinaryExpr(Expression left, Expression right, Operator op) {
+    	setLeft(left);
+    	setRight(right);
+    	setOperator(op);
+    }
+
+    public BinaryExpr(int beginLine, int beginColumn, int endLine, int endColumn, Expression left, Expression right, Operator op) {
+        super(beginLine, beginColumn, endLine, endColumn);
+    	setLeft(left);
+    	setRight(right);
+    	setOperator(op);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getLeft() {
+        return left;
+    }
+
+    public Operator getOperator() {
+        return op;
+    }
+
+    public Expression getRight() {
+        return right;
+    }
+
+    public void setLeft(Expression left) {
+        this.left = left;
+		setAsParentNodeOf(this.left);
+    }
+
+    public void setOperator(Operator op) {
+        this.op = op;
+    }
+
+    public void setRight(Expression right) {
+        this.right = right;
+		setAsParentNodeOf(this.right);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/BooleanLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/BooleanLiteralExpr.java
new file mode 100644
index 0000000..e92244a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/BooleanLiteralExpr.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BooleanLiteralExpr extends LiteralExpr {
+
+    private boolean value;
+
+    public BooleanLiteralExpr() {
+    }
+
+    public BooleanLiteralExpr(boolean value) {
+    	setValue(value);
+    }
+
+    public BooleanLiteralExpr(int beginLine, int beginColumn, int endLine, int endColumn, boolean value) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setValue(value);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public boolean getValue() {
+        return value;
+    }
+
+    public void setValue(boolean value) {
+        this.value = value;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/CastExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/CastExpr.java
new file mode 100644
index 0000000..8433869
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/CastExpr.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class CastExpr extends Expression {
+
+    private Type type;
+
+    private Expression expr;
+
+    public CastExpr() {
+    }
+
+    public CastExpr(Type type, Expression expr) {
+    	setType(type);
+    	setExpr(expr);
+    }
+
+    public CastExpr(int beginLine, int beginColumn, int endLine, int endColumn, Type type, Expression expr) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setType(type);
+    	setExpr(expr);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getExpr() {
+        return expr;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public void setExpr(Expression expr) {
+        this.expr = expr;
+		setAsParentNodeOf(this.expr);
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/CharLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/CharLiteralExpr.java
new file mode 100644
index 0000000..061805d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/CharLiteralExpr.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class CharLiteralExpr extends StringLiteralExpr {
+
+    public CharLiteralExpr() {
+    }
+
+    public CharLiteralExpr(String value) {
+        super(value);
+    }
+
+    public CharLiteralExpr(int beginLine, int beginColumn, int endLine, int endColumn, String value) {
+        super(beginLine, beginColumn, endLine, endColumn, value);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ClassExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ClassExpr.java
new file mode 100644
index 0000000..bd33c67
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ClassExpr.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassExpr extends Expression {
+
+    private Type type;
+
+    public ClassExpr() {
+    }
+
+    public ClassExpr(Type type) {
+       setType(type);
+    }
+
+    public ClassExpr(int beginLine, int beginColumn, int endLine, int endColumn, Type type) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setType(type);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+		setAsParentNodeOf(this.type);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ConditionalExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ConditionalExpr.java
new file mode 100644
index 0000000..31db61c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ConditionalExpr.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ConditionalExpr extends Expression {
+
+    private Expression condition;
+
+    private Expression thenExpr;
+
+    private Expression elseExpr;
+
+    public ConditionalExpr() {
+    }
+
+    public ConditionalExpr(Expression condition, Expression thenExpr, Expression elseExpr) {
+        setCondition(condition);
+        setThenExpr(thenExpr);
+        setElseExpr(elseExpr);
+    }
+
+    public ConditionalExpr(int beginLine, int beginColumn, int endLine, int endColumn, Expression condition, Expression thenExpr, Expression elseExpr) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setCondition(condition);
+        setThenExpr(thenExpr);
+        setElseExpr(elseExpr);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getCondition() {
+        return condition;
+    }
+
+    public Expression getElseExpr() {
+        return elseExpr;
+    }
+
+    public Expression getThenExpr() {
+        return thenExpr;
+    }
+
+    public void setCondition(Expression condition) {
+        this.condition = condition;
+		setAsParentNodeOf(this.condition);
+    }
+
+    public void setElseExpr(Expression elseExpr) {
+        this.elseExpr = elseExpr;
+		setAsParentNodeOf(this.elseExpr);
+    }
+
+    public void setThenExpr(Expression thenExpr) {
+        this.thenExpr = thenExpr;
+		setAsParentNodeOf(this.thenExpr);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/DoubleLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/DoubleLiteralExpr.java
new file mode 100644
index 0000000..ce6962d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/DoubleLiteralExpr.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class DoubleLiteralExpr extends StringLiteralExpr {
+
+	public DoubleLiteralExpr() {
+	}
+
+	public DoubleLiteralExpr(final String value) {
+		super(value);
+	}
+
+	public DoubleLiteralExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String value) {
+		super(beginLine, beginColumn, endLine, endColumn, value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/EnclosedExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/EnclosedExpr.java
new file mode 100644
index 0000000..72f9de2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/EnclosedExpr.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EnclosedExpr extends Expression {
+
+	private Expression inner;
+
+	public EnclosedExpr() {
+	}
+
+	public EnclosedExpr(final Expression inner) {
+		setInner(inner);
+	}
+
+	public EnclosedExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression inner) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setInner(inner);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getInner() {
+		return inner;
+	}
+
+	public void setInner(final Expression inner) {
+		this.inner = inner;
+		setAsParentNodeOf(this.inner);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/Expression.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/Expression.java
new file mode 100644
index 0000000..8b36d6b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/Expression.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Expression extends Node {
+
+	public Expression() {
+	}
+
+	public Expression(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/FieldAccessExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/FieldAccessExpr.java
new file mode 100644
index 0000000..b57bf7f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/FieldAccessExpr.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class FieldAccessExpr extends Expression {
+
+	private Expression scope;
+
+	private List<Type> typeArgs;
+
+	private NameExpr field;
+
+	public FieldAccessExpr() {
+	}
+
+	public FieldAccessExpr(final Expression scope, final String field) {
+		setScope(scope);
+		setField(field);
+	}
+
+	public FieldAccessExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression scope, final List<Type> typeArgs, final String field) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setScope(scope);
+		setTypeArgs(typeArgs);
+		setField(field);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getField() {
+		return field.getName();
+	}
+
+	public NameExpr getFieldExpr() {
+		return field;
+	}
+
+	public Expression getScope() {
+		return scope;
+	}
+
+	public List<Type> getTypeArgs() {
+		return typeArgs;
+	}
+
+	public void setField(final String field) {
+		this.field = new NameExpr(field);
+	}
+
+	public void setFieldExpr(NameExpr field) {
+		this.field = field;
+	}
+
+	public void setScope(final Expression scope) {
+		this.scope = scope;
+		setAsParentNodeOf(this.scope);
+	}
+
+	public void setTypeArgs(final List<Type> typeArgs) {
+		this.typeArgs = typeArgs;
+		setAsParentNodeOf(this.typeArgs);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/InstanceOfExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/InstanceOfExpr.java
new file mode 100644
index 0000000..9a97865
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/InstanceOfExpr.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class InstanceOfExpr extends Expression {
+
+	private Expression expr;
+
+	private Type type;
+
+	public InstanceOfExpr() {
+	}
+
+	public InstanceOfExpr(final Expression expr, final Type type) {
+		setExpr(expr);
+		setType(type);
+	}
+
+	public InstanceOfExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression expr, final Type type) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setExpr(expr);
+		setType(type);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public void setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+	}
+
+	public void setType(final Type type) {
+		this.type = type;
+		setAsParentNodeOf(this.type);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/IntegerLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/IntegerLiteralExpr.java
new file mode 100644
index 0000000..b326c57
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/IntegerLiteralExpr.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class IntegerLiteralExpr extends StringLiteralExpr {
+
+	private static final String UNSIGNED_MIN_VALUE = "2147483648";
+
+	protected static final String MIN_VALUE = "-" + UNSIGNED_MIN_VALUE;
+
+	public IntegerLiteralExpr() {
+	}
+
+	public IntegerLiteralExpr(final String value) {
+		super(value);
+	}
+
+	public IntegerLiteralExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String value) {
+		super(beginLine, beginColumn, endLine, endColumn, value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public final boolean isMinValue() {
+		return value != null && //
+				value.length() == 10 && //
+				value.equals(UNSIGNED_MIN_VALUE);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr.java
new file mode 100644
index 0000000..238b564
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/IntegerLiteralMinValueExpr.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class IntegerLiteralMinValueExpr extends IntegerLiteralExpr {
+
+	public IntegerLiteralMinValueExpr() {
+		super(MIN_VALUE);
+	}
+
+	public IntegerLiteralMinValueExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn, MIN_VALUE);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LambdaExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LambdaExpr.java
new file mode 100644
index 0000000..4e4e934
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LambdaExpr.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * Lambda expressions. 
+ * @author Raquel Pau
+ *
+ */
+public class LambdaExpr extends Expression {
+
+	private List<Parameter> parameters;
+
+	private boolean parametersEnclosed;
+
+	private Statement body;
+
+	public LambdaExpr() {
+	}
+
+	public LambdaExpr(int beginLine, int beginColumn, int endLine,
+                      int endColumn, List<Parameter> parameters, Statement body,
+                      boolean parametersEnclosed) {
+
+		super(beginLine, beginColumn, endLine, endColumn);
+		setParameters(parameters);
+		setBody(body);
+        setParametersEnclosed(parametersEnclosed);
+	}
+
+	public List<Parameter> getParameters() {
+		return parameters;
+	}
+
+	public void setParameters(List<Parameter> parameters) {
+		this.parameters = parameters;
+		setAsParentNodeOf(this.parameters);
+	}
+
+	public Statement getBody() {
+		return body;
+	}
+
+	public void setBody(Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+	}
+
+	@Override
+	public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(VoidVisitor<A> v, A arg) {
+		v.visit(this, arg);
+	}
+
+	public boolean isParametersEnclosed() {
+		return parametersEnclosed;
+	}
+
+	public void setParametersEnclosed(boolean parametersEnclosed) {
+		this.parametersEnclosed = parametersEnclosed;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LiteralExpr.java
new file mode 100644
index 0000000..7827f78
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LiteralExpr.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class LiteralExpr extends Expression {
+
+	public LiteralExpr() {
+	}
+
+	public LiteralExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LongLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LongLiteralExpr.java
new file mode 100644
index 0000000..15ea255
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LongLiteralExpr.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class LongLiteralExpr extends StringLiteralExpr {
+
+	private static final String UNSIGNED_MIN_VALUE = "9223372036854775808";
+
+	protected static final String MIN_VALUE = "-" + UNSIGNED_MIN_VALUE + "L";
+
+	public LongLiteralExpr() {
+	}
+
+	public LongLiteralExpr(final String value) {
+		super(value);
+	}
+
+	public LongLiteralExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String value) {
+		super(beginLine, beginColumn, endLine, endColumn, value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public final boolean isMinValue() {
+		return value != null && //
+				value.length() == 20 && //
+				value.startsWith(UNSIGNED_MIN_VALUE) && //
+				(value.charAt(19) == 'L' || value.charAt(19) == 'l');
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LongLiteralMinValueExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LongLiteralMinValueExpr.java
new file mode 100644
index 0000000..f351f7a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/LongLiteralMinValueExpr.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class LongLiteralMinValueExpr extends LongLiteralExpr {
+
+	public LongLiteralMinValueExpr() {
+		super(MIN_VALUE);
+	}
+
+	public LongLiteralMinValueExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn, MIN_VALUE);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java
new file mode 100644
index 0000000..c1a3545
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MarkerAnnotationExpr.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MarkerAnnotationExpr extends AnnotationExpr {
+
+	public MarkerAnnotationExpr() {
+	}
+
+	public MarkerAnnotationExpr(final NameExpr name) {
+		setName(name);
+	}
+
+	public MarkerAnnotationExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final NameExpr name) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setName(name);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MemberValuePair.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MemberValuePair.java
new file mode 100644
index 0000000..e0fa80c
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MemberValuePair.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MemberValuePair extends Node implements NamedNode {
+
+	private String name;
+
+	private Expression value;
+
+	public MemberValuePair() {
+	}
+
+	public MemberValuePair(final String name, final Expression value) {
+		setName(name);
+		setValue(value);
+	}
+
+	public MemberValuePair(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String name, final Expression value) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setName(name);
+		setValue(value);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Expression getValue() {
+		return value;
+	}
+
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	public void setValue(final Expression value) {
+		this.value = value;
+		setAsParentNodeOf(this.value);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MethodCallExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MethodCallExpr.java
new file mode 100644
index 0000000..9d5d10f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MethodCallExpr.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class MethodCallExpr extends Expression {
+
+	private Expression scope;
+
+	private List<Type> typeArgs;
+
+	private NameExpr name;
+
+	private List<Expression> args;
+
+	public MethodCallExpr() {
+	}
+
+	public MethodCallExpr(final Expression scope, final String name) {
+		setScope(scope);
+		setName(name);
+	}
+
+	public MethodCallExpr(final Expression scope, final String name, final List<Expression> args) {
+		setScope(scope);
+		setName(name);
+		setArgs(args);
+	}
+
+	public MethodCallExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression scope, final List<Type> typeArgs, final String name, final List<Expression> args) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setScope(scope);
+		setTypeArgs(typeArgs);
+		setName(name);
+		setArgs(args);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<Expression> getArgs() {
+		return args;
+	}
+
+	public String getName() {
+		return name.getName();
+	}
+
+	public NameExpr getNameExpr() {
+		return name;
+	}
+
+	public Expression getScope() {
+		return scope;
+	}
+
+	public List<Type> getTypeArgs() {
+		return typeArgs;
+	}
+
+	public void setArgs(final List<Expression> args) {
+		this.args = args;
+		setAsParentNodeOf(this.args);
+	}
+
+	public void setName(final String name) {
+		this.name = new NameExpr(name);
+	}
+
+	public void setNameExpr(NameExpr name) {
+		this.name = name;
+	}
+
+	public void setScope(final Expression scope) {
+		this.scope = scope;
+		setAsParentNodeOf(this.scope);
+	}
+
+	public void setTypeArgs(final List<Type> typeArgs) {
+		this.typeArgs = typeArgs;
+		setAsParentNodeOf(this.typeArgs);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MethodReferenceExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MethodReferenceExpr.java
new file mode 100644
index 0000000..918ad3f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/MethodReferenceExpr.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * Method reference expressions introduced in Java 8 specifically designed to simplify lambda Expressions.
+ * These are some examples:
+ *
+ * System.out::println; 
+ *
+ * (test ? stream.map(String::trim) : stream)::toArray; 
+ * @author Raquel Pau
+ *
+ */
+public class MethodReferenceExpr extends Expression {
+
+    private Expression scope;
+
+    private List<TypeParameter> typeParameters;
+
+    private String identifier;
+
+    public MethodReferenceExpr() {
+    }
+
+    public MethodReferenceExpr(int beginLine, int beginColumn, int endLine,
+                               int endColumn, Expression scope,
+                               List<TypeParameter> typeParameters, String identifier) {
+
+        super(beginLine, beginColumn, endLine, endColumn);
+        setIdentifier(identifier);
+        setScope(scope);
+        setTypeParameters(typeParameters);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Expression getScope() {
+        return scope;
+    }
+
+    public void setScope(Expression scope) {
+        this.scope = scope;
+        setAsParentNodeOf(this.scope);
+    }
+
+    public List<TypeParameter> getTypeParameters() {
+        return typeParameters;
+    }
+
+    public void setTypeParameters(List<TypeParameter> typeParameters) {
+        this.typeParameters = typeParameters;
+        setAsParentNodeOf(this.typeParameters);
+    }
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NameExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NameExpr.java
new file mode 100644
index 0000000..5cdbbbb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NameExpr.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.NamedNode;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class NameExpr extends Expression implements NamedNode {
+
+	private String name;
+
+	public NameExpr() {
+	}
+
+	public NameExpr(final String name) {
+		this.name = name;
+	}
+
+	public NameExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String name) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		this.name = name;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public final String getName() {
+		return name;
+	}
+
+	public final void setName(final String name) {
+		this.name = name;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NormalAnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NormalAnnotationExpr.java
new file mode 100644
index 0000000..2b2adfd
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NormalAnnotationExpr.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class NormalAnnotationExpr extends AnnotationExpr {
+
+	private List<MemberValuePair> pairs;
+
+	public NormalAnnotationExpr() {
+	}
+
+	public NormalAnnotationExpr(final NameExpr name, final List<MemberValuePair> pairs) {
+		setName(name);
+		setPairs(pairs);
+	}
+
+	public NormalAnnotationExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final NameExpr name, final List<MemberValuePair> pairs) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setName(name);
+		setPairs(pairs);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<MemberValuePair> getPairs() {
+		return pairs;
+	}
+
+	public void setPairs(final List<MemberValuePair> pairs) {
+		this.pairs = pairs;
+		setAsParentNodeOf(this.pairs);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NullLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NullLiteralExpr.java
new file mode 100644
index 0000000..c7bc177
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/NullLiteralExpr.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class NullLiteralExpr extends LiteralExpr {
+
+	public NullLiteralExpr() {
+	}
+
+	public NullLiteralExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ObjectCreationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ObjectCreationExpr.java
new file mode 100644
index 0000000..228dabc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ObjectCreationExpr.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ObjectCreationExpr extends Expression {
+
+	private Expression scope;
+
+	private ClassOrInterfaceType type;
+
+	private List<Type> typeArgs;
+
+	private List<Expression> args;
+
+	private List<BodyDeclaration> anonymousClassBody;
+
+	public ObjectCreationExpr() {
+	}
+
+	public ObjectCreationExpr(final Expression scope, final ClassOrInterfaceType type, final List<Expression> args) {
+		setScope(scope);
+		setType(type);
+		setArgs(args);
+	}
+
+	public ObjectCreationExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression scope, final ClassOrInterfaceType type, final List<Type> typeArgs,
+			final List<Expression> args, final List<BodyDeclaration> anonymousBody) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setScope(scope);
+		setType(type);
+		setTypeArgs(typeArgs);
+		setArgs(args);
+		setAnonymousClassBody(anonymousBody);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<BodyDeclaration> getAnonymousClassBody() {
+		return anonymousClassBody;
+	}
+
+	public List<Expression> getArgs() {
+		return args;
+	}
+
+	public Expression getScope() {
+		return scope;
+	}
+
+	public ClassOrInterfaceType getType() {
+		return type;
+	}
+
+	public List<Type> getTypeArgs() {
+		return typeArgs;
+	}
+
+	public void setAnonymousClassBody(final List<BodyDeclaration> anonymousClassBody) {
+		this.anonymousClassBody = anonymousClassBody;
+		setAsParentNodeOf(this.anonymousClassBody);
+	}
+
+	public void setArgs(final List<Expression> args) {
+		this.args = args;
+		setAsParentNodeOf(this.args);
+	}
+
+	public void setScope(final Expression scope) {
+		this.scope = scope;
+		setAsParentNodeOf(this.scope);
+	}
+
+	public void setType(final ClassOrInterfaceType type) {
+		this.type = type;
+		setAsParentNodeOf(this.type);
+	}
+
+	public void setTypeArgs(final List<Type> typeArgs) {
+		this.typeArgs = typeArgs;
+		setAsParentNodeOf(this.typeArgs);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/QualifiedNameExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/QualifiedNameExpr.java
new file mode 100644
index 0000000..00a65aa
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/QualifiedNameExpr.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class QualifiedNameExpr extends NameExpr {
+
+	private NameExpr qualifier;
+
+	public QualifiedNameExpr() {
+	}
+
+	public QualifiedNameExpr(final NameExpr scope, final String name) {
+		super(name);
+		setQualifier(scope);
+	}
+
+	public QualifiedNameExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final NameExpr scope, final String name) {
+		super(beginLine, beginColumn, endLine, endColumn, name);
+		setQualifier(scope);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public NameExpr getQualifier() {
+		return qualifier;
+	}
+
+	public void setQualifier(final NameExpr qualifier) {
+		this.qualifier = qualifier;
+		setAsParentNodeOf(this.qualifier);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java
new file mode 100644
index 0000000..bd8adb1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/SingleMemberAnnotationExpr.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SingleMemberAnnotationExpr extends AnnotationExpr {
+
+	private Expression memberValue;
+
+	public SingleMemberAnnotationExpr() {
+	}
+
+	public SingleMemberAnnotationExpr(final NameExpr name, final Expression memberValue) {
+		setName(name);
+		setMemberValue(memberValue);
+	}
+
+	public SingleMemberAnnotationExpr(final int beginLine, final int beginColumn, final int endLine,
+			final int endColumn, final NameExpr name, final Expression memberValue) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setName(name);
+		setMemberValue(memberValue);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getMemberValue() {
+		return memberValue;
+	}
+
+	public void setMemberValue(final Expression memberValue) {
+		this.memberValue = memberValue;
+		setAsParentNodeOf(this.memberValue);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/StringLiteralExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/StringLiteralExpr.java
new file mode 100644
index 0000000..6876fa2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/StringLiteralExpr.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class StringLiteralExpr extends LiteralExpr {
+
+	protected String value;
+
+	public StringLiteralExpr() {
+	}
+
+	public StringLiteralExpr(final String value) {
+		this.value = value;
+	}
+
+	public StringLiteralExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String value) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		this.value = value;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public final String getValue() {
+		return value;
+	}
+
+	public final void setValue(final String value) {
+		this.value = value;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/SuperExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/SuperExpr.java
new file mode 100644
index 0000000..791d28b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/SuperExpr.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SuperExpr extends Expression {
+
+	private Expression classExpr;
+
+	public SuperExpr() {
+	}
+
+	public SuperExpr(final Expression classExpr) {
+		setClassExpr(classExpr);
+	}
+
+	public SuperExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression classExpr) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setClassExpr(classExpr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getClassExpr() {
+		return classExpr;
+	}
+
+	public void setClassExpr(final Expression classExpr) {
+		this.classExpr = classExpr;
+		setAsParentNodeOf(this.classExpr);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ThisExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ThisExpr.java
new file mode 100644
index 0000000..c269376
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/ThisExpr.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ThisExpr extends Expression {
+
+	private Expression classExpr;
+
+	public ThisExpr() {
+	}
+
+	public ThisExpr(final Expression classExpr) {
+		setClassExpr(classExpr);
+	}
+
+	public ThisExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression classExpr) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setClassExpr(classExpr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getClassExpr() {
+		return classExpr;
+	}
+
+	public void setClassExpr(final Expression classExpr) {
+		this.classExpr = classExpr;
+		setAsParentNodeOf(this.classExpr);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/TypeExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/TypeExpr.java
new file mode 100644
index 0000000..636d2c4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/TypeExpr.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * This class is just instantiated as scopes for MethodReferenceExpr nodes to encapsulate Types.
+ * @author Raquel Pau
+ *
+ */
+public class TypeExpr extends Expression{
+
+    private Type type;
+
+    public TypeExpr(){}
+
+    public TypeExpr(int beginLine, int beginColumn, int endLine, int endColumn, Type type) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setType(type);
+    }
+
+    @Override
+    public <R, A> R accept(GenericVisitor<R, A> v, A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(VoidVisitor<A> v, A arg) {
+        v.visit(this, arg);
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public void setType(Type type) {
+        this.type = type;
+        setAsParentNodeOf(this.type);
+    }
+
+
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/UnaryExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/UnaryExpr.java
new file mode 100644
index 0000000..19d9360
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/UnaryExpr.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class UnaryExpr extends Expression {
+
+	public static enum Operator {
+		positive, // +
+		negative, // -
+		preIncrement, // ++
+		preDecrement, // --
+		not, // !
+		inverse, // ~
+		posIncrement, // ++
+		posDecrement, // --
+	}
+
+	private Expression expr;
+
+	private Operator op;
+
+	public UnaryExpr() {
+	}
+
+	public UnaryExpr(final Expression expr, final Operator op) {
+		setExpr(expr);
+		setOperator(op);
+	}
+
+	public UnaryExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression expr, final Operator op) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setExpr(expr);
+		setOperator(op);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public Operator getOperator() {
+		return op;
+	}
+
+	public void setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+	}
+
+	public void setOperator(final Operator op) {
+		this.op = op;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/VariableDeclarationExpr.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/VariableDeclarationExpr.java
new file mode 100644
index 0000000..2dcaa22
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/expr/VariableDeclarationExpr.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ast.body.ModifierSet;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VariableDeclarationExpr extends Expression {
+
+	private int modifiers;
+
+	private List<AnnotationExpr> annotations;
+
+	private Type type;
+
+	private List<VariableDeclarator> vars;
+
+	public VariableDeclarationExpr() {
+	}
+
+	public VariableDeclarationExpr(final Type type, final List<VariableDeclarator> vars) {
+		setType(type);
+		setVars(vars);
+	}
+
+	public VariableDeclarationExpr(final int modifiers, final Type type, final List<VariableDeclarator> vars) {
+		setModifiers(modifiers);
+		setType(type);
+		setVars(vars);
+	}
+
+	public VariableDeclarationExpr(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final int modifiers, final List<AnnotationExpr> annotations, final Type type,
+			final List<VariableDeclarator> vars) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setModifiers(modifiers);
+		setAnnotations(annotations);
+		setType(type);
+		setVars(vars);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<AnnotationExpr> getAnnotations() {
+		return annotations;
+	}
+
+	/**
+	 * Return the modifiers of this variable declaration.
+	 * 
+	 * @see ModifierSet
+	 * @return modifiers
+	 */
+	public int getModifiers() {
+		return modifiers;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public List<VariableDeclarator> getVars() {
+		return vars;
+	}
+
+	public void setAnnotations(final List<AnnotationExpr> annotations) {
+		this.annotations = annotations;
+		setAsParentNodeOf(this.annotations);
+	}
+
+	public void setModifiers(final int modifiers) {
+		this.modifiers = modifiers;
+	}
+
+	public void setType(final Type type) {
+		this.type = type;
+		setAsParentNodeOf(this.type);
+	}
+
+	public void setVars(final List<VariableDeclarator> vars) {
+		this.vars = vars;
+		setAsParentNodeOf(this.vars);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/internal/Utils.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/internal/Utils.java
new file mode 100644
index 0000000..0bb7abb
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/internal/Utils.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Federico Tomassetti
+ * @since 2.0.1
+ */
+public class Utils {
+
+    public static <T> List<T> ensureNotNull(List<T> list) {
+        return list == null ? Collections.<T>emptyList() : list;
+    }
+
+    public static <E> boolean isNullOrEmpty(Collection<E> collection) {
+        return collection == null || collection.isEmpty();
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/AssertStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/AssertStmt.java
new file mode 100644
index 0000000..60f61bc
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/AssertStmt.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class AssertStmt extends Statement {
+
+	private Expression check;
+
+	private Expression msg;
+
+	public AssertStmt() {
+	}
+
+	public AssertStmt(final Expression check) {
+		setCheck(check);
+	}
+
+	public AssertStmt(final Expression check, final Expression msg) {
+		setCheck(check);
+		setMessage(msg);
+	}
+
+	public AssertStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression check, final Expression msg) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		
+		setCheck(check);
+		setMessage(msg);
+		
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getCheck() {
+		return check;
+	}
+
+	public Expression getMessage() {
+		return msg;
+	}
+
+	public void setCheck(final Expression check) {
+		this.check = check;
+		setAsParentNodeOf(this.check);
+	}
+
+	public void setMessage(final Expression msg) {
+		this.msg = msg;
+		setAsParentNodeOf(this.msg);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/BlockStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/BlockStmt.java
new file mode 100644
index 0000000..d8b1673
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/BlockStmt.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BlockStmt extends Statement {
+
+	private List<Statement> stmts;
+
+	public BlockStmt() {
+	}
+
+	public BlockStmt(final List<Statement> stmts) {
+		setStmts(stmts);
+	}
+
+	public BlockStmt(final int beginLine, final int beginColumn,
+			final int endLine, final int endColumn, final List<Statement> stmts) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setStmts(stmts);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<Statement> getStmts() {
+		return stmts;
+	}
+
+	public void setStmts(final List<Statement> stmts) {
+		this.stmts = stmts;
+		setAsParentNodeOf(this.stmts);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/BreakStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/BreakStmt.java
new file mode 100644
index 0000000..1a80f3e
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/BreakStmt.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class BreakStmt extends Statement {
+
+	private String id;
+
+	public BreakStmt() {
+	}
+
+	public BreakStmt(final String id) {
+		this.id = id;
+	}
+
+	public BreakStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn, final String id) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		this.id = id;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(final String id) {
+		this.id = id;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/CatchClause.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/CatchClause.java
new file mode 100644
index 0000000..3f43e79
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/CatchClause.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class CatchClause extends Node {
+
+    private MultiTypeParameter except;
+
+    private BlockStmt catchBlock;
+
+    public CatchClause() {
+    }
+
+    public CatchClause(final MultiTypeParameter except, final BlockStmt catchBlock) {
+        setExcept(except);
+        setCatchBlock(catchBlock);
+    }
+	
+    public CatchClause(int exceptModifier, List<AnnotationExpr> exceptAnnotations, List<Type> exceptTypes, VariableDeclaratorId exceptId, BlockStmt catchBlock) {
+        this(new MultiTypeParameter(exceptModifier, exceptAnnotations, exceptTypes, exceptId), catchBlock);
+    }
+
+    public CatchClause(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+    	    final int exceptModifier, final List<AnnotationExpr> exceptAnnotations, final List<Type> exceptTypes, 
+    	    final VariableDeclaratorId exceptId, final BlockStmt catchBlock) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setExcept(new MultiTypeParameter(beginLine, beginColumn, endLine, endColumn, exceptModifier, exceptAnnotations, exceptTypes, exceptId));
+        setCatchBlock(catchBlock);
+    }
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public BlockStmt getCatchBlock() {
+		return catchBlock;
+	}
+
+	public MultiTypeParameter getExcept() {
+		return except;
+	}
+
+	public void setCatchBlock(final BlockStmt catchBlock) {
+		this.catchBlock = catchBlock;
+		setAsParentNodeOf(this.catchBlock);
+	}
+
+	public void setExcept(final MultiTypeParameter except) {
+		this.except = except;
+		setAsParentNodeOf(this.except);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ContinueStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ContinueStmt.java
new file mode 100644
index 0000000..81760d0
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ContinueStmt.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ContinueStmt extends Statement {
+
+	private String id;
+
+	public ContinueStmt() {
+	}
+
+	public ContinueStmt(final String id) {
+		this.id = id;
+	}
+
+	public ContinueStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String id) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		this.id = id;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(final String id) {
+		this.id = id;
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/DoStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/DoStmt.java
new file mode 100644
index 0000000..0a6a770
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/DoStmt.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class DoStmt extends Statement {
+
+	private Statement body;
+
+	private Expression condition;
+
+	public DoStmt() {
+	}
+
+	public DoStmt(final Statement body, final Expression condition) {
+		setBody(body);
+		setCondition(condition);
+	}
+
+	public DoStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Statement body, final Expression condition) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setBody(body);
+		setCondition(condition);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Statement getBody() {
+		return body;
+	}
+
+	public Expression getCondition() {
+		return condition;
+	}
+
+	public void setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+	}
+
+	public void setCondition(final Expression condition) {
+		this.condition = condition;
+		setAsParentNodeOf(this.condition);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/EmptyStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/EmptyStmt.java
new file mode 100644
index 0000000..fb16c4d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/EmptyStmt.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class EmptyStmt extends Statement {
+
+	public EmptyStmt() {
+	}
+
+	public EmptyStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java
new file mode 100644
index 0000000..d0a9efe
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ExplicitConstructorInvocationStmt.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ExplicitConstructorInvocationStmt extends Statement {
+
+	private List<Type> typeArgs;
+
+	private boolean isThis;
+
+	private Expression expr;
+
+	private List<Expression> args;
+
+	public ExplicitConstructorInvocationStmt() {
+	}
+
+	public ExplicitConstructorInvocationStmt(final boolean isThis,
+			final Expression expr, final List<Expression> args) {
+		setThis(isThis);
+		setExpr(expr);
+		setArgs(args);
+	}
+
+	public ExplicitConstructorInvocationStmt(final int beginLine,
+			final int beginColumn, final int endLine, final int endColumn,
+			final List<Type> typeArgs, final boolean isThis,
+			final Expression expr, final List<Expression> args) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setTypeArgs(typeArgs);
+		setThis(isThis);
+		setExpr(expr);
+		setArgs(args);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<Expression> getArgs() {
+		return args;
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public List<Type> getTypeArgs() {
+		return typeArgs;
+	}
+
+	public boolean isThis() {
+		return isThis;
+	}
+
+	public void setArgs(final List<Expression> args) {
+		this.args = args;
+		setAsParentNodeOf(this.args);
+	}
+
+	public void setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+	}
+
+	public void setThis(final boolean isThis) {
+		this.isThis = isThis;
+	}
+
+	public void setTypeArgs(final List<Type> typeArgs) {
+		this.typeArgs = typeArgs;
+		setAsParentNodeOf(this.typeArgs);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ExpressionStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ExpressionStmt.java
new file mode 100644
index 0000000..3c441e2
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ExpressionStmt.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ExpressionStmt extends Statement {
+
+	private Expression expr;
+
+	public ExpressionStmt() {
+	}
+
+	public ExpressionStmt(final Expression expr) {
+		setExpression(expr);
+	}
+
+	public ExpressionStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression expr) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setExpression(expr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpression() {
+		return expr;
+	}
+
+	public void setExpression(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ForStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ForStmt.java
new file mode 100644
index 0000000..8e349bf
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ForStmt.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ForStmt extends Statement {
+
+	private List<Expression> init;
+
+	private Expression compare;
+
+	private List<Expression> update;
+
+	private Statement body;
+
+	public ForStmt() {
+	}
+
+	public ForStmt(final List<Expression> init, final Expression compare,
+			final List<Expression> update, final Statement body) {
+		setCompare(compare);
+		setInit(init);
+		setUpdate(update);
+		setBody(body);
+	}
+
+	public ForStmt(final int beginLine, final int beginColumn,
+			final int endLine, final int endColumn,
+			final List<Expression> init, final Expression compare,
+			final List<Expression> update, final Statement body) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setCompare(compare);
+		setInit(init);
+		setUpdate(update);
+		setBody(body);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Statement getBody() {
+		return body;
+	}
+
+	public Expression getCompare() {
+		return compare;
+	}
+
+	public List<Expression> getInit() {
+		return init;
+	}
+
+	public List<Expression> getUpdate() {
+		return update;
+	}
+
+	public void setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+	}
+
+	public void setCompare(final Expression compare) {
+		this.compare = compare;
+		setAsParentNodeOf(this.compare);
+	}
+
+	public void setInit(final List<Expression> init) {
+		this.init = init;
+		setAsParentNodeOf(this.init);
+	}
+
+	public void setUpdate(final List<Expression> update) {
+		this.update = update;
+		setAsParentNodeOf(this.update);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ForeachStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ForeachStmt.java
new file mode 100644
index 0000000..245622f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ForeachStmt.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ForeachStmt extends Statement {
+
+	private VariableDeclarationExpr var;
+
+	private Expression iterable;
+
+	private Statement body;
+
+	public ForeachStmt() {
+	}
+
+	public ForeachStmt(final VariableDeclarationExpr var,
+			final Expression iterable, final Statement body) {
+		setVariable(var);
+		setIterable(iterable);
+		setBody(body);
+	}
+
+	public ForeachStmt(final int beginLine, final int beginColumn,
+			final int endLine, final int endColumn,
+			final VariableDeclarationExpr var, final Expression iterable,
+			final Statement body) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setVariable(var);
+		setIterable(iterable);
+		setBody(body);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Statement getBody() {
+		return body;
+	}
+
+	public Expression getIterable() {
+		return iterable;
+	}
+
+	public VariableDeclarationExpr getVariable() {
+		return var;
+	}
+
+	public void setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+	}
+
+	public void setIterable(final Expression iterable) {
+		this.iterable = iterable;
+		setAsParentNodeOf(this.iterable);
+	}
+
+	public void setVariable(final VariableDeclarationExpr var) {
+		this.var = var;
+		setAsParentNodeOf(this.var);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/IfStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/IfStmt.java
new file mode 100644
index 0000000..ccddd90
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/IfStmt.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class IfStmt extends Statement {
+
+	private Expression condition;
+
+	private Statement thenStmt;
+
+	private Statement elseStmt;
+
+	public IfStmt() {
+	}
+
+	public IfStmt(final Expression condition, final Statement thenStmt, final Statement elseStmt) {
+		setCondition(condition);
+		setThenStmt(thenStmt);
+		setElseStmt(elseStmt);
+	}
+
+	public IfStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression condition, final Statement thenStmt, final Statement elseStmt) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setCondition(condition);
+		setThenStmt(thenStmt);
+		setElseStmt(elseStmt);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getCondition() {
+		return condition;
+	}
+
+	public Statement getElseStmt() {
+		return elseStmt;
+	}
+
+	public Statement getThenStmt() {
+		return thenStmt;
+	}
+
+	public void setCondition(final Expression condition) {
+		this.condition = condition;
+		setAsParentNodeOf(this.condition);
+	}
+
+	public void setElseStmt(final Statement elseStmt) {
+		this.elseStmt = elseStmt;
+		setAsParentNodeOf(this.elseStmt);
+	}
+
+	public void setThenStmt(final Statement thenStmt) {
+		this.thenStmt = thenStmt;
+		setAsParentNodeOf(this.thenStmt);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/LabeledStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/LabeledStmt.java
new file mode 100644
index 0000000..85d8e7b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/LabeledStmt.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class LabeledStmt extends Statement {
+
+	private String label;
+
+	private Statement stmt;
+
+	public LabeledStmt() {
+	}
+
+	public LabeledStmt(final String label, final Statement stmt) {
+		setLabel(label);
+		setStmt(stmt);
+	}
+
+	public LabeledStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final String label, final Statement stmt) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setLabel(label);
+		setStmt(stmt);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public String getLabel() {
+		return label;
+	}
+
+	public Statement getStmt() {
+		return stmt;
+	}
+
+	public void setLabel(final String label) {
+		this.label = label;
+	}
+
+	public void setStmt(final Statement stmt) {
+		this.stmt = stmt;
+		setAsParentNodeOf(this.stmt);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ReturnStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ReturnStmt.java
new file mode 100644
index 0000000..3ac6fa6
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ReturnStmt.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ReturnStmt extends Statement {
+
+	private Expression expr;
+
+	public ReturnStmt() {
+	}
+
+	public ReturnStmt(final Expression expr) {
+		setExpr(expr);
+	}
+
+	public ReturnStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression expr) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setExpr(expr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public void setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/Statement.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/Statement.java
new file mode 100644
index 0000000..30c462d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/Statement.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.Node;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Statement extends Node {
+
+	public Statement() {
+	}
+
+	public Statement(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SwitchEntryStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SwitchEntryStmt.java
new file mode 100644
index 0000000..8f5a85a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SwitchEntryStmt.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SwitchEntryStmt extends Statement {
+
+	private Expression label;
+
+	private List<Statement> stmts;
+
+	public SwitchEntryStmt() {
+	}
+
+	public SwitchEntryStmt(final Expression label, final List<Statement> stmts) {
+		setLabel(label);
+		setStmts(stmts);
+	}
+
+	public SwitchEntryStmt(final int beginLine, final int beginColumn,
+			final int endLine, final int endColumn, final Expression label,
+			final List<Statement> stmts) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setLabel(label);
+		setStmts(stmts);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getLabel() {
+		return label;
+	}
+
+	public List<Statement> getStmts() {
+		return stmts;
+	}
+
+	public void setLabel(final Expression label) {
+		this.label = label;
+		setAsParentNodeOf(this.label);
+	}
+
+	public void setStmts(final List<Statement> stmts) {
+		this.stmts = stmts;
+		setAsParentNodeOf(this.stmts);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SwitchStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SwitchStmt.java
new file mode 100644
index 0000000..49fe903
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SwitchStmt.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SwitchStmt extends Statement {
+
+	private Expression selector;
+
+	private List<SwitchEntryStmt> entries;
+
+	public SwitchStmt() {
+	}
+
+	public SwitchStmt(final Expression selector,
+			final List<SwitchEntryStmt> entries) {
+		setSelector(selector);
+		setEntries(entries);
+	}
+
+	public SwitchStmt(final int beginLine, final int beginColumn,
+			final int endLine, final int endColumn, final Expression selector,
+			final List<SwitchEntryStmt> entries) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setSelector(selector);
+		setEntries(entries);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<SwitchEntryStmt> getEntries() {
+		return entries;
+	}
+
+	public Expression getSelector() {
+		return selector;
+	}
+
+	public void setEntries(final List<SwitchEntryStmt> entries) {
+		this.entries = entries;
+		setAsParentNodeOf(this.entries);
+	}
+
+	public void setSelector(final Expression selector) {
+		this.selector = selector;
+		setAsParentNodeOf(this.selector);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SynchronizedStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SynchronizedStmt.java
new file mode 100644
index 0000000..e91fc0b
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/SynchronizedStmt.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class SynchronizedStmt extends Statement {
+
+	private Expression expr;
+
+	private BlockStmt block;
+
+	public SynchronizedStmt() {
+	}
+
+	public SynchronizedStmt(final Expression expr, final BlockStmt block) {
+		setExpr(expr);
+		setBlock(block);
+	}
+
+	public SynchronizedStmt(final int beginLine, final int beginColumn,
+			final int endLine, final int endColumn, final Expression expr,
+			final BlockStmt block) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setExpr(expr);
+		setBlock(block);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public BlockStmt getBlock() {
+		return block;
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public void setBlock(final BlockStmt block) {
+		this.block = block;
+		setAsParentNodeOf(this.block);
+	}
+
+	public void setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ThrowStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ThrowStmt.java
new file mode 100644
index 0000000..48283b1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/ThrowStmt.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ThrowStmt extends Statement {
+
+	private Expression expr;
+
+	public ThrowStmt() {
+	}
+
+	public ThrowStmt(final Expression expr) {
+		setExpr(expr);
+	}
+
+	public ThrowStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression expr) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setExpr(expr);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Expression getExpr() {
+		return expr;
+	}
+
+	public void setExpr(final Expression expr) {
+		this.expr = expr;
+		setAsParentNodeOf(this.expr);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/TryStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/TryStmt.java
new file mode 100644
index 0000000..44009c4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/TryStmt.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class TryStmt extends Statement {
+	
+	private List<VariableDeclarationExpr> resources;
+
+	private BlockStmt tryBlock;
+
+	private List<CatchClause> catchs;
+
+	private BlockStmt finallyBlock;
+
+	public TryStmt() {
+	}
+
+	public TryStmt(final BlockStmt tryBlock, final List<CatchClause> catchs,
+			final BlockStmt finallyBlock) {
+		setTryBlock(tryBlock);
+		setCatchs(catchs);
+		setFinallyBlock(finallyBlock);
+	}
+
+	public TryStmt(final int beginLine, final int beginColumn,
+			final int endLine, final int endColumn, List<VariableDeclarationExpr> resources,
+			final BlockStmt tryBlock, final List<CatchClause> catchs, final BlockStmt finallyBlock) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setResources(resources);
+		setTryBlock(tryBlock);
+		setCatchs(catchs);
+		setFinallyBlock(finallyBlock);
+	}
+
+	@Override
+	public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override
+	public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public List<CatchClause> getCatchs() {
+		return catchs;
+	}
+
+	public BlockStmt getFinallyBlock() {
+		return finallyBlock;
+	}
+
+	public BlockStmt getTryBlock() {
+		return tryBlock;
+	}
+	
+	public List<VariableDeclarationExpr> getResources() {
+		return resources;
+	}
+
+	public void setCatchs(final List<CatchClause> catchs) {
+		this.catchs = catchs;
+		setAsParentNodeOf(this.catchs);
+	}
+
+	public void setFinallyBlock(final BlockStmt finallyBlock) {
+		this.finallyBlock = finallyBlock;
+		setAsParentNodeOf(this.finallyBlock);
+	}
+
+	public void setTryBlock(final BlockStmt tryBlock) {
+		this.tryBlock = tryBlock;
+		setAsParentNodeOf(this.tryBlock);
+	}
+	
+	public void setResources(List<VariableDeclarationExpr> resources) {
+		this.resources = resources;
+		setAsParentNodeOf(this.resources);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/TypeDeclarationStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/TypeDeclarationStmt.java
new file mode 100644
index 0000000..79b507a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/TypeDeclarationStmt.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class TypeDeclarationStmt extends Statement {
+
+	private TypeDeclaration typeDecl;
+
+	public TypeDeclarationStmt() {
+	}
+
+	public TypeDeclarationStmt(final TypeDeclaration typeDecl) {
+		setTypeDeclaration(typeDecl);
+	}
+
+	public TypeDeclarationStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final TypeDeclaration typeDecl) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setTypeDeclaration(typeDecl);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public TypeDeclaration getTypeDeclaration() {
+		return typeDecl;
+	}
+
+	public void setTypeDeclaration(final TypeDeclaration typeDecl) {
+		this.typeDecl = typeDecl;
+		setAsParentNodeOf(this.typeDecl);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/WhileStmt.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/WhileStmt.java
new file mode 100644
index 0000000..51b2a1a
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/stmt/WhileStmt.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class WhileStmt extends Statement {
+
+	private Expression condition;
+
+	private Statement body;
+
+	public WhileStmt() {
+	}
+
+	public WhileStmt(final Expression condition, final Statement body) {
+		setCondition(condition);
+		setBody(body);
+	}
+
+	public WhileStmt(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Expression condition, final Statement body) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setCondition(condition);
+		setBody(body);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Statement getBody() {
+		return body;
+	}
+
+	public Expression getCondition() {
+		return condition;
+	}
+
+	public void setBody(final Statement body) {
+		this.body = body;
+		setAsParentNodeOf(this.body);
+	}
+
+	public void setCondition(final Expression condition) {
+		this.condition = condition;
+		setAsParentNodeOf(this.condition);
+	}
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/ClassOrInterfaceType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/ClassOrInterfaceType.java
new file mode 100644
index 0000000..a7efbf4
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/ClassOrInterfaceType.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ClassOrInterfaceType extends Type {
+
+    private ClassOrInterfaceType scope;
+
+    private String name;
+
+    private List<Type> typeArgs;
+
+    public ClassOrInterfaceType() {
+    }
+
+    public ClassOrInterfaceType(final String name) {
+        setName(name);
+    }
+
+    public ClassOrInterfaceType(final ClassOrInterfaceType scope, final String name) {
+        setScope(scope);
+        setName(name);
+    }
+
+    public ClassOrInterfaceType(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+                                final ClassOrInterfaceType scope, final String name, final List<Type> typeArgs) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        setScope(scope);
+        setName(name);
+        setTypeArgs(typeArgs);
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public ClassOrInterfaceType getScope() {
+        return scope;
+    }
+
+    public List<Type> getTypeArgs() {
+        return typeArgs;
+    }
+
+    public boolean isBoxedType() {
+        return PrimitiveType.unboxMap.containsKey(name);
+    }
+
+    public PrimitiveType toUnboxedType() throws UnsupportedOperationException {
+        if (!isBoxedType()) throw new UnsupportedOperationException(name + " isn't a boxed type.");
+        return new PrimitiveType(PrimitiveType.unboxMap.get(name));
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public void setScope(final ClassOrInterfaceType scope) {
+        this.scope = scope;
+        setAsParentNodeOf(this.scope);
+    }
+
+    public void setTypeArgs(final List<Type> typeArgs) {
+        this.typeArgs = typeArgs;
+        setAsParentNodeOf(this.typeArgs);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/PrimitiveType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/PrimitiveType.java
new file mode 100644
index 0000000..561a896
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/PrimitiveType.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import java.util.HashMap;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class PrimitiveType extends Type {
+
+	public enum Primitive {
+		Boolean ("Boolean"),
+		Char    ("Character"),
+		Byte    ("Byte"),
+		Short   ("Short"),
+		Int     ("Integer"),
+		Long    ("Long"),
+		Float   ("Float"),
+		Double  ("Double");
+
+		final String nameOfBoxedType;
+
+		public ClassOrInterfaceType toBoxedType() {
+			return new ClassOrInterfaceType(nameOfBoxedType);
+		}
+
+		private Primitive(String nameOfBoxedType) {
+			this.nameOfBoxedType = nameOfBoxedType;
+		}
+	}
+
+	static final HashMap<String, Primitive> unboxMap = new HashMap<String, Primitive>();
+	static {
+		for(Primitive unboxedType : Primitive.values()) {
+			unboxMap.put(unboxedType.nameOfBoxedType, unboxedType);
+		}
+	}
+
+	private Primitive type;
+
+	public PrimitiveType() {
+	}
+
+	public PrimitiveType(final Primitive type) {
+		this.type = type;
+	}
+
+	public PrimitiveType(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Primitive type) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		this.type = type;
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public Primitive getType() {
+		return type;
+	}
+
+	public ClassOrInterfaceType toBoxedType() {
+		return type.toBoxedType();
+	}
+
+	public void setType(final Primitive type) {
+		this.type = type;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/ReferenceType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/ReferenceType.java
new file mode 100644
index 0000000..608848f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/ReferenceType.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class ReferenceType extends Type {
+
+	private Type type;
+
+	private int arrayCount;
+
+    private List<List<AnnotationExpr>> arraysAnnotations;
+
+    public ReferenceType() {
+	}
+
+	public ReferenceType(final Type type) {
+		setType(type);
+	}
+
+	public ReferenceType(final Type type, final int arrayCount) {
+		setType(type);
+		setArrayCount(arrayCount);
+	}
+
+	public ReferenceType(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final Type type, final int arrayCount) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setType(type);
+		setArrayCount(arrayCount);
+	}
+
+    public ReferenceType(int beginLine, int beginColumn, int endLine,
+                         int endColumn, Type type, int arrayCount,
+                         List<AnnotationExpr> annotations,
+                         List<List<AnnotationExpr>> arraysAnnotations) {
+        super(beginLine, beginColumn, endLine, endColumn, annotations);
+        setType(type);
+        setArrayCount(arrayCount);
+        this.arraysAnnotations = arraysAnnotations;
+    }
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public int getArrayCount() {
+		return arrayCount;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public void setArrayCount(final int arrayCount) {
+		this.arrayCount = arrayCount;
+	}
+
+	public void setType(final Type type) {
+		this.type = type;
+		setAsParentNodeOf(this.type);
+	}
+
+	/**
+	 * <p>Arrays annotations are annotations on the arrays modifiers of the type.
+	 * Consider this example:</p>
+	 * 
+	 * <p><pre>
+	 * {@code
+	 * int @Ann1 [] @Ann2 [] array;
+	 * }</pre></p>
+	 * 
+	 * <p>in this this method will return a list with the annotation expressions <pre>@Ann1</pre>
+	 * and <pre>@Ann2</pre></p>
+	 * 
+	 * <p>Note that the first list element of arraysAnnotations will refer to the first array modifier encountered.
+	 * Considering the example the first element will be a list containing just @Ann1 while the second element will
+	 * be a list containing just @Ann2.
+	 * </p>
+	 *
+	 * <p>This property is guaranteed to hold: <pre>{@code getArraysAnnotations().size() == getArrayCount()}</pre>
+	 * If a certain array modifier has no annotation the corresponding entry of arraysAnnotations will be null</p>
+	 */
+    public List<List<AnnotationExpr>> getArraysAnnotations() {
+        return arraysAnnotations;
+    }
+
+	/**
+	 * For a description of the arrayAnnotations field refer to {@link #getArraysAnnotations()}
+	 */
+    public void setArraysAnnotations(List<List<AnnotationExpr>> arraysAnnotations) {
+        this.arraysAnnotations = arraysAnnotations;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/Type.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/Type.java
new file mode 100644
index 0000000..22c9124
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/Type.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class Type extends Node {
+
+    private List<AnnotationExpr> annotations;
+
+    public Type() {
+    }
+
+    public Type(List<AnnotationExpr> annotation){
+        this.annotations = annotation;
+    }
+
+    public Type(int beginLine, int beginColumn, int endLine, int endColumn) {
+        super(beginLine, beginColumn, endLine, endColumn);
+    }
+
+    public Type(int beginLine, int beginColumn, int endLine, int endColumn, List<AnnotationExpr> annotations) {
+        super(beginLine, beginColumn, endLine, endColumn);
+        this.annotations = annotations;
+    }
+
+    public List<AnnotationExpr> getAnnotations() {
+        return annotations;
+    }
+
+    public void setAnnotations(List<AnnotationExpr> annotations) {
+        this.annotations = annotations;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/UnknownType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/UnknownType.java
new file mode 100644
index 0000000..af6d4d9
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/UnknownType.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * An unknown parameter type object. It plays the role of a null object for
+ * lambda parameters that have no explicit type declared. As such, it has no
+ * lexical representation and hence gets no comment attributed.
+ *
+ * @author Didier Villevalois
+ */
+public final class UnknownType extends Type {
+
+    public UnknownType() {
+    }
+
+    @Override
+    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+        return v.visit(this, arg);
+    }
+
+    @Override
+    public <A> void accept(final VoidVisitor<A> v, final A arg) {
+        v.visit(this, arg);
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/VoidType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/VoidType.java
new file mode 100644
index 0000000..5dacbe1
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/VoidType.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class VoidType extends Type {
+
+	public VoidType() {
+	}
+
+	public VoidType(final int beginLine, final int beginColumn, final int endLine, final int endColumn) {
+		super(beginLine, beginColumn, endLine, endColumn);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/WildcardType.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/WildcardType.java
new file mode 100644
index 0000000..8016ed7
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/type/WildcardType.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.visitor.GenericVisitor;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public final class WildcardType extends Type {
+
+	private ReferenceType ext;
+
+	private ReferenceType sup;
+
+	public WildcardType() {
+	}
+
+	public WildcardType(final ReferenceType ext) {
+		setExtends(ext);
+	}
+
+	public WildcardType(final ReferenceType ext, final ReferenceType sup) {
+		setExtends(ext);
+		setSuper(sup);
+	}
+
+	public WildcardType(final int beginLine, final int beginColumn, final int endLine, final int endColumn,
+			final ReferenceType ext, final ReferenceType sup) {
+		super(beginLine, beginColumn, endLine, endColumn);
+		setExtends(ext);
+		setSuper(sup);
+	}
+
+	@Override public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
+		return v.visit(this, arg);
+	}
+
+	@Override public <A> void accept(final VoidVisitor<A> v, final A arg) {
+		v.visit(this, arg);
+	}
+
+	public ReferenceType getExtends() {
+		return ext;
+	}
+
+	public ReferenceType getSuper() {
+		return sup;
+	}
+
+	public void setExtends(final ReferenceType ext) {
+		this.ext = ext;
+		setAsParentNodeOf(this.ext);
+	}
+
+	public void setSuper(final ReferenceType sup) {
+		this.sup = sup;
+		setAsParentNodeOf(this.sup);
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/CloneVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/CloneVisitor.java
new file mode 100644
index 0000000..3d8d299
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/CloneVisitor.java
@@ -0,0 +1,1211 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+
+public class CloneVisitor implements GenericVisitor<Node, Object> {
+
+	@Override
+	public Node visit(CompilationUnit _n, Object _arg) {
+		PackageDeclaration package_ = cloneNodes(_n.getPackage(), _arg);
+		List<ImportDeclaration> imports = visit(_n.getImports(), _arg);
+		List<TypeDeclaration> types = visit(_n.getTypes(), _arg);
+
+		return new CompilationUnit(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				package_, imports, types
+		);
+	}
+
+	@Override
+	public Node visit(PackageDeclaration _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		PackageDeclaration r = new PackageDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				annotations, name
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ImportDeclaration _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ImportDeclaration r = new ImportDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				name, _n.isStatic(), _n.isAsterisk()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(TypeParameter _n, Object _arg) {
+        List<ClassOrInterfaceType> typeBound = visit(_n.getTypeBound(), _arg);
+
+        List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+        TypeParameter r = new TypeParameter(_n.getBeginLine(),
+                _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+                _n.getName(), typeBound, annotations);
+
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LineComment _n, Object _arg) {
+		return new LineComment(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getContent());
+	}
+
+	@Override
+	public Node visit(BlockComment _n, Object _arg) {
+		return new BlockComment(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), _n.getContent());
+	}
+
+	@Override
+	public Node visit(ClassOrInterfaceDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg);
+		List<ClassOrInterfaceType> extendsList = visit(_n.getExtends(), _arg);
+		List<ClassOrInterfaceType> implementsList = visit(_n.getImplements(), _arg);
+		List<BodyDeclaration> members = visit(_n.getMembers(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ClassOrInterfaceDeclaration r = new ClassOrInterfaceDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getModifiers(), annotations, _n.isInterface(), _n.getName(), typeParameters, extendsList, implementsList, members
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EnumDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<ClassOrInterfaceType> implementsList = visit(_n.getImplements(), _arg);
+		List<EnumConstantDeclaration> entries = visit(_n.getEntries(), _arg);
+		List<BodyDeclaration> members = visit(_n.getMembers(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EnumDeclaration r = new EnumDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 _n.getModifiers(), annotations, _n.getName(), implementsList, entries, members
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EmptyTypeDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EmptyTypeDeclaration r = new EmptyTypeDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EnumConstantDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<Expression> args = visit(_n.getArgs(), _arg);
+		List<BodyDeclaration> classBody = visit(_n.getClassBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EnumConstantDeclaration r = new EnumConstantDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 annotations, _n.getName(), args, classBody
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AnnotationDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<BodyDeclaration> members = visit(_n.getMembers(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AnnotationDeclaration r = new AnnotationDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 _n.getModifiers(), annotations, _n.getName(), members
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AnnotationMemberDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		Expression defaultValue = cloneNodes(_n.getDefaultValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AnnotationMemberDeclaration r = new AnnotationMemberDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 _n.getModifiers(), annotations, type_, _n.getName(), defaultValue
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(FieldDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		List<VariableDeclarator> variables = visit(_n.getVariables(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		FieldDeclaration r = new FieldDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 _n.getModifiers(), annotations, type_, variables
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(VariableDeclarator _n, Object _arg) {
+		VariableDeclaratorId id = cloneNodes(_n.getId(), _arg);
+		Expression init = cloneNodes(_n.getInit(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		VariableDeclarator r = new VariableDeclarator(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				id, init
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(VariableDeclaratorId _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		VariableDeclaratorId r = new VariableDeclaratorId(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getName(), _n.getArrayCount()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ConstructorDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg);
+		List<Parameter> parameters = visit(_n.getParameters(), _arg);
+		List<NameExpr> throws_ = visit(_n.getThrows(), _arg);
+		BlockStmt block = cloneNodes(_n.getBlock(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ConstructorDeclaration r = new ConstructorDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 _n.getModifiers(), annotations, typeParameters, _n.getName(), parameters, throws_, block
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MethodDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<TypeParameter> typeParameters = visit(_n.getTypeParameters(), _arg);
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		List<Parameter> parameters = visit(_n.getParameters(), _arg);
+		List<NameExpr> throws_ = visit(_n.getThrows(), _arg);
+		BlockStmt block = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MethodDeclaration r = new MethodDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 _n.getModifiers(), annotations, typeParameters, type_, _n.getName(), parameters, _n.getArrayCount(), throws_, block
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(Parameter _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		VariableDeclaratorId id = cloneNodes(_n.getId(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		Parameter r = new Parameter(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getModifiers(), annotations, type_, _n.isVarArgs(), id
+		);
+		r.setComment(comment);
+		return r;
+	}
+	
+	@Override
+	public Node visit(MultiTypeParameter _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		List<Type> types = visit(_n.getTypes(), _arg);
+		VariableDeclaratorId id = cloneNodes(_n.getId(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MultiTypeParameter r = new MultiTypeParameter(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getModifiers(), annotations, types, id
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EmptyMemberDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EmptyMemberDeclaration r = new EmptyMemberDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(InitializerDeclaration _n, Object _arg) {
+		JavadocComment javaDoc = cloneNodes(_n.getJavaDoc(), _arg);
+		BlockStmt block = cloneNodes(_n.getBlock(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		InitializerDeclaration r = new InitializerDeclaration(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				 _n.isStatic(), block
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(JavadocComment _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		JavadocComment r = new JavadocComment(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getContent()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ClassOrInterfaceType _n, Object _arg) {
+		ClassOrInterfaceType scope = cloneNodes(_n.getScope(), _arg);
+		List<Type> typeArgs = visit(_n.getTypeArgs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ClassOrInterfaceType r = new ClassOrInterfaceType(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				scope, _n.getName(), typeArgs
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(PrimitiveType _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		PrimitiveType r = new PrimitiveType(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getType()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ReferenceType _n, Object _arg) {
+		List<AnnotationExpr> ann = visit(_n.getAnnotations(), _arg);
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		List<List<AnnotationExpr>> arraysAnnotations = _n.getArraysAnnotations();
+		List<List<AnnotationExpr>> _arraysAnnotations = null;
+		if(arraysAnnotations != null){
+			_arraysAnnotations = new LinkedList<List<AnnotationExpr>>();
+			for(List<AnnotationExpr> aux: arraysAnnotations){
+				_arraysAnnotations.add(visit(aux, _arg));
+			}
+		}
+
+        ReferenceType r = new ReferenceType(_n.getBeginLine(),
+                _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_,
+                _n.getArrayCount(), ann, _arraysAnnotations);
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(VoidType _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		VoidType r = new VoidType(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(WildcardType _n, Object _arg) {
+		ReferenceType ext = cloneNodes(_n.getExtends(), _arg);
+		ReferenceType sup = cloneNodes(_n.getSuper(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		WildcardType r = new WildcardType(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				ext, sup
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(UnknownType _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		UnknownType r = new UnknownType();
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayAccessExpr _n, Object _arg) {
+		Expression name = cloneNodes(_n.getName(), _arg);
+		Expression index = cloneNodes(_n.getIndex(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ArrayAccessExpr r = new ArrayAccessExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				name, index
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayCreationExpr _n, Object _arg) {
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		List<Expression> dimensions = visit(_n.getDimensions(), _arg);
+		ArrayCreationExpr r = new ArrayCreationExpr(_n.getBeginLine(),
+				_n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), type_,
+				dimensions, _n.getArrayCount());
+		if (_n.getInitializer() != null) {// ArrayCreationExpr has two mutually
+			// exclusive constructors
+			r.setInitializer(cloneNodes(_n.getInitializer(), _arg));
+		}
+		List<List<AnnotationExpr>> arraysAnnotations = _n.getArraysAnnotations();
+		List<List<AnnotationExpr>> _arraysAnnotations = null;
+		if(arraysAnnotations != null){
+			_arraysAnnotations = new LinkedList<List<AnnotationExpr>>();
+			for(List<AnnotationExpr> aux: arraysAnnotations){
+				_arraysAnnotations.add(visit(aux, _arg));
+			}
+		}
+		r.setArraysAnnotations(_arraysAnnotations);
+        Comment comment = cloneNodes(_n.getComment(), _arg);
+        r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ArrayInitializerExpr _n, Object _arg) {
+		List<Expression> values = visit(_n.getValues(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ArrayInitializerExpr r = new ArrayInitializerExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				values
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AssignExpr _n, Object _arg) {
+		Expression target = cloneNodes(_n.getTarget(), _arg);
+		Expression value = cloneNodes(_n.getValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AssignExpr r = new AssignExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				target, value, _n.getOperator());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BinaryExpr _n, Object _arg) {
+		Expression left = cloneNodes(_n.getLeft(), _arg);
+		Expression right = cloneNodes(_n.getRight(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BinaryExpr r = new BinaryExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				left, right, _n.getOperator()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(CastExpr _n, Object _arg) {
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		CastExpr r = new CastExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				type_, expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ClassExpr _n, Object _arg) {
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ClassExpr r = new ClassExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				type_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ConditionalExpr _n, Object _arg) {
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Expression thenExpr = cloneNodes(_n.getThenExpr(), _arg);
+		Expression elseExpr = cloneNodes(_n.getElseExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ConditionalExpr r = new ConditionalExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				condition, thenExpr, elseExpr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EnclosedExpr _n, Object _arg) {
+		Expression inner = cloneNodes(_n.getInner(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EnclosedExpr r = new EnclosedExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				inner
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(FieldAccessExpr _n, Object _arg) {
+		Expression scope = cloneNodes(_n.getScope(), _arg);
+		List<Type> typeArgs = visit(_n.getTypeArgs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		FieldAccessExpr r = new FieldAccessExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				scope, typeArgs, _n.getField()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(InstanceOfExpr _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		InstanceOfExpr r = new InstanceOfExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				expr, type_
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(StringLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+		StringLiteralExpr r = new StringLiteralExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(IntegerLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		IntegerLiteralExpr r = new IntegerLiteralExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LongLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		LongLiteralExpr r = new LongLiteralExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(IntegerLiteralMinValueExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		IntegerLiteralMinValueExpr r = new IntegerLiteralMinValueExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LongLiteralMinValueExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		LongLiteralMinValueExpr r = new LongLiteralMinValueExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(CharLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		CharLiteralExpr r = new CharLiteralExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(DoubleLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		DoubleLiteralExpr r = new DoubleLiteralExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BooleanLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BooleanLiteralExpr r = new BooleanLiteralExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getValue()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(NullLiteralExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		NullLiteralExpr r = new NullLiteralExpr(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MethodCallExpr _n, Object _arg) {
+		Expression scope = cloneNodes(_n.getScope(), _arg);
+		List<Type> typeArgs = visit(_n.getTypeArgs(), _arg);
+		List<Expression> args = visit(_n.getArgs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MethodCallExpr r = new MethodCallExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				scope, typeArgs, _n.getName(), args
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(NameExpr _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		NameExpr r = new NameExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getName()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ObjectCreationExpr _n, Object _arg) {
+		Expression scope = cloneNodes(_n.getScope(), _arg);
+		ClassOrInterfaceType type_ = cloneNodes(_n.getType(), _arg);
+		List<Type> typeArgs = visit(_n.getTypeArgs(), _arg);
+		List<Expression> args = visit(_n.getArgs(), _arg);
+		List<BodyDeclaration> anonymousBody = visit(_n.getAnonymousClassBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ObjectCreationExpr r = new ObjectCreationExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				scope, type_, typeArgs, args, anonymousBody
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(QualifiedNameExpr _n, Object _arg) {
+		NameExpr scope = cloneNodes(_n.getQualifier(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		QualifiedNameExpr r = new QualifiedNameExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				scope, _n.getName()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ThisExpr _n, Object _arg) {
+		Expression classExpr = cloneNodes(_n.getClassExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ThisExpr r = new ThisExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				classExpr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SuperExpr _n, Object _arg) {
+		Expression classExpr = cloneNodes(_n.getClassExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SuperExpr r = new SuperExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				classExpr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(UnaryExpr _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		UnaryExpr r = new UnaryExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				expr, _n.getOperator()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(VariableDeclarationExpr _n, Object _arg) {
+		List<AnnotationExpr> annotations = visit(_n.getAnnotations(), _arg);
+		Type type_ = cloneNodes(_n.getType(), _arg);
+		List<VariableDeclarator> vars = visit(_n.getVars(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		VariableDeclarationExpr r = new VariableDeclarationExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getModifiers(), annotations, type_, vars
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MarkerAnnotationExpr _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MarkerAnnotationExpr r = new MarkerAnnotationExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				name
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SingleMemberAnnotationExpr _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		Expression memberValue = cloneNodes(_n.getMemberValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SingleMemberAnnotationExpr r = new SingleMemberAnnotationExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				name, memberValue
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(NormalAnnotationExpr _n, Object _arg) {
+		NameExpr name = cloneNodes(_n.getName(), _arg);
+		List<MemberValuePair> pairs = visit(_n.getPairs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		NormalAnnotationExpr r = new NormalAnnotationExpr(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				name, pairs
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(MemberValuePair _n, Object _arg) {
+		Expression value = cloneNodes(_n.getValue(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		MemberValuePair r = new MemberValuePair(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getName(), value
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ExplicitConstructorInvocationStmt _n, Object _arg) {
+		List<Type> typeArgs = visit(_n.getTypeArgs(), _arg);
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		List<Expression> args = visit(_n.getArgs(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ExplicitConstructorInvocationStmt r = new ExplicitConstructorInvocationStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				typeArgs, _n.isThis(), expr, args
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(TypeDeclarationStmt _n, Object _arg) {
+		TypeDeclaration typeDecl = cloneNodes(_n.getTypeDeclaration(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		TypeDeclarationStmt r = new TypeDeclarationStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				typeDecl
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(AssertStmt _n, Object _arg) {
+		Expression check = cloneNodes(_n.getCheck(), _arg);
+		Expression message = cloneNodes(_n.getMessage(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		AssertStmt r = new AssertStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				check, message
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BlockStmt _n, Object _arg) {
+		List<Statement> stmts = visit(_n.getStmts(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BlockStmt r = new BlockStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				stmts
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LabeledStmt _n, Object _arg) {
+		Statement stmt = cloneNodes(_n.getStmt(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		LabeledStmt r = new LabeledStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getLabel(), stmt
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(EmptyStmt _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		EmptyStmt r = new EmptyStmt(_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn());
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ExpressionStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpression(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ExpressionStmt r = new ExpressionStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SwitchStmt _n, Object _arg) {
+		Expression selector = cloneNodes(_n.getSelector(), _arg);
+		List<SwitchEntryStmt> entries = visit(_n.getEntries(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SwitchStmt r = new SwitchStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				selector, entries
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SwitchEntryStmt _n, Object _arg) {
+		Expression label = cloneNodes(_n.getLabel(), _arg);
+		List<Statement> stmts = visit(_n.getStmts(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SwitchEntryStmt r = new SwitchEntryStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				label, stmts
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(BreakStmt _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		BreakStmt r = new BreakStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getId()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ReturnStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ReturnStmt r = new ReturnStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(IfStmt _n, Object _arg) {
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Statement thenStmt = cloneNodes(_n.getThenStmt(), _arg);
+		Statement elseStmt = cloneNodes(_n.getElseStmt(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		IfStmt r = new IfStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				condition, thenStmt, elseStmt
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(WhileStmt _n, Object _arg) {
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		WhileStmt r = new WhileStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				condition, body
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ContinueStmt _n, Object _arg) {
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ContinueStmt r = new ContinueStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				_n.getId()
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(DoStmt _n, Object _arg) {
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Expression condition = cloneNodes(_n.getCondition(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		DoStmt r = new DoStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				body, condition
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ForeachStmt _n, Object _arg) {
+		VariableDeclarationExpr var = cloneNodes(_n.getVariable(), _arg);
+		Expression iterable = cloneNodes(_n.getIterable(), _arg);
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ForeachStmt r = new ForeachStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				var, iterable, body
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ForStmt _n, Object _arg) {
+		List<Expression> init = visit(_n.getInit(), _arg);
+		Expression compare = cloneNodes(_n.getCompare(), _arg);
+		List<Expression> update = visit(_n.getUpdate(), _arg);
+		Statement body = cloneNodes(_n.getBody(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ForStmt r = new ForStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				init, compare, update, body
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(ThrowStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		ThrowStmt r = new ThrowStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				expr
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(SynchronizedStmt _n, Object _arg) {
+		Expression expr = cloneNodes(_n.getExpr(), _arg);
+		BlockStmt block = cloneNodes(_n.getBlock(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		SynchronizedStmt r = new SynchronizedStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				expr, block
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(TryStmt _n, Object _arg) {
+		List<VariableDeclarationExpr> resources = visit(_n.getResources(),_arg);
+		BlockStmt tryBlock = cloneNodes(_n.getTryBlock(), _arg);
+		List<CatchClause> catchs = visit(_n.getCatchs(), _arg);
+		BlockStmt finallyBlock = cloneNodes(_n.getFinallyBlock(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		TryStmt r = new TryStmt(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				resources, tryBlock, catchs, finallyBlock
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(CatchClause _n, Object _arg) {
+		MultiTypeParameter except = cloneNodes(_n.getExcept(), _arg);
+		BlockStmt catchBlock = cloneNodes(_n.getCatchBlock(), _arg);
+		Comment comment = cloneNodes(_n.getComment(), _arg);
+
+		CatchClause r = new CatchClause(
+				_n.getBeginLine(), _n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(),
+				except.getModifiers(), except.getAnnotations(), except.getTypes(), except.getId(), catchBlock
+		);
+		r.setComment(comment);
+		return r;
+	}
+
+	@Override
+	public Node visit(LambdaExpr _n, Object _arg) {
+
+		List<Parameter> lambdaParameters = visit(_n.getParameters(), _arg);
+
+		Statement body = cloneNodes(_n.getBody(), _arg);
+
+		LambdaExpr r = new LambdaExpr(_n.getBeginLine(), _n.getBeginColumn(),
+				_n.getEndLine(), _n.getEndColumn(), lambdaParameters, body,
+				_n.isParametersEnclosed());
+
+		return r;
+	}
+
+	@Override
+	public Node visit(MethodReferenceExpr _n, Object arg) {
+
+		List<TypeParameter> typeParams = visit(_n.getTypeParameters(), arg);
+		Expression scope = cloneNodes(_n.getScope(), arg);
+
+		MethodReferenceExpr r = new MethodReferenceExpr(_n.getBeginLine(),
+				_n.getBeginColumn(), _n.getEndLine(), _n.getEndColumn(), scope,
+				typeParams, _n.getIdentifier());
+		return r;
+	}
+
+	@Override
+	public Node visit(TypeExpr n, Object arg) {
+
+		Type t = cloneNodes(n.getType(), arg);
+
+		TypeExpr r = new TypeExpr(n.getBeginLine(), n.getBeginColumn(),
+				n.getEndLine(), n.getEndColumn(), t);
+
+		return r;
+	}
+
+    public <T extends Node> List<T> visit(List<T> _nodes, Object _arg) {
+        if (_nodes == null)
+            return null;
+        List<T> r = new ArrayList<T>(_nodes.size());
+        for (T n : _nodes) {
+            T rN = cloneNodes(n, _arg);
+            if (rN != null)
+                r.add(rN);
+        }
+        return r;
+    }
+
+    protected <T extends Node> T cloneNodes(T _node, Object _arg) {
+        if (_node == null)
+            return null;
+        Node r = _node.accept(this, _arg);
+        if (r == null)
+            return null;
+        return (T) r;
+    }
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/DumpVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/DumpVisitor.java
new file mode 100644
index 0000000..8b04afe
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/DumpVisitor.java
@@ -0,0 +1,1657 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import static com.github.javaparser.PositionUtils.sortByBeginPosition;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.ModifierSet;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.github.javaparser.ast.internal.Utils.isNullOrEmpty;
+
+/**
+ * Dumps the AST to formatted Java source code.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public final class DumpVisitor implements VoidVisitor<Object> {
+
+    private boolean printComments;
+
+    public DumpVisitor() {
+        this(true);
+    }
+
+    public DumpVisitor(boolean printComments) {
+        this.printComments = printComments;
+    }
+
+	private static class SourcePrinter {
+
+		private int level = 0;
+
+		private boolean indented = false;
+
+		private final StringBuilder buf = new StringBuilder();
+
+		public void indent() {
+			level++;
+		}
+
+		public void unindent() {
+			level--;
+		}
+
+		private void makeIndent() {
+			for (int i = 0; i < level; i++) {
+				buf.append("    ");
+			}
+		}
+
+		public void print(final String arg) {
+			if (!indented) {
+				makeIndent();
+				indented = true;
+			}
+			buf.append(arg);
+		}
+
+		public void printLn(final String arg) {
+			print(arg);
+			printLn();
+		}
+
+		public void printLn() {
+			buf.append(System.getProperty("line.separator"));
+			indented = false;
+		}
+
+		public String getSource() {
+			return buf.toString();
+		}
+
+		@Override public String toString() {
+			return getSource();
+		}
+	}
+
+	private final SourcePrinter printer = new SourcePrinter();
+
+	public String getSource() {
+		return printer.getSource();
+	}
+
+	private void printModifiers(final int modifiers) {
+		if (ModifierSet.isPrivate(modifiers)) {
+			printer.print("private ");
+		}
+		if (ModifierSet.isProtected(modifiers)) {
+			printer.print("protected ");
+		}
+		if (ModifierSet.isPublic(modifiers)) {
+			printer.print("public ");
+		}
+		if (ModifierSet.isAbstract(modifiers)) {
+			printer.print("abstract ");
+		}
+		if (ModifierSet.isStatic(modifiers)) {
+			printer.print("static ");
+		}
+		if (ModifierSet.isFinal(modifiers)) {
+			printer.print("final ");
+		}
+		if (ModifierSet.isNative(modifiers)) {
+			printer.print("native ");
+		}
+		if (ModifierSet.isStrictfp(modifiers)) {
+			printer.print("strictfp ");
+		}
+		if (ModifierSet.isSynchronized(modifiers)) {
+			printer.print("synchronized ");
+		}
+		if (ModifierSet.isTransient(modifiers)) {
+			printer.print("transient ");
+		}
+		if (ModifierSet.isVolatile(modifiers)) {
+			printer.print("volatile ");
+		}
+	}
+
+	private void printMembers(final List<BodyDeclaration> members, final Object arg) {
+		for (final BodyDeclaration member : members) {
+			printer.printLn();
+			member.accept(this, arg);
+			printer.printLn();
+		}
+	}
+
+	private void printMemberAnnotations(final List<AnnotationExpr> annotations, final Object arg) {
+		if (!isNullOrEmpty(annotations)) {
+			for (final AnnotationExpr a : annotations) {
+				a.accept(this, arg);
+				printer.printLn();
+			}
+		}
+	}
+
+	private void printAnnotations(final List<AnnotationExpr> annotations, final Object arg) {
+		if (!isNullOrEmpty(annotations)) {
+			for (final AnnotationExpr a : annotations) {
+				a.accept(this, arg);
+				printer.print(" ");
+			}
+		}
+	}
+
+	private void printTypeArgs(final List<Type> args, final Object arg) {
+        if (!isNullOrEmpty(args)) {
+			printer.print("<");
+			for (final Iterator<Type> i = args.iterator(); i.hasNext();) {
+				final Type t = i.next();
+				t.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+			printer.print(">");
+		}
+	}
+
+	private void printTypeParameters(final List<TypeParameter> args, final Object arg) {
+        if (!isNullOrEmpty(args)) {
+			printer.print("<");
+			for (final Iterator<TypeParameter> i = args.iterator(); i.hasNext();) {
+				final TypeParameter t = i.next();
+				t.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+			printer.print(">");
+		}
+	}
+
+	private void printArguments(final List<Expression> args, final Object arg) {
+		printer.print("(");
+        if (!isNullOrEmpty(args)) {
+			for (final Iterator<Expression> i = args.iterator(); i.hasNext();) {
+				final Expression e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+	}
+
+	private void printJavadoc(final JavadocComment javadoc, final Object arg) {
+		if (javadoc != null) {
+			javadoc.accept(this, arg);
+		}
+	}
+
+	private void printJavaComment(final Comment javacomment, final Object arg) {
+		if (javacomment != null) {
+			javacomment.accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final CompilationUnit n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+
+		if (n.getPackage() != null) {
+			n.getPackage().accept(this, arg);
+		}
+
+		if (n.getImports() != null) {
+			for (final ImportDeclaration i : n.getImports()) {
+				i.accept(this, arg);
+			}
+			printer.printLn();
+		}
+
+		if (n.getTypes() != null) {
+			for (final Iterator<TypeDeclaration> i = n.getTypes().iterator(); i.hasNext();) {
+				i.next().accept(this, arg);
+				printer.printLn();
+				if (i.hasNext()) {
+					printer.printLn();
+				}
+			}
+		}
+
+        printOrphanCommentsEnding(n);
+	}
+
+	@Override public void visit(final PackageDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), arg);
+		printer.print("package ");
+		n.getName().accept(this, arg);
+		printer.printLn(";");
+		printer.printLn();
+
+        printOrphanCommentsEnding(n);
+	}
+
+	@Override public void visit(final NameExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getName());
+
+        printOrphanCommentsEnding(n);
+	}
+
+	@Override public void visit(final QualifiedNameExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getQualifier().accept(this, arg);
+		printer.print(".");
+		printer.print(n.getName());
+
+        printOrphanCommentsEnding(n);
+	}
+
+	@Override public void visit(final ImportDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("import ");
+		if (n.isStatic()) {
+			printer.print("static ");
+		}
+		n.getName().accept(this, arg);
+		if (n.isAsterisk()) {
+			printer.print(".*");
+		}
+		printer.printLn(";");
+
+        printOrphanCommentsEnding(n);
+	}
+
+	@Override public void visit(final ClassOrInterfaceDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		if (n.isInterface()) {
+			printer.print("interface ");
+		} else {
+			printer.print("class ");
+		}
+
+		printer.print(n.getName());
+
+		printTypeParameters(n.getTypeParameters(), arg);
+
+		if (!isNullOrEmpty(n.getExtends())) {
+			printer.print(" extends ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getExtends().iterator(); i.hasNext();) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+
+		if (!isNullOrEmpty(n.getImplements())) {
+			printer.print(" implements ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getImplements().iterator(); i.hasNext();) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+
+		printer.printLn(" {");
+		printer.indent();
+		if (!isNullOrEmpty(n.getMembers())) {
+			printMembers(n.getMembers(), arg);
+		}
+
+        printOrphanCommentsEnding(n);
+
+		printer.unindent();
+		printer.print("}");
+	}
+
+	@Override public void visit(final EmptyTypeDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printer.print(";");
+
+        printOrphanCommentsEnding(n);
+	}
+
+	@Override public void visit(final JavadocComment n, final Object arg) {
+		printer.print("/**");
+		printer.print(n.getContent());
+		printer.printLn("*/");
+	}
+
+	@Override public void visit(final ClassOrInterfaceType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+
+		if (n.getAnnotations() != null) {
+			for (AnnotationExpr ae : n.getAnnotations()) {
+				ae.accept(this, arg);
+				printer.print(" ");
+			}
+		}
+
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+			printer.print(".");
+		}
+		printer.print(n.getName());
+		printTypeArgs(n.getTypeArgs(), arg);
+	}
+
+	@Override public void visit(final TypeParameter n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (AnnotationExpr ann : n.getAnnotations()) {
+				ann.accept(this, arg);
+				printer.print(" ");
+			}
+		}
+		printer.print(n.getName());
+		if (n.getTypeBound() != null) {
+			printer.print(" extends ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getTypeBound().iterator(); i.hasNext();) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(" & ");
+				}
+			}
+		}
+	}
+
+	@Override public void visit(final PrimitiveType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (AnnotationExpr ae : n.getAnnotations()) {
+				ae.accept(this, arg);
+				printer.print(" ");
+			}
+		}
+		switch (n.getType()) {
+		case Boolean:
+			printer.print("boolean");
+			break;
+		case Byte:
+			printer.print("byte");
+			break;
+		case Char:
+			printer.print("char");
+			break;
+		case Double:
+			printer.print("double");
+			break;
+		case Float:
+			printer.print("float");
+			break;
+		case Int:
+			printer.print("int");
+			break;
+		case Long:
+			printer.print("long");
+			break;
+		case Short:
+			printer.print("short");
+			break;
+		}
+	}
+
+	@Override public void visit(final ReferenceType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (AnnotationExpr ae : n.getAnnotations()) {
+				ae.accept(this, arg);
+				printer.print(" ");
+			}
+		}
+		n.getType().accept(this, arg);
+		List<List<AnnotationExpr>> arraysAnnotations = n.getArraysAnnotations();
+		for (int i = 0; i < n.getArrayCount(); i++) {
+			if (arraysAnnotations != null && i < arraysAnnotations.size()) {
+				List<AnnotationExpr> annotations = arraysAnnotations.get(i);
+				if (annotations != null) {
+					for (AnnotationExpr ae : annotations) {
+						printer.print(" ");
+						ae.accept(this, arg);
+
+					}
+				}
+			}
+			printer.print("[]");
+		}
+	}
+
+	@Override public void visit(final WildcardType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (AnnotationExpr ae : n.getAnnotations()) {
+				printer.print(" ");
+				ae.accept(this, arg);
+			}
+		}
+		printer.print("?");
+		if (n.getExtends() != null) {
+			printer.print(" extends ");
+			n.getExtends().accept(this, arg);
+		}
+		if (n.getSuper() != null) {
+			printer.print(" super ");
+			n.getSuper().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final UnknownType n, final Object arg) {
+		// Nothing to dump
+	}
+
+	@Override public void visit(final FieldDeclaration n, final Object arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+		n.getType().accept(this, arg);
+
+		printer.print(" ");
+		for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext();) {
+			final VariableDeclarator var = i.next();
+			var.accept(this, arg);
+			if (i.hasNext()) {
+				printer.print(", ");
+			}
+		}
+
+		printer.print(";");
+	}
+
+	@Override public void visit(final VariableDeclarator n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getId().accept(this, arg);
+		if (n.getInit() != null) {
+			printer.print(" = ");
+			n.getInit().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final VariableDeclaratorId n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getName());
+		for (int i = 0; i < n.getArrayCount(); i++) {
+			printer.print("[]");
+		}
+	}
+
+	@Override public void visit(final ArrayInitializerExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("{");
+		if (n.getValues() != null) {
+			printer.print(" ");
+			for (final Iterator<Expression> i = n.getValues().iterator(); i.hasNext();) {
+				final Expression expr = i.next();
+				expr.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+			printer.print(" ");
+		}
+		printer.print("}");
+	}
+
+	@Override public void visit(final VoidType n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("void");
+	}
+
+	@Override public void visit(final ArrayAccessExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		printer.print("[");
+		n.getIndex().accept(this, arg);
+		printer.print("]");
+	}
+
+	@Override public void visit(final ArrayCreationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("new ");
+		n.getType().accept(this, arg);
+		List<List<AnnotationExpr>> arraysAnnotations = n.getArraysAnnotations();
+		if (n.getDimensions() != null) {
+			int j = 0;
+			for (final Expression dim : n.getDimensions()) {
+
+				if (arraysAnnotations != null && j < arraysAnnotations.size()) {
+					List<AnnotationExpr> annotations = arraysAnnotations.get(j);
+					if (annotations != null) {
+						for (AnnotationExpr ae : annotations) {
+							printer.print(" ");
+							ae.accept(this, arg);
+						}
+					}
+				}
+				printer.print("[");
+				dim.accept(this, arg);
+				printer.print("]");
+				j++;
+			}
+			for (int i = 0; i < n.getArrayCount(); i++) {
+				if (arraysAnnotations != null && i < arraysAnnotations.size()) {
+
+					List<AnnotationExpr> annotations = arraysAnnotations.get(i);
+					if (annotations != null) {
+						for (AnnotationExpr ae : annotations) {
+							printer.print(" ");
+							ae.accept(this, arg);
+
+						}
+					}
+				}
+				printer.print("[]");
+			}
+
+		} else {
+			for (int i = 0; i < n.getArrayCount(); i++) {
+				if (arraysAnnotations != null && i < arraysAnnotations.size()) {
+					List<AnnotationExpr> annotations = arraysAnnotations.get(i);
+					if (annotations != null) {
+						for (AnnotationExpr ae : annotations) {
+							ae.accept(this, arg);
+							printer.print(" ");
+						}
+					}
+				}
+				printer.print("[]");
+			}
+			printer.print(" ");
+			n.getInitializer().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final AssignExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getTarget().accept(this, arg);
+		printer.print(" ");
+		switch (n.getOperator()) {
+		case assign:
+			printer.print("=");
+			break;
+		case and:
+			printer.print("&=");
+			break;
+		case or:
+			printer.print("|=");
+			break;
+		case xor:
+			printer.print("^=");
+			break;
+		case plus:
+			printer.print("+=");
+			break;
+		case minus:
+			printer.print("-=");
+			break;
+		case rem:
+			printer.print("%=");
+			break;
+		case slash:
+			printer.print("/=");
+			break;
+		case star:
+			printer.print("*=");
+			break;
+		case lShift:
+			printer.print("<<=");
+			break;
+		case rSignedShift:
+			printer.print(">>=");
+			break;
+		case rUnsignedShift:
+			printer.print(">>>=");
+			break;
+		}
+		printer.print(" ");
+		n.getValue().accept(this, arg);
+	}
+
+	@Override public void visit(final BinaryExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getLeft().accept(this, arg);
+		printer.print(" ");
+		switch (n.getOperator()) {
+		case or:
+			printer.print("||");
+			break;
+		case and:
+			printer.print("&&");
+			break;
+		case binOr:
+			printer.print("|");
+			break;
+		case binAnd:
+			printer.print("&");
+			break;
+		case xor:
+			printer.print("^");
+			break;
+		case equals:
+			printer.print("==");
+			break;
+		case notEquals:
+			printer.print("!=");
+			break;
+		case less:
+			printer.print("<");
+			break;
+		case greater:
+			printer.print(">");
+			break;
+		case lessEquals:
+			printer.print("<=");
+			break;
+		case greaterEquals:
+			printer.print(">=");
+			break;
+		case lShift:
+			printer.print("<<");
+			break;
+		case rSignedShift:
+			printer.print(">>");
+			break;
+		case rUnsignedShift:
+			printer.print(">>>");
+			break;
+		case plus:
+			printer.print("+");
+			break;
+		case minus:
+			printer.print("-");
+			break;
+		case times:
+			printer.print("*");
+			break;
+		case divide:
+			printer.print("/");
+			break;
+		case remainder:
+			printer.print("%");
+			break;
+		}
+		printer.print(" ");
+		n.getRight().accept(this, arg);
+	}
+
+	@Override public void visit(final CastExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("(");
+		n.getType().accept(this, arg);
+		printer.print(") ");
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final ClassExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+		printer.print(".class");
+	}
+
+	@Override public void visit(final ConditionalExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		printer.print(" ? ");
+		n.getThenExpr().accept(this, arg);
+		printer.print(" : ");
+		n.getElseExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final EnclosedExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("(");
+		if (n.getInner() != null) {
+		n.getInner().accept(this, arg);
+		}
+		printer.print(")");
+	}
+
+	@Override public void visit(final FieldAccessExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getScope().accept(this, arg);
+		printer.print(".");
+		printer.print(n.getField());
+	}
+
+	@Override public void visit(final InstanceOfExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+		printer.print(" instanceof ");
+		n.getType().accept(this, arg);
+	}
+
+	@Override public void visit(final CharLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("'");
+		printer.print(n.getValue());
+		printer.print("'");
+	}
+
+	@Override public void visit(final DoubleLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override public void visit(final IntegerLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override public void visit(final LongLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override public void visit(final IntegerLiteralMinValueExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override public void visit(final LongLiteralMinValueExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getValue());
+	}
+
+	@Override public void visit(final StringLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("\"");
+		printer.print(n.getValue());
+		printer.print("\"");
+	}
+
+	@Override public void visit(final BooleanLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(String.valueOf(n.getValue()));
+	}
+
+	@Override public void visit(final NullLiteralExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("null");
+	}
+
+	@Override public void visit(final ThisExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+			printer.print(".");
+		}
+		printer.print("this");
+	}
+
+	@Override public void visit(final SuperExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+			printer.print(".");
+		}
+		printer.print("super");
+	}
+
+	@Override public void visit(final MethodCallExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+			printer.print(".");
+		}
+		printTypeArgs(n.getTypeArgs(), arg);
+		printer.print(n.getName());
+		printArguments(n.getArgs(), arg);
+	}
+
+	@Override public void visit(final ObjectCreationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+			printer.print(".");
+		}
+
+		printer.print("new ");
+
+		printTypeArgs(n.getTypeArgs(), arg);
+		if (!isNullOrEmpty(n.getTypeArgs())) {
+			printer.print(" ");
+		}
+
+		n.getType().accept(this, arg);
+
+		printArguments(n.getArgs(), arg);
+
+		if (n.getAnonymousClassBody() != null) {
+			printer.printLn(" {");
+			printer.indent();
+			printMembers(n.getAnonymousClassBody(), arg);
+			printer.unindent();
+			printer.print("}");
+		}
+	}
+
+	@Override public void visit(final UnaryExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		switch (n.getOperator()) {
+		case positive:
+			printer.print("+");
+			break;
+		case negative:
+			printer.print("-");
+			break;
+		case inverse:
+			printer.print("~");
+			break;
+		case not:
+			printer.print("!");
+			break;
+		case preIncrement:
+			printer.print("++");
+			break;
+		case preDecrement:
+			printer.print("--");
+			break;
+		default:
+		}
+
+		n.getExpr().accept(this, arg);
+
+		switch (n.getOperator()) {
+		case posIncrement:
+			printer.print("++");
+			break;
+		case posDecrement:
+			printer.print("--");
+			break;
+		default:
+		}
+	}
+
+	@Override public void visit(final ConstructorDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		printTypeParameters(n.getTypeParameters(), arg);
+		if (n.getTypeParameters() != null) {
+			printer.print(" ");
+		}
+		printer.print(n.getName());
+
+		printer.print("(");
+		if (n.getParameters() != null) {
+			for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext();) {
+				final Parameter p = i.next();
+				p.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+
+		if (!isNullOrEmpty(n.getThrows())) {
+			printer.print(" throws ");
+			for (final Iterator<NameExpr> i = n.getThrows().iterator(); i.hasNext();) {
+				final NameExpr name = i.next();
+				name.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(" ");
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final MethodDeclaration n, final Object arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+		if (n.isDefault()) {
+			printer.print("default ");
+		}
+		printTypeParameters(n.getTypeParameters(), arg);
+		if (n.getTypeParameters() != null) {
+			printer.print(" ");
+		}
+
+		n.getType().accept(this, arg);
+		printer.print(" ");
+		printer.print(n.getName());
+
+		printer.print("(");
+		if (n.getParameters() != null) {
+			for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext();) {
+				final Parameter p = i.next();
+				p.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+
+		for (int i = 0; i < n.getArrayCount(); i++) {
+			printer.print("[]");
+		}
+
+		if (!isNullOrEmpty(n.getThrows())) {
+			printer.print(" throws ");
+			for (final Iterator<NameExpr> i = n.getThrows().iterator(); i.hasNext();) {
+				final NameExpr name = i.next();
+				name.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		if (n.getBody() == null) {
+			printer.print(";");
+		} else {
+			printer.print(" ");
+			n.getBody().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final Parameter n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+		if (n.getType() != null) {
+			n.getType().accept(this, arg);
+		}
+		if (n.isVarArgs()) {
+			printer.print("...");
+		}
+		printer.print(" ");
+		n.getId().accept(this, arg);
+	}
+	
+    @Override public void visit(MultiTypeParameter n, Object arg) {
+        printAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        Iterator<Type> types = n.getTypes().iterator();
+        types.next().accept(this, arg);
+        while (types.hasNext()) {
+        	printer.print(" | ");
+        	types.next().accept(this, arg);
+        }
+        
+        printer.print(" ");
+        n.getId().accept(this, arg);
+    }
+
+	@Override public void visit(final ExplicitConstructorInvocationStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.isThis()) {
+			printTypeArgs(n.getTypeArgs(), arg);
+			printer.print("this");
+		} else {
+			if (n.getExpr() != null) {
+				n.getExpr().accept(this, arg);
+				printer.print(".");
+			}
+			printTypeArgs(n.getTypeArgs(), arg);
+			printer.print("super");
+		}
+		printArguments(n.getArgs(), arg);
+		printer.print(";");
+	}
+
+	@Override public void visit(final VariableDeclarationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		n.getType().accept(this, arg);
+		printer.print(" ");
+
+		for (final Iterator<VariableDeclarator> i = n.getVars().iterator(); i.hasNext();) {
+			final VariableDeclarator v = i.next();
+			v.accept(this, arg);
+			if (i.hasNext()) {
+				printer.print(", ");
+			}
+		}
+	}
+
+	@Override public void visit(final TypeDeclarationStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		n.getTypeDeclaration().accept(this, arg);
+	}
+
+	@Override public void visit(final AssertStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("assert ");
+		n.getCheck().accept(this, arg);
+		if (n.getMessage() != null) {
+			printer.print(" : ");
+			n.getMessage().accept(this, arg);
+		}
+		printer.print(";");
+	}
+
+	@Override public void visit(final BlockStmt n, final Object arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+		printJavaComment(n.getComment(), arg);
+		printer.printLn("{");
+		if (n.getStmts() != null) {
+			printer.indent();
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+				printer.printLn();
+			}
+			printer.unindent();
+		}
+		printOrphanCommentsEnding(n);
+		printer.print("}");
+
+	}
+
+	@Override public void visit(final LabeledStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getLabel());
+		printer.print(": ");
+		n.getStmt().accept(this, arg);
+	}
+
+	@Override public void visit(final EmptyStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(";");
+	}
+
+	@Override public void visit(final ExpressionStmt n, final Object arg) {
+		printOrphanCommentsBeforeThisChildNode(n);
+		printJavaComment(n.getComment(), arg);
+		n.getExpression().accept(this, arg);
+		printer.print(";");
+	}
+
+	@Override public void visit(final SwitchStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("switch(");
+		n.getSelector().accept(this, arg);
+		printer.printLn(") {");
+		if (n.getEntries() != null) {
+			printer.indent();
+			for (final SwitchEntryStmt e : n.getEntries()) {
+				e.accept(this, arg);
+			}
+			printer.unindent();
+		}
+		printer.print("}");
+
+	}
+
+	@Override public void visit(final SwitchEntryStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		if (n.getLabel() != null) {
+			printer.print("case ");
+			n.getLabel().accept(this, arg);
+			printer.print(":");
+		} else {
+			printer.print("default:");
+		}
+		printer.printLn();
+		printer.indent();
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+				printer.printLn();
+			}
+		}
+		printer.unindent();
+	}
+
+	@Override public void visit(final BreakStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("break");
+		if (n.getId() != null) {
+			printer.print(" ");
+			printer.print(n.getId());
+		}
+		printer.print(";");
+	}
+
+	@Override public void visit(final ReturnStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("return");
+		if (n.getExpr() != null) {
+			printer.print(" ");
+			n.getExpr().accept(this, arg);
+		}
+		printer.print(";");
+	}
+
+	@Override public void visit(final EnumDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		printer.print("enum ");
+		printer.print(n.getName());
+
+		if (n.getImplements() != null) {
+			printer.print(" implements ");
+			for (final Iterator<ClassOrInterfaceType> i = n.getImplements().iterator(); i.hasNext();) {
+				final ClassOrInterfaceType c = i.next();
+				c.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+
+		printer.printLn(" {");
+		printer.indent();
+		if (n.getEntries() != null) {
+			printer.printLn();
+			for (final Iterator<EnumConstantDeclaration> i = n.getEntries().iterator(); i.hasNext();) {
+				final EnumConstantDeclaration e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		if (n.getMembers() != null) {
+			printer.printLn(";");
+			printMembers(n.getMembers(), arg);
+		} else {
+			if (n.getEntries() != null) {
+				printer.printLn();
+			}
+		}
+		printer.unindent();
+		printer.print("}");
+	}
+
+	@Override public void visit(final EnumConstantDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printer.print(n.getName());
+
+		if (n.getArgs() != null) {
+			printArguments(n.getArgs(), arg);
+		}
+
+		if (n.getClassBody() != null) {
+			printer.printLn(" {");
+			printer.indent();
+			printMembers(n.getClassBody(), arg);
+			printer.unindent();
+			printer.printLn("}");
+		}
+	}
+
+	@Override public void visit(final EmptyMemberDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printer.print(";");
+	}
+
+	@Override public void visit(final InitializerDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		if (n.isStatic()) {
+			printer.print("static ");
+		}
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final IfStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("if (");
+		n.getCondition().accept(this, arg);
+		final boolean thenBlock = n.getThenStmt() instanceof BlockStmt;
+		if (thenBlock) // block statement should start on the same line
+			printer.print(") ");
+		else {
+			printer.printLn(")");
+			printer.indent();
+		}
+		n.getThenStmt().accept(this, arg);
+		if (!thenBlock)
+			printer.unindent();
+		if (n.getElseStmt() != null) {
+			if (thenBlock)
+				printer.print(" ");
+			else
+				printer.printLn();
+			final boolean elseIf = n.getElseStmt() instanceof IfStmt;
+			final boolean elseBlock = n.getElseStmt() instanceof BlockStmt;
+			if (elseIf || elseBlock) // put chained if and start of block statement on a same level
+				printer.print("else ");
+			else {
+				printer.printLn("else");
+				printer.indent();
+			}
+			n.getElseStmt().accept(this, arg);
+			if (!(elseIf || elseBlock))
+				printer.unindent();
+		}
+	}
+
+	@Override public void visit(final WhileStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("while (");
+		n.getCondition().accept(this, arg);
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final ContinueStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("continue");
+		if (n.getId() != null) {
+			printer.print(" ");
+			printer.print(n.getId());
+		}
+		printer.print(";");
+	}
+
+	@Override public void visit(final DoStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("do ");
+		n.getBody().accept(this, arg);
+		printer.print(" while (");
+		n.getCondition().accept(this, arg);
+		printer.print(");");
+	}
+
+	@Override public void visit(final ForeachStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("for (");
+		n.getVariable().accept(this, arg);
+		printer.print(" : ");
+		n.getIterable().accept(this, arg);
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final ForStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("for (");
+		if (n.getInit() != null) {
+			for (final Iterator<Expression> i = n.getInit().iterator(); i.hasNext();) {
+				final Expression e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print("; ");
+		if (n.getCompare() != null) {
+			n.getCompare().accept(this, arg);
+		}
+		printer.print("; ");
+		if (n.getUpdate() != null) {
+			for (final Iterator<Expression> i = n.getUpdate().iterator(); i.hasNext();) {
+				final Expression e = i.next();
+				e.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(") ");
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final ThrowStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("throw ");
+		n.getExpr().accept(this, arg);
+		printer.print(";");
+	}
+
+	@Override public void visit(final SynchronizedStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("synchronized (");
+		n.getExpr().accept(this, arg);
+		printer.print(") ");
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final TryStmt n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("try ");
+		if (!n.getResources().isEmpty()) {
+			printer.print("(");
+			Iterator<VariableDeclarationExpr> resources = n.getResources().iterator();
+			boolean first = true;
+			while (resources.hasNext()) {
+				visit(resources.next(), arg);
+				if (resources.hasNext()) {
+					printer.print(";");
+					printer.printLn();
+					if (first) {
+						printer.indent();
+					}
+				}
+				first = false;
+			}
+			if (n.getResources().size() > 1) {
+				printer.unindent();
+			}
+			printer.print(") ");
+		}
+		n.getTryBlock().accept(this, arg);
+		if (n.getCatchs() != null) {
+			for (final CatchClause c : n.getCatchs()) {
+				c.accept(this, arg);
+			}
+		}
+		if (n.getFinallyBlock() != null) {
+			printer.print(" finally ");
+			n.getFinallyBlock().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final CatchClause n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(" catch (");
+		n.getExcept().accept(this, arg);
+		printer.print(") ");
+		n.getCatchBlock().accept(this, arg);
+
+	}
+
+	@Override public void visit(final AnnotationDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		printer.print("@interface ");
+		printer.print(n.getName());
+		printer.printLn(" {");
+		printer.indent();
+		if (n.getMembers() != null) {
+			printMembers(n.getMembers(), arg);
+		}
+		printer.unindent();
+		printer.print("}");
+	}
+
+	@Override public void visit(final AnnotationMemberDeclaration n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printJavadoc(n.getJavaDoc(), arg);
+		printMemberAnnotations(n.getAnnotations(), arg);
+		printModifiers(n.getModifiers());
+
+		n.getType().accept(this, arg);
+		printer.print(" ");
+		printer.print(n.getName());
+		printer.print("()");
+		if (n.getDefaultValue() != null) {
+			printer.print(" default ");
+			n.getDefaultValue().accept(this, arg);
+		}
+		printer.print(";");
+	}
+
+	@Override public void visit(final MarkerAnnotationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("@");
+		n.getName().accept(this, arg);
+	}
+
+	@Override public void visit(final SingleMemberAnnotationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("@");
+		n.getName().accept(this, arg);
+		printer.print("(");
+		n.getMemberValue().accept(this, arg);
+		printer.print(")");
+	}
+
+	@Override public void visit(final NormalAnnotationExpr n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print("@");
+		n.getName().accept(this, arg);
+		printer.print("(");
+		if (n.getPairs() != null) {
+			for (final Iterator<MemberValuePair> i = n.getPairs().iterator(); i.hasNext();) {
+				final MemberValuePair m = i.next();
+				m.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		printer.print(")");
+	}
+
+	@Override public void visit(final MemberValuePair n, final Object arg) {
+		printJavaComment(n.getComment(), arg);
+		printer.print(n.getName());
+		printer.print(" = ");
+		n.getValue().accept(this, arg);
+	}
+
+	@Override public void visit(final LineComment n, final Object arg) {
+		if (!this.printComments) {
+            return;
+        }
+        printer.print("//");
+		String tmp = n.getContent();
+		tmp = tmp.replace('\r', ' ');
+		tmp = tmp.replace('\n', ' ');
+		printer.printLn(tmp);
+	}
+
+	@Override public void visit(final BlockComment n, final Object arg) {
+        if (!this.printComments) {
+            return;
+        }
+        printer.print("/*");
+		printer.print(n.getContent());
+		printer.printLn("*/");
+	}
+
+	@Override
+	public void visit(LambdaExpr n, Object arg) {
+        printJavaComment(n.getComment(), arg);
+
+        List<Parameter> parameters = n.getParameters();
+		boolean printPar = false;
+		printPar = n.isParametersEnclosed();
+
+		if (printPar) {
+			printer.print("(");
+		}
+		if (parameters != null) {
+			for (Iterator<Parameter> i = parameters.iterator(); i.hasNext();) {
+				Parameter p = i.next();
+				p.accept(this, arg);
+				if (i.hasNext()) {
+					printer.print(", ");
+				}
+			}
+		}
+		if (printPar) {
+			printer.print(")");
+		}
+
+		printer.print(" -> ");
+		Statement body = n.getBody();
+		if (body instanceof ExpressionStmt) {
+			// Print the expression directly
+			((ExpressionStmt) body).getExpression().accept(this, arg);
+		} else {
+			body.accept(this, arg);
+		}
+	}
+
+
+    @Override
+    public void visit(MethodReferenceExpr n, Object arg) {
+        printJavaComment(n.getComment(), arg);
+        Expression scope = n.getScope();
+        String identifier = n.getIdentifier();
+        if (scope != null) {
+            n.getScope().accept(this, arg);
+        }
+
+        printer.print("::");
+        if (n.getTypeParameters() != null) {
+            printer.print("<");
+            for (Iterator<TypeParameter> i = n.getTypeParameters().iterator(); i
+                    .hasNext();) {
+                TypeParameter p = i.next();
+                p.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(">");
+        }
+        if (identifier != null) {
+            printer.print(identifier);
+        }
+
+    }
+
+    @Override
+    public void visit(TypeExpr n, Object arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+    }
+
+    private void printOrphanCommentsBeforeThisChildNode(final Node node){
+        if (node instanceof Comment) return;
+
+        Node parent = node.getParentNode();
+        if (parent==null) return;
+        List<Node> everything = new LinkedList<Node>();
+        everything.addAll(parent.getChildrenNodes());
+        sortByBeginPosition(everything);
+        int positionOfTheChild = -1;
+        for (int i=0;i<everything.size();i++){
+            if (everything.get(i)==node) positionOfTheChild=i;
+        }
+        if (positionOfTheChild==-1) throw new RuntimeException("My index not found!!! "+node);
+        int positionOfPreviousChild = -1;
+        for (int i=positionOfTheChild-1;i>=0 && positionOfPreviousChild==-1;i--){
+            if (!(everything.get(i) instanceof Comment)) positionOfPreviousChild = i;
+        }
+        for (int i=positionOfPreviousChild+1;i<positionOfTheChild;i++){
+            Node nodeToPrint = everything.get(i);
+            if (!(nodeToPrint instanceof Comment)) throw new RuntimeException("Expected comment, instead "+nodeToPrint.getClass()+". Position of previous child: "+positionOfPreviousChild+", position of child "+positionOfTheChild);
+            nodeToPrint.accept(this,null);
+        }
+    }
+
+
+    private void printOrphanCommentsEnding(final Node node){
+        List<Node> everything = new LinkedList<Node>();
+        everything.addAll(node.getChildrenNodes());
+        sortByBeginPosition(everything);
+        if (everything.size()==0) return;
+
+        int commentsAtEnd = 0;
+        boolean findingComments = true;
+        while (findingComments&&commentsAtEnd<everything.size()){
+            Node last = everything.get(everything.size()-1-commentsAtEnd);
+            findingComments = (last instanceof Comment);
+            if (findingComments) commentsAtEnd++;
+        }
+        for (int i=0;i<commentsAtEnd;i++){
+            everything.get(everything.size()-commentsAtEnd+i).accept(this,null);
+        }
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/EqualsVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/EqualsVisitor.java
new file mode 100644
index 0000000..8f4a786
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/EqualsVisitor.java
@@ -0,0 +1,1468 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BaseParameter;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public class EqualsVisitor implements GenericVisitor<Boolean, Node> {
+
+	private static final EqualsVisitor SINGLETON = new EqualsVisitor();
+
+	public static boolean equals(final Node n1, final Node n2) {
+		return SINGLETON.nodeEquals(n1, n2);
+	}
+
+	private EqualsVisitor() {
+		// hide constructor
+	}
+
+    /**
+     * Check for equality that can be applied to each kind of node,
+     * to not repeat it in every method we store that here.
+     */
+    private boolean commonNodeEquality(Node n1, Node n2) {
+        if (!nodeEquals(n1.getComment(), n2.getComment())) {
+            return false;
+        }
+        if (!nodesEquals(n1.getOrphanComments(), n2.getOrphanComments())){
+            return false;
+        }
+        return true;
+    }
+
+	private <T extends Node> boolean nodesEquals(final List<T> nodes1, final List<T> nodes2) {
+		if (nodes1 == null) {
+			if (nodes2 == null) {
+				return true;
+			}
+			return false;
+		} else if (nodes2 == null) {
+			return false;
+		}
+		if (nodes1.size() != nodes2.size()) {
+			return false;
+		}
+		for (int i = 0; i < nodes1.size(); i++) {
+			if (!nodeEquals(nodes1.get(i), nodes2.get(i))) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	private <T extends Node> boolean nodeEquals(final T n1, final T n2) {
+		if (n1 == n2) {
+			return true;
+		}
+		if (n1 == null) {
+			if (n2 == null) {
+				return true;
+			}
+			return false;
+		} else if (n2 == null) {
+			return false;
+		}
+		if (n1.getClass() != n2.getClass()) {
+			return false;
+		}
+        if (!commonNodeEquality(n1, n2)){
+            return false;
+        }
+		return n1.accept(this, n2).booleanValue();
+	}
+
+	private boolean objEquals(final Object n1, final Object n2) {
+		if (n1 == n2) {
+			return true;
+		}
+		if (n1 == null) {
+			if (n2 == null) {
+				return true;
+			}
+			return false;
+		} else if (n2 == null) {
+			return false;
+		}
+		return n1.equals(n2);
+	}
+
+	@Override public Boolean visit(final CompilationUnit n1, final Node arg) {
+		final CompilationUnit n2 = (CompilationUnit) arg;
+
+		if (!nodeEquals(n1.getPackage(), n2.getPackage())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getImports(), n2.getImports())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypes(), n2.getTypes())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getComments(), n2.getComments())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final PackageDeclaration n1, final Node arg) {
+		final PackageDeclaration n2 = (PackageDeclaration) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ImportDeclaration n1, final Node arg) {
+		final ImportDeclaration n2 = (ImportDeclaration) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final TypeParameter n1, final Node arg) {
+		final TypeParameter n2 = (TypeParameter) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeBound(), n2.getTypeBound())) {
+			return Boolean.FALSE;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final LineComment n1, final Node arg) {
+		final LineComment n2 = (LineComment) arg;
+
+		if (!objEquals(n1.getContent(), n2.getContent())) {
+			return Boolean.FALSE;
+		}
+
+        if (!objEquals(n1.getBeginLine(), n2.getBeginLine())) {
+      		return Boolean.FALSE;
+      	}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final BlockComment n1, final Node arg) {
+		final BlockComment n2 = (BlockComment) arg;
+
+		if (!objEquals(n1.getContent(), n2.getContent())) {
+			return Boolean.FALSE;
+		}
+
+        if (!objEquals(n1.getBeginLine(), n2.getBeginLine())) {
+      			return Boolean.FALSE;
+      	}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ClassOrInterfaceDeclaration n1, final Node arg) {
+		final ClassOrInterfaceDeclaration n2 = (ClassOrInterfaceDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (n1.isInterface() != n2.isInterface()) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeParameters(), n2.getTypeParameters())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getExtends(), n2.getExtends())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getImplements(), n2.getImplements())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getMembers(), n2.getMembers())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final EnumDeclaration n1, final Node arg) {
+		final EnumDeclaration n2 = (EnumDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getImplements(), n2.getImplements())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getEntries(), n2.getEntries())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getMembers(), n2.getMembers())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final EmptyTypeDeclaration n1, final Node arg) {
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final EnumConstantDeclaration n1, final Node arg) {
+		final EnumConstantDeclaration n2 = (EnumConstantDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getClassBody(), n2.getClassBody())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final AnnotationDeclaration n1, final Node arg) {
+		final AnnotationDeclaration n2 = (AnnotationDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getMembers(), n2.getMembers())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final AnnotationMemberDeclaration n1, final Node arg) {
+		final AnnotationMemberDeclaration n2 = (AnnotationMemberDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getDefaultValue(), n2.getDefaultValue())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final FieldDeclaration n1, final Node arg) {
+		final FieldDeclaration n2 = (FieldDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getVariables(), n2.getVariables())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final VariableDeclarator n1, final Node arg) {
+		final VariableDeclarator n2 = (VariableDeclarator) arg;
+
+		if (!nodeEquals(n1.getId(), n2.getId())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getInit(), n2.getInit())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final VariableDeclaratorId n1, final Node arg) {
+		final VariableDeclaratorId n2 = (VariableDeclaratorId) arg;
+
+		if (n1.getArrayCount() != n2.getArrayCount()) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ConstructorDeclaration n1, final Node arg) {
+		final ConstructorDeclaration n2 = (ConstructorDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getBlock(), n2.getBlock())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getParameters(), n2.getParameters())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getThrows(), n2.getThrows())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeParameters(), n2.getTypeParameters())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final MethodDeclaration n1, final Node arg) {
+		final MethodDeclaration n2 = (MethodDeclaration) arg;
+
+		// javadoc are checked at CompilationUnit
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (n1.getArrayCount() != n2.getArrayCount()) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getParameters(), n2.getParameters())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getThrows(), n2.getThrows())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeParameters(), n2.getTypeParameters())) {
+			return Boolean.FALSE;
+		}
+		if(n1.isDefault() != n2.isDefault()){
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+	
+	@Override public Boolean visit(final Parameter n1, final Node arg) {
+		final Parameter n2 = (Parameter) arg;
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+		return visit((BaseParameter) n1, arg);
+	}
+	
+	@Override public Boolean visit(MultiTypeParameter n1, Node arg) {
+		MultiTypeParameter n2 = (MultiTypeParameter) arg;
+		if (n1.getTypes().size() != n2.getTypes().size()) {
+			return Boolean.FALSE;
+		}
+		Iterator<Type> n1types = n1.getTypes().iterator();
+		Iterator<Type> n2types = n2.getTypes().iterator();
+		while (n1types.hasNext() && n2types.hasNext()) {
+			if (!nodeEquals(n1types.next(), n2types.next())) {
+				return Boolean.FALSE;
+			}
+		}
+		return visit((BaseParameter) n1, arg);
+	}
+
+	protected Boolean visit(final BaseParameter n1, final Node arg) {
+		final BaseParameter n2 = (BaseParameter) arg;
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getId(), n2.getId())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+	
+	@Override public Boolean visit(final EmptyMemberDeclaration n1, final Node arg) {
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final InitializerDeclaration n1, final Node arg) {
+		final InitializerDeclaration n2 = (InitializerDeclaration) arg;
+
+		if (!nodeEquals(n1.getBlock(), n2.getBlock())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final JavadocComment n1, final Node arg) {
+		final JavadocComment n2 = (JavadocComment) arg;
+
+		if (!objEquals(n1.getContent(), n2.getContent())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ClassOrInterfaceType n1, final Node arg) {
+		final ClassOrInterfaceType n2 = (ClassOrInterfaceType) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeArgs(), n2.getTypeArgs())) {
+			return Boolean.FALSE;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final PrimitiveType n1, final Node arg) {
+		final PrimitiveType n2 = (PrimitiveType) arg;
+
+		if (n1.getType() != n2.getType()) {
+			return Boolean.FALSE;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ReferenceType n1, final Node arg) {
+		final ReferenceType n2 = (ReferenceType) arg;
+
+		if (n1.getArrayCount() != n2.getArrayCount()) {
+			return Boolean.FALSE;
+		}
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+		List<List<AnnotationExpr>> n1a = n1.getArraysAnnotations();
+		List<List<AnnotationExpr>> n2a = n2.getArraysAnnotations();
+
+		if (n1a !=null && n2a!= null) {
+			if(n1a.size() != n2a.size()){
+				return Boolean.FALSE;
+			}
+			else{
+				int i = 0;
+				for(List<AnnotationExpr> aux: n1a){
+					if(!nodesEquals(aux, n2a.get(i))){
+						return Boolean.FALSE;
+					}
+					i++;
+				}
+			}
+		}
+		else if (n1a != n2a){
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	public Boolean visit(VoidType n1, Node arg) {
+		VoidType n2 = (VoidType) arg;
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final WildcardType n1, final Node arg) {
+		final WildcardType n2 = (WildcardType) arg;
+
+		if (!nodeEquals(n1.getExtends(), n2.getExtends())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getSuper(), n2.getSuper())) {
+			return Boolean.FALSE;
+		}
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final UnknownType n1, final Node arg) {
+		final WildcardType n2 = (WildcardType) arg;
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ArrayAccessExpr n1, final Node arg) {
+		final ArrayAccessExpr n2 = (ArrayAccessExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getIndex(), n2.getIndex())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ArrayCreationExpr n1, final Node arg) {
+		final ArrayCreationExpr n2 = (ArrayCreationExpr) arg;
+
+		if (n1.getArrayCount() != n2.getArrayCount()) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getInitializer(), n2.getInitializer())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getDimensions(), n2.getDimensions())) {
+			return Boolean.FALSE;
+		}
+		List<List<AnnotationExpr>> n1a = n1.getArraysAnnotations();
+		List<List<AnnotationExpr>> n2a = n2.getArraysAnnotations();
+
+		if (n1a !=null && n2a!= null) {
+			if(n1a.size() != n2a.size()){
+				return Boolean.FALSE;
+			}
+			else{
+				int i = 0;
+				for(List<AnnotationExpr> aux: n1a){
+					if(!nodesEquals(aux, n2a.get(i))){
+						return Boolean.FALSE;
+					}
+					i++;
+				}
+			}
+		}
+		else if (n1a != n2a){
+			return Boolean.FALSE;
+		}
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ArrayInitializerExpr n1, final Node arg) {
+		final ArrayInitializerExpr n2 = (ArrayInitializerExpr) arg;
+
+		if (!nodesEquals(n1.getValues(), n2.getValues())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final AssignExpr n1, final Node arg) {
+		final AssignExpr n2 = (AssignExpr) arg;
+
+		if (n1.getOperator() != n2.getOperator()) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getTarget(), n2.getTarget())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final BinaryExpr n1, final Node arg) {
+		final BinaryExpr n2 = (BinaryExpr) arg;
+
+		if (n1.getOperator() != n2.getOperator()) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getLeft(), n2.getLeft())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getRight(), n2.getRight())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final CastExpr n1, final Node arg) {
+		final CastExpr n2 = (CastExpr) arg;
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ClassExpr n1, final Node arg) {
+		final ClassExpr n2 = (ClassExpr) arg;
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ConditionalExpr n1, final Node arg) {
+		final ConditionalExpr n2 = (ConditionalExpr) arg;
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getThenExpr(), n2.getThenExpr())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getElseExpr(), n2.getElseExpr())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final EnclosedExpr n1, final Node arg) {
+		final EnclosedExpr n2 = (EnclosedExpr) arg;
+
+		if (!nodeEquals(n1.getInner(), n2.getInner())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final FieldAccessExpr n1, final Node arg) {
+		final FieldAccessExpr n2 = (FieldAccessExpr) arg;
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getField(), n2.getField())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeArgs(), n2.getTypeArgs())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final InstanceOfExpr n1, final Node arg) {
+		final InstanceOfExpr n2 = (InstanceOfExpr) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final StringLiteralExpr n1, final Node arg) {
+		final StringLiteralExpr n2 = (StringLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final IntegerLiteralExpr n1, final Node arg) {
+		final IntegerLiteralExpr n2 = (IntegerLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final LongLiteralExpr n1, final Node arg) {
+		final LongLiteralExpr n2 = (LongLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final IntegerLiteralMinValueExpr n1, final Node arg) {
+		final IntegerLiteralMinValueExpr n2 = (IntegerLiteralMinValueExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final LongLiteralMinValueExpr n1, final Node arg) {
+		final LongLiteralMinValueExpr n2 = (LongLiteralMinValueExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final CharLiteralExpr n1, final Node arg) {
+		final CharLiteralExpr n2 = (CharLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final DoubleLiteralExpr n1, final Node arg) {
+		final DoubleLiteralExpr n2 = (DoubleLiteralExpr) arg;
+
+		if (!objEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final BooleanLiteralExpr n1, final Node arg) {
+		final BooleanLiteralExpr n2 = (BooleanLiteralExpr) arg;
+
+		if (n1.getValue() != n2.getValue()) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final NullLiteralExpr n1, final Node arg) {
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final MethodCallExpr n1, final Node arg) {
+		final MethodCallExpr n2 = (MethodCallExpr) arg;
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeArgs(), n2.getTypeArgs())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final NameExpr n1, final Node arg) {
+		final NameExpr n2 = (NameExpr) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ObjectCreationExpr n1, final Node arg) {
+		final ObjectCreationExpr n2 = (ObjectCreationExpr) arg;
+
+		if (!nodeEquals(n1.getScope(), n2.getScope())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnonymousClassBody(), n2.getAnonymousClassBody())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeArgs(), n2.getTypeArgs())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final QualifiedNameExpr n1, final Node arg) {
+		final QualifiedNameExpr n2 = (QualifiedNameExpr) arg;
+
+		if (!nodeEquals(n1.getQualifier(), n2.getQualifier())) {
+			return Boolean.FALSE;
+		}
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ThisExpr n1, final Node arg) {
+		final ThisExpr n2 = (ThisExpr) arg;
+
+		if (!nodeEquals(n1.getClassExpr(), n2.getClassExpr())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final SuperExpr n1, final Node arg) {
+		final SuperExpr n2 = (SuperExpr) arg;
+
+		if (!nodeEquals(n1.getClassExpr(), n2.getClassExpr())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final UnaryExpr n1, final Node arg) {
+		final UnaryExpr n2 = (UnaryExpr) arg;
+
+		if (n1.getOperator() != n2.getOperator()) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final VariableDeclarationExpr n1, final Node arg) {
+		final VariableDeclarationExpr n2 = (VariableDeclarationExpr) arg;
+
+		if (n1.getModifiers() != n2.getModifiers()) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getAnnotations(), n2.getAnnotations())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getType(), n2.getType())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getVars(), n2.getVars())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final MarkerAnnotationExpr n1, final Node arg) {
+		final MarkerAnnotationExpr n2 = (MarkerAnnotationExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final SingleMemberAnnotationExpr n1, final Node arg) {
+		final SingleMemberAnnotationExpr n2 = (SingleMemberAnnotationExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getMemberValue(), n2.getMemberValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final NormalAnnotationExpr n1, final Node arg) {
+		final NormalAnnotationExpr n2 = (NormalAnnotationExpr) arg;
+
+		if (!nodeEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getPairs(), n2.getPairs())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final MemberValuePair n1, final Node arg) {
+		final MemberValuePair n2 = (MemberValuePair) arg;
+
+		if (!objEquals(n1.getName(), n2.getName())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getValue(), n2.getValue())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ExplicitConstructorInvocationStmt n1, final Node arg) {
+		final ExplicitConstructorInvocationStmt n2 = (ExplicitConstructorInvocationStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getArgs(), n2.getArgs())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getTypeArgs(), n2.getTypeArgs())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final TypeDeclarationStmt n1, final Node arg) {
+		final TypeDeclarationStmt n2 = (TypeDeclarationStmt) arg;
+
+		if (!nodeEquals(n1.getTypeDeclaration(), n2.getTypeDeclaration())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final AssertStmt n1, final Node arg) {
+		final AssertStmt n2 = (AssertStmt) arg;
+
+		if (!nodeEquals(n1.getCheck(), n2.getCheck())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getMessage(), n2.getMessage())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final BlockStmt n1, final Node arg) {
+		final BlockStmt n2 = (BlockStmt) arg;
+
+		if (!nodesEquals(n1.getStmts(), n2.getStmts())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final LabeledStmt n1, final Node arg) {
+		final LabeledStmt n2 = (LabeledStmt) arg;
+
+		if (!nodeEquals(n1.getStmt(), n2.getStmt())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final EmptyStmt n1, final Node arg) {
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ExpressionStmt n1, final Node arg) {
+		final ExpressionStmt n2 = (ExpressionStmt) arg;
+
+		if (!nodeEquals(n1.getExpression(), n2.getExpression())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final SwitchStmt n1, final Node arg) {
+		final SwitchStmt n2 = (SwitchStmt) arg;
+
+		if (!nodeEquals(n1.getSelector(), n2.getSelector())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getEntries(), n2.getEntries())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final SwitchEntryStmt n1, final Node arg) {
+		final SwitchEntryStmt n2 = (SwitchEntryStmt) arg;
+
+		if (!nodeEquals(n1.getLabel(), n2.getLabel())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getStmts(), n2.getStmts())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final BreakStmt n1, final Node arg) {
+		final BreakStmt n2 = (BreakStmt) arg;
+
+		if (!objEquals(n1.getId(), n2.getId())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ReturnStmt n1, final Node arg) {
+		final ReturnStmt n2 = (ReturnStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final IfStmt n1, final Node arg) {
+		final IfStmt n2 = (IfStmt) arg;
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getThenStmt(), n2.getThenStmt())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getElseStmt(), n2.getElseStmt())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final WhileStmt n1, final Node arg) {
+		final WhileStmt n2 = (WhileStmt) arg;
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ContinueStmt n1, final Node arg) {
+		final ContinueStmt n2 = (ContinueStmt) arg;
+
+		if (!objEquals(n1.getId(), n2.getId())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final DoStmt n1, final Node arg) {
+		final DoStmt n2 = (DoStmt) arg;
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getCondition(), n2.getCondition())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ForeachStmt n1, final Node arg) {
+		final ForeachStmt n2 = (ForeachStmt) arg;
+
+		if (!nodeEquals(n1.getVariable(), n2.getVariable())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getIterable(), n2.getIterable())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ForStmt n1, final Node arg) {
+		final ForStmt n2 = (ForStmt) arg;
+
+		if (!nodesEquals(n1.getInit(), n2.getInit())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getCompare(), n2.getCompare())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getUpdate(), n2.getUpdate())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getBody(), n2.getBody())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final ThrowStmt n1, final Node arg) {
+		final ThrowStmt n2 = (ThrowStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final SynchronizedStmt n1, final Node arg) {
+		final SynchronizedStmt n2 = (SynchronizedStmt) arg;
+
+		if (!nodeEquals(n1.getExpr(), n2.getExpr())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getBlock(), n2.getBlock())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final TryStmt n1, final Node arg) {
+		final TryStmt n2 = (TryStmt) arg;
+
+		if (!nodeEquals(n1.getTryBlock(), n2.getTryBlock())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodesEquals(n1.getCatchs(), n2.getCatchs())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getFinallyBlock(), n2.getFinallyBlock())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+	@Override public Boolean visit(final CatchClause n1, final Node arg) {
+		final CatchClause n2 = (CatchClause) arg;
+
+		if (!nodeEquals(n1.getExcept(), n2.getExcept())) {
+			return Boolean.FALSE;
+		}
+
+		if (!nodeEquals(n1.getCatchBlock(), n2.getCatchBlock())) {
+			return Boolean.FALSE;
+		}
+
+		return Boolean.TRUE;
+	}
+
+    @Override
+    public Boolean visit(LambdaExpr n1, Node arg) {
+        LambdaExpr n2 = (LambdaExpr) arg;
+        if (!nodesEquals(n1.getParameters(), n2.getParameters())) {
+            return Boolean.FALSE;
+        }
+        if(n1.isParametersEnclosed() != n2.isParametersEnclosed()){
+            return Boolean.FALSE;
+        }
+        if (!nodeEquals(n1.getBody(), n2.getBody())) {
+            return Boolean.FALSE;
+        }
+        return Boolean.TRUE;
+    }
+
+    @Override
+    public Boolean visit(MethodReferenceExpr n1, Node arg) {
+        MethodReferenceExpr n2 = (MethodReferenceExpr) arg;
+        if (!nodeEquals(n1.getScope(), n2.getScope())) {
+            return Boolean.FALSE;
+        }
+        if (!nodesEquals(n1.getTypeParameters(), n2.getTypeParameters())) {
+            return Boolean.FALSE;
+        }
+        if (!objEquals(n1.getIdentifier(), n2.getIdentifier())) {
+            return Boolean.FALSE;
+        }
+        return Boolean.TRUE;
+    }
+
+    @Override
+    public Boolean visit(TypeExpr n, Node arg) {
+        TypeExpr n2 = (TypeExpr) arg;
+        if (!nodeEquals(n.getType(), n2.getType())) {
+            return Boolean.FALSE;
+        }
+        return Boolean.TRUE;
+    }
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/GenericVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/GenericVisitor.java
new file mode 100644
index 0000000..58fbf6d
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/GenericVisitor.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * A visitor that has a return value.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public interface GenericVisitor<R, A> {
+
+	//- Compilation Unit ----------------------------------
+
+	public R visit(CompilationUnit n, A arg);
+
+	public R visit(PackageDeclaration n, A arg);
+
+	public R visit(ImportDeclaration n, A arg);
+
+	public R visit(TypeParameter n, A arg);
+
+	public R visit(LineComment n, A arg);
+
+	public R visit(BlockComment n, A arg);
+
+	//- Body ----------------------------------------------
+
+	public R visit(ClassOrInterfaceDeclaration n, A arg);
+
+	public R visit(EnumDeclaration n, A arg);
+
+	public R visit(EmptyTypeDeclaration n, A arg);
+
+	public R visit(EnumConstantDeclaration n, A arg);
+
+	public R visit(AnnotationDeclaration n, A arg);
+
+	public R visit(AnnotationMemberDeclaration n, A arg);
+
+	public R visit(FieldDeclaration n, A arg);
+
+	public R visit(VariableDeclarator n, A arg);
+
+	public R visit(VariableDeclaratorId n, A arg);
+
+	public R visit(ConstructorDeclaration n, A arg);
+
+	public R visit(MethodDeclaration n, A arg);
+
+	public R visit(Parameter n, A arg);
+	
+	public R visit(MultiTypeParameter n, A arg);
+
+	public R visit(EmptyMemberDeclaration n, A arg);
+
+	public R visit(InitializerDeclaration n, A arg);
+
+	public R visit(JavadocComment n, A arg);
+
+	//- Type ----------------------------------------------
+
+	public R visit(ClassOrInterfaceType n, A arg);
+
+	public R visit(PrimitiveType n, A arg);
+
+	public R visit(ReferenceType n, A arg);
+
+	public R visit(VoidType n, A arg);
+
+	public R visit(WildcardType n, A arg);
+
+	public R visit(UnknownType n, A arg);
+
+	//- Expression ----------------------------------------
+
+	public R visit(ArrayAccessExpr n, A arg);
+
+	public R visit(ArrayCreationExpr n, A arg);
+
+	public R visit(ArrayInitializerExpr n, A arg);
+
+	public R visit(AssignExpr n, A arg);
+
+	public R visit(BinaryExpr n, A arg);
+
+	public R visit(CastExpr n, A arg);
+
+	public R visit(ClassExpr n, A arg);
+
+	public R visit(ConditionalExpr n, A arg);
+
+	public R visit(EnclosedExpr n, A arg);
+
+	public R visit(FieldAccessExpr n, A arg);
+
+	public R visit(InstanceOfExpr n, A arg);
+
+	public R visit(StringLiteralExpr n, A arg);
+
+	public R visit(IntegerLiteralExpr n, A arg);
+
+	public R visit(LongLiteralExpr n, A arg);
+
+	public R visit(IntegerLiteralMinValueExpr n, A arg);
+
+	public R visit(LongLiteralMinValueExpr n, A arg);
+
+	public R visit(CharLiteralExpr n, A arg);
+
+	public R visit(DoubleLiteralExpr n, A arg);
+
+	public R visit(BooleanLiteralExpr n, A arg);
+
+	public R visit(NullLiteralExpr n, A arg);
+
+	public R visit(MethodCallExpr n, A arg);
+
+	public R visit(NameExpr n, A arg);
+
+	public R visit(ObjectCreationExpr n, A arg);
+
+	public R visit(QualifiedNameExpr n, A arg);
+
+	public R visit(ThisExpr n, A arg);
+
+	public R visit(SuperExpr n, A arg);
+
+	public R visit(UnaryExpr n, A arg);
+
+	public R visit(VariableDeclarationExpr n, A arg);
+
+	public R visit(MarkerAnnotationExpr n, A arg);
+
+	public R visit(SingleMemberAnnotationExpr n, A arg);
+
+	public R visit(NormalAnnotationExpr n, A arg);
+
+	public R visit(MemberValuePair n, A arg);
+
+	//- Statements ----------------------------------------
+
+	public R visit(ExplicitConstructorInvocationStmt n, A arg);
+
+	public R visit(TypeDeclarationStmt n, A arg);
+
+	public R visit(AssertStmt n, A arg);
+
+	public R visit(BlockStmt n, A arg);
+
+	public R visit(LabeledStmt n, A arg);
+
+	public R visit(EmptyStmt n, A arg);
+
+	public R visit(ExpressionStmt n, A arg);
+
+	public R visit(SwitchStmt n, A arg);
+
+	public R visit(SwitchEntryStmt n, A arg);
+
+	public R visit(BreakStmt n, A arg);
+
+	public R visit(ReturnStmt n, A arg);
+
+	public R visit(IfStmt n, A arg);
+
+	public R visit(WhileStmt n, A arg);
+
+	public R visit(ContinueStmt n, A arg);
+
+	public R visit(DoStmt n, A arg);
+
+	public R visit(ForeachStmt n, A arg);
+
+	public R visit(ForStmt n, A arg);
+
+	public R visit(ThrowStmt n, A arg);
+
+	public R visit(SynchronizedStmt n, A arg);
+
+	public R visit(TryStmt n, A arg);
+
+	public R visit(CatchClause n, A arg);
+
+    public R visit(LambdaExpr n, A arg);
+
+    public R visit(MethodReferenceExpr n, A arg);
+
+    public R visit(TypeExpr n, A arg);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
new file mode 100644
index 0000000..eac9cab
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/GenericVisitorAdapter.java
@@ -0,0 +1,1613 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class GenericVisitorAdapter<R, A> implements GenericVisitor<R, A> {
+
+	@Override
+	public R visit(final AnnotationDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getMembers() != null) {
+			for (final BodyDeclaration member : n.getMembers()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final AnnotationMemberDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getDefaultValue() != null) {
+			{
+				R result = n.getDefaultValue().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ArrayAccessExpr n, final A arg) {
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getIndex().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ArrayCreationExpr n, final A arg) {
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getDimensions() != null) {
+			for (final Expression dim : n.getDimensions()) {
+				{
+					R result = dim.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		} else {
+			{
+				R result = n.getInitializer().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ArrayInitializerExpr n, final A arg) {
+		if (n.getValues() != null) {
+			for (final Expression expr : n.getValues()) {
+				{
+					R result = expr.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final AssertStmt n, final A arg) {
+		{
+			R result = n.getCheck().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getMessage() != null) {
+			{
+				R result = n.getMessage().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final AssignExpr n, final A arg) {
+		{
+			R result = n.getTarget().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getValue().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final BinaryExpr n, final A arg) {
+		{
+			R result = n.getLeft().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getRight().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final BlockStmt n, final A arg) {
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				{
+					R result = s.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+
+	}
+
+	@Override
+	public R visit(final BooleanLiteralExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final BreakStmt n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final CastExpr n, final A arg) {
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final CatchClause n, final A arg) {
+		{
+			R result = n.getExcept().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getCatchBlock().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+
+	}
+
+	@Override
+	public R visit(final CharLiteralExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final ClassExpr n, final A arg) {
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ClassOrInterfaceDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getExtends() != null) {
+			for (final ClassOrInterfaceType c : n.getExtends()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+
+		if (n.getImplements() != null) {
+			for (final ClassOrInterfaceType c : n.getImplements()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getMembers() != null) {
+			for (final BodyDeclaration member : n.getMembers()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ClassOrInterfaceType n, final A arg) {
+		if (n.getScope() != null) {
+			{
+				R result = n.getScope().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final CompilationUnit n, final A arg) {
+		if (n.getPackage() != null) {
+			{
+				R result = n.getPackage().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getImports() != null) {
+			for (final ImportDeclaration i : n.getImports()) {
+				{
+					R result = i.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypes() != null) {
+			for (final TypeDeclaration typeDeclaration : n.getTypes()) {
+				{
+					R result = typeDeclaration.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ConditionalExpr n, final A arg) {
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getThenExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getElseExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ConstructorDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				{
+					R result = p.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final NameExpr name : n.getThrows()) {
+				{
+					R result = name.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getBlock().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ContinueStmt n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final DoStmt n, final A arg) {
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final DoubleLiteralExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final EmptyMemberDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final EmptyStmt n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final EmptyTypeDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final EnclosedExpr n, final A arg) {
+		{
+			R result = n.getInner().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final EnumConstantDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getClassBody() != null) {
+			for (final BodyDeclaration member : n.getClassBody()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final EnumDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getImplements() != null) {
+			for (final ClassOrInterfaceType c : n.getImplements()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getEntries() != null) {
+			for (final EnumConstantDeclaration e : n.getEntries()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getMembers() != null) {
+			for (final BodyDeclaration member : n.getMembers()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+		if (!n.isThis()) {
+			if (n.getExpr() != null) {
+				{
+					R result = n.getExpr().accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ExpressionStmt n, final A arg) {
+		{
+			R result = n.getExpression().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final FieldAccessExpr n, final A arg) {
+		{
+			R result = n.getScope().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final FieldDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		for (final VariableDeclarator var : n.getVariables()) {
+			{
+				R result = var.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ForeachStmt n, final A arg) {
+		{
+			R result = n.getVariable().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getIterable().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ForStmt n, final A arg) {
+		if (n.getInit() != null) {
+			for (final Expression e : n.getInit()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getCompare() != null) {
+			{
+				R result = n.getCompare().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getUpdate() != null) {
+			for (final Expression e : n.getUpdate()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final IfStmt n, final A arg) {
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getThenStmt().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getElseStmt() != null) {
+			{
+				R result = n.getElseStmt().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ImportDeclaration n, final A arg) {
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final InitializerDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		{
+			R result = n.getBlock().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final InstanceOfExpr n, final A arg) {
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final IntegerLiteralExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final IntegerLiteralMinValueExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final JavadocComment n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final LabeledStmt n, final A arg) {
+		{
+			R result = n.getStmt().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final LongLiteralExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final LongLiteralMinValueExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final MarkerAnnotationExpr n, final A arg) {
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final MemberValuePair n, final A arg) {
+		{
+			R result = n.getValue().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final MethodCallExpr n, final A arg) {
+		if (n.getScope() != null) {
+			{
+				R result = n.getScope().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final MethodDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			{
+				R result = n.getJavaDoc().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				{
+					R result = p.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final NameExpr name : n.getThrows()) {
+				{
+					R result = name.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getBody() != null) {
+			{
+				R result = n.getBody().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final NameExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final NormalAnnotationExpr n, final A arg) {
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getPairs() != null) {
+			for (final MemberValuePair m : n.getPairs()) {
+				{
+					R result = m.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final NullLiteralExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final ObjectCreationExpr n, final A arg) {
+		if (n.getScope() != null) {
+			{
+				R result = n.getScope().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				{
+					R result = t.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getAnonymousClassBody() != null) {
+			for (final BodyDeclaration member : n.getAnonymousClassBody()) {
+				{
+					R result = member.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final PackageDeclaration n, final A arg) {
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final Parameter n, final A arg) {
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getId().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+	
+	@Override
+	public R visit(final MultiTypeParameter n, final A arg) {
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			for (final Type type : n.getTypes()) {
+				R result = type.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		{
+			R result = n.getId().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final PrimitiveType n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final QualifiedNameExpr n, final A arg) {
+		{
+			R result = n.getQualifier().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ReferenceType n, final A arg) {
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ReturnStmt n, final A arg) {
+		if (n.getExpr() != null) {
+			{
+				R result = n.getExpr().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final SingleMemberAnnotationExpr n, final A arg) {
+		{
+			R result = n.getName().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getMemberValue().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final StringLiteralExpr n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final SuperExpr n, final A arg) {
+		if (n.getClassExpr() != null) {
+			{
+				R result = n.getClassExpr().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final SwitchEntryStmt n, final A arg) {
+		if (n.getLabel() != null) {
+			{
+				R result = n.getLabel().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				{
+					R result = s.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final SwitchStmt n, final A arg) {
+		{
+			R result = n.getSelector().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getEntries() != null) {
+			for (final SwitchEntryStmt e : n.getEntries()) {
+				{
+					R result = e.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+
+	}
+
+	@Override
+	public R visit(final SynchronizedStmt n, final A arg) {
+		{
+			if (n.getExpr() != null) {
+			    R result = n.getExpr().accept(this, arg);
+			    if (result != null) {
+				    return result;
+			    }
+			}
+		}
+		{
+			R result = n.getBlock().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ThisExpr n, final A arg) {
+		if (n.getClassExpr() != null) {
+			{
+				R result = n.getClassExpr().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final ThrowStmt n, final A arg) {
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final TryStmt n, final A arg) {
+		if (n.getResources() != null) {
+			for (final VariableDeclarationExpr v : n.getResources()) {
+				{
+					R result = v.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getTryBlock().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getCatchs() != null) {
+			for (final CatchClause c : n.getCatchs()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		if (n.getFinallyBlock() != null) {
+			{
+				R result = n.getFinallyBlock().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final TypeDeclarationStmt n, final A arg) {
+		{
+			R result = n.getTypeDeclaration().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final TypeParameter n, final A arg) {
+		if (n.getTypeBound() != null) {
+			for (final ClassOrInterfaceType c : n.getTypeBound()) {
+				{
+					R result = c.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final UnaryExpr n, final A arg) {
+		{
+			R result = n.getExpr().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final UnknownType n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final VariableDeclarationExpr n, final A arg) {
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				{
+					R result = a.accept(this, arg);
+					if (result != null) {
+						return result;
+					}
+				}
+			}
+		}
+		{
+			R result = n.getType().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		for (final VariableDeclarator v : n.getVars()) {
+			{
+				R result = v.accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final VariableDeclarator n, final A arg) {
+		{
+			R result = n.getId().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		if (n.getInit() != null) {
+			{
+				R result = n.getInit().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final VariableDeclaratorId n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final VoidType n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final WhileStmt n, final A arg) {
+		{
+			R result = n.getCondition().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		{
+			R result = n.getBody().accept(this, arg);
+			if (result != null) {
+				return result;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public R visit(final WildcardType n, final A arg) {
+		if (n.getExtends() != null) {
+			{
+				R result = n.getExtends().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		if (n.getSuper() != null) {
+			{
+				R result = n.getSuper().accept(this, arg);
+				if (result != null) {
+					return result;
+				}
+			}
+		}
+		return null;
+	}
+
+    @Override
+    public R visit(LambdaExpr n, A arg) {
+        return null;
+    }
+
+    @Override
+    public R visit(MethodReferenceExpr n, A arg){
+        return null;
+    }
+
+    @Override
+    public R visit(TypeExpr n, A arg){
+        return null;
+    }
+
+	@Override
+	public R visit(final BlockComment n, final A arg) {
+		return null;
+	}
+
+	@Override
+	public R visit(final LineComment n, final A arg) {
+		return null;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java
new file mode 100644
index 0000000..3d23cea
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/ModifierVisitorAdapter.java
@@ -0,0 +1,973 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BaseParameter;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.ArrayAccessExpr;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.ArrayInitializerExpr;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.expr.BooleanLiteralExpr;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.CharLiteralExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
+import com.github.javaparser.ast.expr.ConditionalExpr;
+import com.github.javaparser.ast.expr.DoubleLiteralExpr;
+import com.github.javaparser.ast.expr.EnclosedExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.InstanceOfExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.expr.LongLiteralExpr;
+import com.github.javaparser.ast.expr.LongLiteralMinValueExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.MemberValuePair;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.MethodReferenceExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.NullLiteralExpr;
+import com.github.javaparser.ast.expr.ObjectCreationExpr;
+import com.github.javaparser.ast.expr.QualifiedNameExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.SuperExpr;
+import com.github.javaparser.ast.expr.ThisExpr;
+import com.github.javaparser.ast.expr.TypeExpr;
+import com.github.javaparser.ast.expr.UnaryExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * This visitor adapter can be used to save time when some specific nodes needs
+ * to be changed. To do that just extend this class and override the methods
+ * from the nodes who needs to be changed, returning the changed node.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public abstract class ModifierVisitorAdapter<A> implements GenericVisitor<Node, A> {
+
+	private void removeNulls(final List<?> list) {
+		for (int i = list.size() - 1; i >= 0; i--) {
+			if (list.get(i) == null) {
+				list.remove(i);
+			}
+		}
+	}
+
+	@Override public Node visit(final AnnotationDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<BodyDeclaration> members = n.getMembers();
+		if (members != null) {
+			for (int i = 0; i < members.size(); i++) {
+				members.set(i, (BodyDeclaration) members.get(i).accept(this, arg));
+			}
+			removeNulls(members);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final AnnotationMemberDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		n.setType((Type) n.getType().accept(this, arg));
+		if (n.getDefaultValue() != null) {
+			n.setDefaultValue((Expression) n.getDefaultValue().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ArrayAccessExpr n, final A arg) {
+		n.setName((Expression) n.getName().accept(this, arg));
+		n.setIndex((Expression) n.getIndex().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ArrayCreationExpr n, final A arg) {
+		n.setType((Type) n.getType().accept(this, arg));
+		if (n.getDimensions() != null) {
+			final List<Expression> dimensions = n.getDimensions();
+			if (dimensions != null) {
+				for (int i = 0; i < dimensions.size(); i++) {
+					dimensions.set(i, (Expression) dimensions.get(i).accept(this, arg));
+				}
+				removeNulls(dimensions);
+			}
+		} else {
+			n.setInitializer((ArrayInitializerExpr) n.getInitializer().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ArrayInitializerExpr n, final A arg) {
+		if (n.getValues() != null) {
+			final List<Expression> values = n.getValues();
+			if (values != null) {
+				for (int i = 0; i < values.size(); i++) {
+					values.set(i, (Expression) values.get(i).accept(this, arg));
+				}
+				removeNulls(values);
+			}
+		}
+		return n;
+	}
+
+	@Override public Node visit(final AssertStmt n, final A arg) {
+		n.setCheck((Expression) n.getCheck().accept(this, arg));
+		if (n.getMessage() != null) {
+			n.setMessage((Expression) n.getMessage().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final AssignExpr n, final A arg) {
+		n.setTarget((Expression) n.getTarget().accept(this, arg));
+		n.setValue((Expression) n.getValue().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final BinaryExpr n, final A arg) {
+		n.setLeft((Expression) n.getLeft().accept(this, arg));
+		n.setRight((Expression) n.getRight().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final BlockStmt n, final A arg) {
+		final List<Statement> stmts = n.getStmts();
+		if (stmts != null) {
+			for (int i = 0; i < stmts.size(); i++) {
+				stmts.set(i, (Statement) stmts.get(i).accept(this, arg));
+			}
+			removeNulls(stmts);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final BooleanLiteralExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final BreakStmt n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final CastExpr n, final A arg) {
+		n.setType((Type) n.getType().accept(this, arg));
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final CatchClause n, final A arg) {
+		n.setExcept((MultiTypeParameter) n.getExcept().accept(this, arg));
+		n.setCatchBlock((BlockStmt) n.getCatchBlock().accept(this, arg));
+		return n;
+
+	}
+
+	@Override public Node visit(final CharLiteralExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final ClassExpr n, final A arg) {
+		n.setType((Type) n.getType().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ClassOrInterfaceDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<TypeParameter> typeParameters = n.getTypeParameters();
+		if (typeParameters != null) {
+			for (int i = 0; i < typeParameters.size(); i++) {
+				typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg));
+			}
+			removeNulls(typeParameters);
+		}
+		final List<ClassOrInterfaceType> extendz = n.getExtends();
+		if (extendz != null) {
+			for (int i = 0; i < extendz.size(); i++) {
+				extendz.set(i, (ClassOrInterfaceType) extendz.get(i).accept(this, arg));
+			}
+			removeNulls(extendz);
+		}
+		final List<ClassOrInterfaceType> implementz = n.getImplements();
+		if (implementz != null) {
+			for (int i = 0; i < implementz.size(); i++) {
+				implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg));
+			}
+			removeNulls(implementz);
+		}
+		final List<BodyDeclaration> members = n.getMembers();
+		if (members != null) {
+			for (int i = 0; i < members.size(); i++) {
+				members.set(i, (BodyDeclaration) members.get(i).accept(this, arg));
+			}
+			removeNulls(members);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ClassOrInterfaceType n, final A arg) {
+		if (n.getScope() != null) {
+			n.setScope((ClassOrInterfaceType) n.getScope().accept(this, arg));
+		}
+		final List<Type> typeArgs = n.getTypeArgs();
+		if (typeArgs != null) {
+			for (int i = 0; i < typeArgs.size(); i++) {
+				typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg));
+			}
+			removeNulls(typeArgs);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final CompilationUnit n, final A arg) {
+		if (n.getPackage() != null) {
+			n.setPackage((PackageDeclaration) n.getPackage().accept(this, arg));
+		}
+		final List<ImportDeclaration> imports = n.getImports();
+		if (imports != null) {
+			for (int i = 0; i < imports.size(); i++) {
+				imports.set(i, (ImportDeclaration) imports.get(i).accept(this, arg));
+			}
+			removeNulls(imports);
+		}
+		final List<TypeDeclaration> types = n.getTypes();
+		if (types != null) {
+			for (int i = 0; i < types.size(); i++) {
+				types.set(i, (TypeDeclaration) types.get(i).accept(this, arg));
+			}
+			removeNulls(types);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ConditionalExpr n, final A arg) {
+		n.setCondition((Expression) n.getCondition().accept(this, arg));
+		n.setThenExpr((Expression) n.getThenExpr().accept(this, arg));
+		n.setElseExpr((Expression) n.getElseExpr().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ConstructorDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<TypeParameter> typeParameters = n.getTypeParameters();
+		if (typeParameters != null) {
+			for (int i = 0; i < typeParameters.size(); i++) {
+				typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg));
+			}
+			removeNulls(typeParameters);
+		}
+		final List<Parameter> parameters = n.getParameters();
+		if (parameters != null) {
+			for (int i = 0; i < parameters.size(); i++) {
+				parameters.set(i, (Parameter) parameters.get(i).accept(this, arg));
+			}
+			removeNulls(parameters);
+		}
+		final List<NameExpr> throwz = n.getThrows();
+		if (throwz != null) {
+			for (int i = 0; i < throwz.size(); i++) {
+				throwz.set(i, (NameExpr) throwz.get(i).accept(this, arg));
+			}
+			removeNulls(throwz);
+		}
+		n.setBlock((BlockStmt) n.getBlock().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ContinueStmt n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final DoStmt n, final A arg) {
+		n.setBody((Statement) n.getBody().accept(this, arg));
+		n.setCondition((Expression) n.getCondition().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final DoubleLiteralExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final EmptyMemberDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final EmptyStmt n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final EmptyTypeDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final EnclosedExpr n, final A arg) {
+		n.setInner((Expression) n.getInner().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final EnumConstantDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+		final List<BodyDeclaration> classBody = n.getClassBody();
+		if (classBody != null) {
+			for (int i = 0; i < classBody.size(); i++) {
+				classBody.set(i, (BodyDeclaration) classBody.get(i).accept(this, arg));
+			}
+			removeNulls(classBody);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final EnumDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<ClassOrInterfaceType> implementz = n.getImplements();
+		if (implementz != null) {
+			for (int i = 0; i < implementz.size(); i++) {
+				implementz.set(i, (ClassOrInterfaceType) implementz.get(i).accept(this, arg));
+			}
+			removeNulls(implementz);
+		}
+		final List<EnumConstantDeclaration> entries = n.getEntries();
+		if (entries != null) {
+			for (int i = 0; i < entries.size(); i++) {
+				entries.set(i, (EnumConstantDeclaration) entries.get(i).accept(this, arg));
+			}
+			removeNulls(entries);
+		}
+		final List<BodyDeclaration> members = n.getMembers();
+		if (members != null) {
+			for (int i = 0; i < members.size(); i++) {
+				members.set(i, (BodyDeclaration) members.get(i).accept(this, arg));
+			}
+			removeNulls(members);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+		if (!n.isThis()) {
+			if (n.getExpr() != null) {
+				n.setExpr((Expression) n.getExpr().accept(this, arg));
+			}
+		}
+		final List<Type> typeArgs = n.getTypeArgs();
+		if (typeArgs != null) {
+			for (int i = 0; i < typeArgs.size(); i++) {
+				typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg));
+			}
+			removeNulls(typeArgs);
+		}
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ExpressionStmt n, final A arg) {
+		n.setExpression((Expression) n.getExpression().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final FieldAccessExpr n, final A arg) {
+		n.setScope((Expression) n.getScope().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final FieldDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		n.setType((Type) n.getType().accept(this, arg));
+		final List<VariableDeclarator> variables = n.getVariables();
+		for (int i = 0; i < variables.size(); i++) {
+			variables.set(i, (VariableDeclarator) variables.get(i).accept(this, arg));
+		}
+		removeNulls(variables);
+		return n;
+	}
+
+	@Override public Node visit(final ForeachStmt n, final A arg) {
+		n.setVariable((VariableDeclarationExpr) n.getVariable().accept(this, arg));
+		n.setIterable((Expression) n.getIterable().accept(this, arg));
+		n.setBody((Statement) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ForStmt n, final A arg) {
+		final List<Expression> init = n.getInit();
+		if (init != null) {
+			for (int i = 0; i < init.size(); i++) {
+				init.set(i, (Expression) init.get(i).accept(this, arg));
+			}
+			removeNulls(init);
+		}
+		if (n.getCompare() != null) {
+			n.setCompare((Expression) n.getCompare().accept(this, arg));
+		}
+		final List<Expression> update = n.getUpdate();
+		if (update != null) {
+			for (int i = 0; i < update.size(); i++) {
+				update.set(i, (Expression) update.get(i).accept(this, arg));
+			}
+			removeNulls(update);
+		}
+		n.setBody((Statement) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final IfStmt n, final A arg) {
+		n.setCondition((Expression) n.getCondition().accept(this, arg));
+		n.setThenStmt((Statement) n.getThenStmt().accept(this, arg));
+		if (n.getElseStmt() != null) {
+			n.setElseStmt((Statement) n.getElseStmt().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ImportDeclaration n, final A arg) {
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final InitializerDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		n.setBlock((BlockStmt) n.getBlock().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final InstanceOfExpr n, final A arg) {
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		n.setType((Type) n.getType().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final IntegerLiteralExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final IntegerLiteralMinValueExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final JavadocComment n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final LabeledStmt n, final A arg) {
+		n.setStmt((Statement) n.getStmt().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final LongLiteralExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final LongLiteralMinValueExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final MarkerAnnotationExpr n, final A arg) {
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final MemberValuePair n, final A arg) {
+		n.setValue((Expression) n.getValue().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final MethodCallExpr n, final A arg) {
+		if (n.getScope() != null) {
+			n.setScope((Expression) n.getScope().accept(this, arg));
+		}
+		final List<Type> typeArgs = n.getTypeArgs();
+		if (typeArgs != null) {
+			for (int i = 0; i < typeArgs.size(); i++) {
+				typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg));
+			}
+			removeNulls(typeArgs);
+		}
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final MethodDeclaration n, final A arg) {
+		if (n.getJavaDoc() != null) {
+			n.setJavaDoc((JavadocComment) n.getJavaDoc().accept(this, arg));
+		}
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		final List<TypeParameter> typeParameters = n.getTypeParameters();
+		if (typeParameters != null) {
+			for (int i = 0; i < typeParameters.size(); i++) {
+				typeParameters.set(i, (TypeParameter) typeParameters.get(i).accept(this, arg));
+			}
+			removeNulls(typeParameters);
+		}
+		n.setType((Type) n.getType().accept(this, arg));
+		final List<Parameter> parameters = n.getParameters();
+		if (parameters != null) {
+			for (int i = 0; i < parameters.size(); i++) {
+				parameters.set(i, (Parameter) parameters.get(i).accept(this, arg));
+			}
+			removeNulls(parameters);
+		}
+		final List<NameExpr> throwz = n.getThrows();
+		if (throwz != null) {
+			for (int i = 0; i < throwz.size(); i++) {
+				throwz.set(i, (NameExpr) throwz.get(i).accept(this, arg));
+			}
+			removeNulls(throwz);
+		}
+		if (n.getBody() != null) {
+			n.setBody((BlockStmt) n.getBody().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final NameExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final NormalAnnotationExpr n, final A arg) {
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		final List<MemberValuePair> pairs = n.getPairs();
+		if (pairs != null) {
+			for (int i = 0; i < pairs.size(); i++) {
+				pairs.set(i, (MemberValuePair) pairs.get(i).accept(this, arg));
+			}
+			removeNulls(pairs);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final NullLiteralExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final ObjectCreationExpr n, final A arg) {
+		if (n.getScope() != null) {
+			n.setScope((Expression) n.getScope().accept(this, arg));
+		}
+		final List<Type> typeArgs = n.getTypeArgs();
+		if (typeArgs != null) {
+			for (int i = 0; i < typeArgs.size(); i++) {
+				typeArgs.set(i, (Type) typeArgs.get(i).accept(this, arg));
+			}
+			removeNulls(typeArgs);
+		}
+		n.setType((ClassOrInterfaceType) n.getType().accept(this, arg));
+		final List<Expression> args = n.getArgs();
+		if (args != null) {
+			for (int i = 0; i < args.size(); i++) {
+				args.set(i, (Expression) args.get(i).accept(this, arg));
+			}
+			removeNulls(args);
+		}
+		final List<BodyDeclaration> anonymousClassBody = n.getAnonymousClassBody();
+		if (anonymousClassBody != null) {
+			for (int i = 0; i < anonymousClassBody.size(); i++) {
+				anonymousClassBody.set(i, (BodyDeclaration) anonymousClassBody.get(i).accept(this, arg));
+			}
+			removeNulls(anonymousClassBody);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final PackageDeclaration n, final A arg) {
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		return n;
+	}
+	
+	@Override public Node visit(final Parameter n, final A arg) {
+		visit((BaseParameter) n, arg);
+		n.setType((Type) n.getType().accept(this, arg));
+		return n;
+	}
+	
+	@Override public Node visit(MultiTypeParameter n, A arg) {
+    	visit((BaseParameter) n, arg);
+    	List<Type> types = new LinkedList<Type>();
+    	for (Type type : n.getTypes()) {
+    		types.add((Type) type.accept(this, arg));
+    	}
+        n.setTypes(types);
+        return n;
+    }
+
+	protected Node visit(final BaseParameter n, final A arg) {
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		
+		n.setId((VariableDeclaratorId) n.getId().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final PrimitiveType n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final QualifiedNameExpr n, final A arg) {
+		n.setQualifier((NameExpr) n.getQualifier().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ReferenceType n, final A arg) {
+		n.setType((Type) n.getType().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ReturnStmt n, final A arg) {
+		if (n.getExpr() != null) {
+			n.setExpr((Expression) n.getExpr().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final SingleMemberAnnotationExpr n, final A arg) {
+		n.setName((NameExpr) n.getName().accept(this, arg));
+		n.setMemberValue((Expression) n.getMemberValue().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final StringLiteralExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final SuperExpr n, final A arg) {
+		if (n.getClassExpr() != null) {
+			n.setClassExpr((Expression) n.getClassExpr().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final SwitchEntryStmt n, final A arg) {
+		if (n.getLabel() != null) {
+			n.setLabel((Expression) n.getLabel().accept(this, arg));
+		}
+		final List<Statement> stmts = n.getStmts();
+		if (stmts != null) {
+			for (int i = 0; i < stmts.size(); i++) {
+				stmts.set(i, (Statement) stmts.get(i).accept(this, arg));
+			}
+			removeNulls(stmts);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final SwitchStmt n, final A arg) {
+		n.setSelector((Expression) n.getSelector().accept(this, arg));
+		final List<SwitchEntryStmt> entries = n.getEntries();
+		if (entries != null) {
+			for (int i = 0; i < entries.size(); i++) {
+				entries.set(i, (SwitchEntryStmt) entries.get(i).accept(this, arg));
+			}
+			removeNulls(entries);
+		}
+		return n;
+
+	}
+
+	@Override public Node visit(final SynchronizedStmt n, final A arg) {
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		n.setBlock((BlockStmt) n.getBlock().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final ThisExpr n, final A arg) {
+		if (n.getClassExpr() != null) {
+			n.setClassExpr((Expression) n.getClassExpr().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final ThrowStmt n, final A arg) {
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final TryStmt n, final A arg) {
+		n.setTryBlock((BlockStmt) n.getTryBlock().accept(this, arg));
+		final List<CatchClause> catchs = n.getCatchs();
+		if (catchs != null) {
+			for (int i = 0; i < catchs.size(); i++) {
+				catchs.set(i, (CatchClause) catchs.get(i).accept(this, arg));
+			}
+			removeNulls(catchs);
+		}
+		if (n.getFinallyBlock() != null) {
+			n.setFinallyBlock((BlockStmt) n.getFinallyBlock().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final TypeDeclarationStmt n, final A arg) {
+		n.setTypeDeclaration((TypeDeclaration) n.getTypeDeclaration().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final TypeParameter n, final A arg) {
+		final List<ClassOrInterfaceType> typeBound = n.getTypeBound();
+		if (typeBound != null) {
+			for (int i = 0; i < typeBound.size(); i++) {
+				typeBound.set(i, (ClassOrInterfaceType) typeBound.get(i).accept(this, arg));
+			}
+			removeNulls(typeBound);
+		}
+		return n;
+	}
+
+	@Override public Node visit(final UnaryExpr n, final A arg) {
+		n.setExpr((Expression) n.getExpr().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final UnknownType n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final VariableDeclarationExpr n, final A arg) {
+		final List<AnnotationExpr> annotations = n.getAnnotations();
+		if (annotations != null) {
+			for (int i = 0; i < annotations.size(); i++) {
+				annotations.set(i, (AnnotationExpr) annotations.get(i).accept(this, arg));
+			}
+			removeNulls(annotations);
+		}
+		n.setType((Type) n.getType().accept(this, arg));
+		final List<VariableDeclarator> vars = n.getVars();
+		for (int i = 0; i < vars.size(); i++) {
+			vars.set(i, (VariableDeclarator) vars.get(i).accept(this, arg));
+		}
+		removeNulls(vars);
+		return n;
+	}
+
+	@Override public Node visit(final VariableDeclarator n, final A arg) {
+		n.setId((VariableDeclaratorId) n.getId().accept(this, arg));
+		if (n.getInit() != null) {
+			n.setInit((Expression) n.getInit().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final VariableDeclaratorId n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final VoidType n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final WhileStmt n, final A arg) {
+		n.setCondition((Expression) n.getCondition().accept(this, arg));
+		n.setBody((Statement) n.getBody().accept(this, arg));
+		return n;
+	}
+
+	@Override public Node visit(final WildcardType n, final A arg) {
+		if (n.getExtends() != null) {
+			n.setExtends((ReferenceType) n.getExtends().accept(this, arg));
+		}
+		if (n.getSuper() != null) {
+			n.setSuper((ReferenceType) n.getSuper().accept(this, arg));
+		}
+		return n;
+	}
+
+	@Override public Node visit(final LambdaExpr n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final MethodReferenceExpr n, final A arg){
+		return n;
+	}
+
+	@Override public Node visit(final TypeExpr n, final A arg){
+		return n;
+	}
+
+	@Override public Node visit(final BlockComment n, final A arg) {
+		return n;
+	}
+
+	@Override public Node visit(final LineComment n, final A arg) {
+		return n;
+	}
+
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/VoidVisitor.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/VoidVisitor.java
new file mode 100644
index 0000000..b85bd55
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/VoidVisitor.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+/**
+ * A visitor that does not return anything.
+ * 
+ * @author Julio Vilmar Gesser
+ */
+public interface VoidVisitor<A> {
+
+	//- Compilation Unit ----------------------------------
+
+	void visit(CompilationUnit n, A arg);
+
+	void visit(PackageDeclaration n, A arg);
+
+	void visit(ImportDeclaration n, A arg);
+
+	void visit(TypeParameter n, A arg);
+
+	void visit(LineComment n, A arg);
+
+	void visit(BlockComment n, A arg);
+
+	//- Body ----------------------------------------------
+
+	void visit(ClassOrInterfaceDeclaration n, A arg);
+
+	void visit(EnumDeclaration n, A arg);
+
+	void visit(EmptyTypeDeclaration n, A arg);
+
+	void visit(EnumConstantDeclaration n, A arg);
+
+	void visit(AnnotationDeclaration n, A arg);
+
+	void visit(AnnotationMemberDeclaration n, A arg);
+
+	void visit(FieldDeclaration n, A arg);
+
+	void visit(VariableDeclarator n, A arg);
+
+	void visit(VariableDeclaratorId n, A arg);
+
+	void visit(ConstructorDeclaration n, A arg);
+
+	void visit(MethodDeclaration n, A arg);
+
+	void visit(Parameter n, A arg);
+	
+	void visit(MultiTypeParameter n, A arg);
+
+	void visit(EmptyMemberDeclaration n, A arg);
+
+	void visit(InitializerDeclaration n, A arg);
+
+	void visit(JavadocComment n, A arg);
+
+	//- Type ----------------------------------------------
+
+	void visit(ClassOrInterfaceType n, A arg);
+
+	void visit(PrimitiveType n, A arg);
+
+	void visit(ReferenceType n, A arg);
+
+	void visit(VoidType n, A arg);
+
+	void visit(WildcardType n, A arg);
+
+	void visit(UnknownType n, A arg);
+
+	//- Expression ----------------------------------------
+
+	void visit(ArrayAccessExpr n, A arg);
+
+	void visit(ArrayCreationExpr n, A arg);
+
+	void visit(ArrayInitializerExpr n, A arg);
+
+	void visit(AssignExpr n, A arg);
+
+	void visit(BinaryExpr n, A arg);
+
+	void visit(CastExpr n, A arg);
+
+	void visit(ClassExpr n, A arg);
+
+	void visit(ConditionalExpr n, A arg);
+
+	void visit(EnclosedExpr n, A arg);
+
+	void visit(FieldAccessExpr n, A arg);
+
+	void visit(InstanceOfExpr n, A arg);
+
+	void visit(StringLiteralExpr n, A arg);
+
+	void visit(IntegerLiteralExpr n, A arg);
+
+	void visit(LongLiteralExpr n, A arg);
+
+	void visit(IntegerLiteralMinValueExpr n, A arg);
+
+	void visit(LongLiteralMinValueExpr n, A arg);
+
+	void visit(CharLiteralExpr n, A arg);
+
+	void visit(DoubleLiteralExpr n, A arg);
+
+	void visit(BooleanLiteralExpr n, A arg);
+
+	void visit(NullLiteralExpr n, A arg);
+
+	void visit(MethodCallExpr n, A arg);
+
+	void visit(NameExpr n, A arg);
+
+	void visit(ObjectCreationExpr n, A arg);
+
+	void visit(QualifiedNameExpr n, A arg);
+
+	void visit(ThisExpr n, A arg);
+
+	void visit(SuperExpr n, A arg);
+
+	void visit(UnaryExpr n, A arg);
+
+	void visit(VariableDeclarationExpr n, A arg);
+
+	void visit(MarkerAnnotationExpr n, A arg);
+
+	void visit(SingleMemberAnnotationExpr n, A arg);
+
+	void visit(NormalAnnotationExpr n, A arg);
+
+	void visit(MemberValuePair n, A arg);
+
+	//- Statements ----------------------------------------
+
+	void visit(ExplicitConstructorInvocationStmt n, A arg);
+
+	void visit(TypeDeclarationStmt n, A arg);
+
+	void visit(AssertStmt n, A arg);
+
+	void visit(BlockStmt n, A arg);
+
+	void visit(LabeledStmt n, A arg);
+
+	void visit(EmptyStmt n, A arg);
+
+	void visit(ExpressionStmt n, A arg);
+
+	void visit(SwitchStmt n, A arg);
+
+	void visit(SwitchEntryStmt n, A arg);
+
+	void visit(BreakStmt n, A arg);
+
+	void visit(ReturnStmt n, A arg);
+
+	void visit(IfStmt n, A arg);
+
+	void visit(WhileStmt n, A arg);
+
+	void visit(ContinueStmt n, A arg);
+
+	void visit(DoStmt n, A arg);
+
+	void visit(ForeachStmt n, A arg);
+
+	void visit(ForStmt n, A arg);
+
+	void visit(ThrowStmt n, A arg);
+
+	void visit(SynchronizedStmt n, A arg);
+
+	void visit(TryStmt n, A arg);
+
+	void visit(CatchClause n, A arg);
+
+    void visit(LambdaExpr n, A arg);
+
+    void visit(MethodReferenceExpr n, A arg);
+
+    void visit(TypeExpr n, A arg);
+}
diff --git a/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
new file mode 100644
index 0000000..ddad12f
--- /dev/null
+++ b/javaparser-symbol-solver-testing/src/test/test_sourcecode/javaparser_src/proper_source/com/github/javaparser/ast/visitor/VoidVisitorAdapter.java
@@ -0,0 +1,846 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2015 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ * 
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License 
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+ 
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.TypeParameter;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.EmptyMemberDeclaration;
+import com.github.javaparser.ast.body.EmptyTypeDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.MultiTypeParameter;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.body.VariableDeclaratorId;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.AssertStmt;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.BreakStmt;
+import com.github.javaparser.ast.stmt.CatchClause;
+import com.github.javaparser.ast.stmt.ContinueStmt;
+import com.github.javaparser.ast.stmt.DoStmt;
+import com.github.javaparser.ast.stmt.EmptyStmt;
+import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ForStmt;
+import com.github.javaparser.ast.stmt.ForeachStmt;
+import com.github.javaparser.ast.stmt.IfStmt;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.SwitchEntryStmt;
+import com.github.javaparser.ast.stmt.SwitchStmt;
+import com.github.javaparser.ast.stmt.SynchronizedStmt;
+import com.github.javaparser.ast.stmt.ThrowStmt;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.stmt.TypeDeclarationStmt;
+import com.github.javaparser.ast.stmt.WhileStmt;
+import com.github.javaparser.ast.type.*;
+
+import static com.github.javaparser.ast.internal.Utils.isNullOrEmpty;
+
+/**
+ * @author Julio Vilmar Gesser
+ */
+public abstract class VoidVisitorAdapter<A> implements VoidVisitor<A> {
+
+	@Override public void visit(final AnnotationDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		if (n.getMembers() != null) {
+			for (final BodyDeclaration member : n.getMembers()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final AnnotationMemberDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		n.getType().accept(this, arg);
+		if (n.getDefaultValue() != null) {
+			n.getDefaultValue().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ArrayAccessExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		n.getIndex().accept(this, arg);
+	}
+
+	@Override public void visit(final ArrayCreationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+		if (!isNullOrEmpty(n.getDimensions())) {
+			for (final Expression dim : n.getDimensions()) {
+				dim.accept(this, arg);
+			}
+		} else {
+			n.getInitializer().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ArrayInitializerExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getValues() != null) {
+			for (final Expression expr : n.getValues()) {
+				expr.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final AssertStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCheck().accept(this, arg);
+		if (n.getMessage() != null) {
+			n.getMessage().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final AssignExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getTarget().accept(this, arg);
+		n.getValue().accept(this, arg);
+	}
+
+	@Override public void visit(final BinaryExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getLeft().accept(this, arg);
+		n.getRight().accept(this, arg);
+	}
+
+	@Override public void visit(final BlockComment n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final BlockStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final BooleanLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final BreakStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final CastExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final CatchClause n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExcept().accept(this, arg);
+		n.getCatchBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final CharLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final ClassExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+	}
+
+	@Override public void visit(final ClassOrInterfaceDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				t.accept(this, arg);
+			}
+		}
+		if (n.getExtends() != null) {
+			for (final ClassOrInterfaceType c : n.getExtends()) {
+				c.accept(this, arg);
+			}
+		}
+
+		if (n.getImplements() != null) {
+			for (final ClassOrInterfaceType c : n.getImplements()) {
+				c.accept(this, arg);
+			}
+		}
+		if (n.getMembers() != null) {
+			for (final BodyDeclaration member : n.getMembers()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final ClassOrInterfaceType n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				t.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final CompilationUnit n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getPackage() != null) {
+			n.getPackage().accept(this, arg);
+		}
+		if (n.getImports() != null) {
+			for (final ImportDeclaration i : n.getImports()) {
+				i.accept(this, arg);
+			}
+		}
+		if (n.getTypes() != null) {
+			for (final TypeDeclaration typeDeclaration : n.getTypes()) {
+				typeDeclaration.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final ConditionalExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		n.getThenExpr().accept(this, arg);
+		n.getElseExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final ConstructorDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				t.accept(this, arg);
+			}
+		}
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				p.accept(this, arg);
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final NameExpr name : n.getThrows()) {
+				name.accept(this, arg);
+			}
+		}
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final ContinueStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final DoStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getBody().accept(this, arg);
+		n.getCondition().accept(this, arg);
+	}
+
+	@Override public void visit(final DoubleLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final EmptyMemberDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final EmptyStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final EmptyTypeDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final EnclosedExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getInner().accept(this, arg);
+	}
+
+	@Override public void visit(final EnumConstantDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getClassBody() != null) {
+			for (final BodyDeclaration member : n.getClassBody()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final EnumDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		if (n.getImplements() != null) {
+			for (final ClassOrInterfaceType c : n.getImplements()) {
+				c.accept(this, arg);
+			}
+		}
+		if (n.getEntries() != null) {
+			for (final EnumConstantDeclaration e : n.getEntries()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getMembers() != null) {
+			for (final BodyDeclaration member : n.getMembers()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final ExplicitConstructorInvocationStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (!n.isThis()) {
+			if (n.getExpr() != null) {
+				n.getExpr().accept(this, arg);
+			}
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				t.accept(this, arg);
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final ExpressionStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpression().accept(this, arg);
+	}
+
+	@Override public void visit(final FieldAccessExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getScope().accept(this, arg);
+	}
+
+	@Override public void visit(final FieldDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		n.getType().accept(this, arg);
+		for (final VariableDeclarator var : n.getVariables()) {
+			var.accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ForeachStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getVariable().accept(this, arg);
+		n.getIterable().accept(this, arg);
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final ForStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getInit() != null) {
+			for (final Expression e : n.getInit()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getCompare() != null) {
+			n.getCompare().accept(this, arg);
+		}
+		if (n.getUpdate() != null) {
+			for (final Expression e : n.getUpdate()) {
+				e.accept(this, arg);
+			}
+		}
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final IfStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		n.getThenStmt().accept(this, arg);
+		if (n.getElseStmt() != null) {
+			n.getElseStmt().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ImportDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+	}
+
+	@Override public void visit(final InitializerDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final InstanceOfExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+		n.getType().accept(this, arg);
+	}
+
+	@Override public void visit(final IntegerLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final IntegerLiteralMinValueExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final JavadocComment n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final LabeledStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getStmt().accept(this, arg);
+	}
+
+	@Override public void visit(final LineComment n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final LongLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final LongLiteralMinValueExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final MarkerAnnotationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+	}
+
+	@Override public void visit(final MemberValuePair n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getValue().accept(this, arg);
+	}
+
+	@Override public void visit(final MethodCallExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				t.accept(this, arg);
+			}
+		}
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final MethodDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getJavaDoc() != null) {
+			n.getJavaDoc().accept(this, arg);
+		}
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		if (n.getTypeParameters() != null) {
+			for (final TypeParameter t : n.getTypeParameters()) {
+				t.accept(this, arg);
+			}
+		}
+		n.getType().accept(this, arg);
+		if (n.getParameters() != null) {
+			for (final Parameter p : n.getParameters()) {
+				p.accept(this, arg);
+			}
+		}
+		if (n.getThrows() != null) {
+			for (final NameExpr name : n.getThrows()) {
+				name.accept(this, arg);
+			}
+		}
+		if (n.getBody() != null) {
+			n.getBody().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final NameExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final NormalAnnotationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		if (n.getPairs() != null) {
+			for (final MemberValuePair m : n.getPairs()) {
+				m.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final NullLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final ObjectCreationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getScope() != null) {
+			n.getScope().accept(this, arg);
+		}
+		if (n.getTypeArgs() != null) {
+			for (final Type t : n.getTypeArgs()) {
+				t.accept(this, arg);
+			}
+		}
+		n.getType().accept(this, arg);
+		if (n.getArgs() != null) {
+			for (final Expression e : n.getArgs()) {
+				e.accept(this, arg);
+			}
+		}
+		if (n.getAnonymousClassBody() != null) {
+			for (final BodyDeclaration member : n.getAnonymousClassBody()) {
+				member.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final PackageDeclaration n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		n.getName().accept(this, arg);
+	}
+
+	@Override public void visit(final Parameter n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		n.getType().accept(this, arg);
+		n.getId().accept(this, arg);
+	}
+	
+	@Override public void visit(final MultiTypeParameter n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		for (final Type type : n.getTypes()) {
+			type.accept(this, arg);
+		}
+		n.getId().accept(this, arg);
+	}
+
+	@Override public void visit(final PrimitiveType n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final QualifiedNameExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getQualifier().accept(this, arg);
+	}
+
+	@Override public void visit(final ReferenceType n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getType().accept(this, arg);
+	}
+
+	@Override public void visit(final ReturnStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getExpr() != null) {
+			n.getExpr().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final SingleMemberAnnotationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getName().accept(this, arg);
+		n.getMemberValue().accept(this, arg);
+	}
+
+	@Override public void visit(final StringLiteralExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final SuperExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final SwitchEntryStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getLabel() != null) {
+			n.getLabel().accept(this, arg);
+		}
+		if (n.getStmts() != null) {
+			for (final Statement s : n.getStmts()) {
+				s.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final SwitchStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getSelector().accept(this, arg);
+		if (n.getEntries() != null) {
+			for (final SwitchEntryStmt e : n.getEntries()) {
+				e.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final SynchronizedStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+		n.getBlock().accept(this, arg);
+	}
+
+	@Override public void visit(final ThisExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getClassExpr() != null) {
+			n.getClassExpr().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final ThrowStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final TryStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getResources() != null) {
+			for (final VariableDeclarationExpr v : n.getResources()) {
+				v.accept(this, arg);
+			}
+		}
+		n.getTryBlock().accept(this, arg);
+		if (n.getCatchs() != null) {
+			for (final CatchClause c : n.getCatchs()) {
+				c.accept(this, arg);
+			}
+		}
+		if (n.getFinallyBlock() != null) {
+			n.getFinallyBlock().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final TypeDeclarationStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getTypeDeclaration().accept(this, arg);
+	}
+
+	@Override public void visit(final TypeParameter n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getTypeBound() != null) {
+			for (final ClassOrInterfaceType c : n.getTypeBound()) {
+				c.accept(this, arg);
+			}
+		}
+	}
+
+	@Override public void visit(final UnaryExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getExpr().accept(this, arg);
+	}
+
+	@Override public void visit(final UnknownType n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final VariableDeclarationExpr n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getAnnotations() != null) {
+			for (final AnnotationExpr a : n.getAnnotations()) {
+				a.accept(this, arg);
+			}
+		}
+		n.getType().accept(this, arg);
+		for (final VariableDeclarator v : n.getVars()) {
+			v.accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final VariableDeclarator n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getId().accept(this, arg);
+		if (n.getInit() != null) {
+			n.getInit().accept(this, arg);
+		}
+	}
+
+	@Override public void visit(final VariableDeclaratorId n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final VoidType n, final A arg) {
+		visitComment(n.getComment(), arg);
+	}
+
+	@Override public void visit(final WhileStmt n, final A arg) {
+		visitComment(n.getComment(), arg);
+		n.getCondition().accept(this, arg);
+		n.getBody().accept(this, arg);
+	}
+
+	@Override public void visit(final WildcardType n, final A arg) {
+		visitComment(n.getComment(), arg);
+		if (n.getExtends() != null) {
+			n.getExtends().accept(this, arg);
+		}
+		if (n.getSuper() != null) {
+			n.getSuper().accept(this, arg);
+		}
+	}
+
+    @Override
+    public void visit(LambdaExpr n, final A arg) {
+        if (n.getParameters() != null) {
+            for (final Parameter a : n.getParameters()) {
+                a.accept(this, arg);
+            }
+        }
+        if (n.getBody() != null) {
+            n.getBody().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(MethodReferenceExpr n, final A arg) {
+        if (n.getTypeParameters() != null) {
+            for (final TypeParameter a : n.getTypeParameters()) {
+                a.accept(this, arg);
+            }
+        }
+        if (n.getScope() != null) {
+            n.getScope().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(TypeExpr n, final A arg) {
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+    }
+
+    private void visitComment(final Comment n, final A arg) {
+		if (n != null) {
+			n.accept(this, arg);
+		}
+	}
+}
diff --git a/javaparser-testing/javaparser-testing.iml b/javaparser-testing/javaparser-testing.iml
new file mode 100644
index 0000000..6130e1a
--- /dev/null
+++ b/javaparser-testing/javaparser-testing.iml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="javaparser-core" scope="TEST" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.0.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.jbehave:jbehave-core:4.1.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-integration:1.3" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.commons:commons-collections4:4.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: commons-io:commons-io:2.5" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.apache.commons:commons-lang3:3.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.codehaus.plexus:plexus-utils:3.0.22" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.freemarker:freemarker:2.3.23" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.thoughtworks.paranamer:paranamer:2.8" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.thoughtworks.xstream:xstream:1.4.9" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: xmlpull:xmlpull:1.1.3.1" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: xpp3:xpp3_min:1.1.4c" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.google.code.gson:gson:2.8.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.github.valfirst:jbehave-junit-runner:2.1.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.6.2" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.squareup.okhttp3:okhttp:3.6.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: com.squareup.okio:okio:1.11.0" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/javaparser-testing/pom.xml b/javaparser-testing/pom.xml
new file mode 100644
index 0000000..7a3a458
--- /dev/null
+++ b/javaparser-testing/pom.xml
@@ -0,0 +1,116 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>javaparser-parent</artifactId>
+        <groupId>com.github.javaparser</groupId>
+        <version>3.5.16-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>javaparser-testing</artifactId>
+    <description>The test suite for javaparser-core</description>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
+            <distribution>repo</distribution>
+        </license>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jacoco</groupId>
+                <artifactId>jacoco-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>jacoco-initialize</id>
+                        <goals>
+                            <goal>prepare-agent</goal>
+                        </goals>
+                    </execution>
+                    <execution>
+                        <id>jacoco-site</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>report</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-resources</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <configuration>
+                            <encoding>UTF-8</encoding>
+                            <outputDirectory>${basedir}/target/classes</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>../javaparser-core/target/classes</directory>
+                                    <filtering>false</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-deploy-plugin</artifactId>
+                <configuration>
+                    <!-- no need to release this module -->
+                    <skip>true</skip>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <dependencies>
+        <dependency>
+            <groupId>com.github.javaparser</groupId>
+            <artifactId>javaparser-core</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jbehave</groupId>
+            <artifactId>jbehave-core</artifactId>
+            <version>4.1.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.github.valfirst</groupId>
+            <artifactId>jbehave-junit-runner</artifactId>
+            <version>2.1.0</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>3.6.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>3.6.0</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/CommentsInserterTest.java b/javaparser-testing/src/test/java/com/github/javaparser/CommentsInserterTest.java
new file mode 100644
index 0000000..c44a63f
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/CommentsInserterTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.comments.CommentsCollection;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class CommentsInserterTest {
+    private String makeFilename(String sampleName) {
+        return "com/github/javaparser/issue_samples/" + sampleName + ".java.txt";
+    }
+
+    private ParseResult<CompilationUnit> parseSample(String sampleName) throws IOException {
+        Provider p = Providers.resourceProvider(
+                makeFilename(sampleName));
+        return new JavaParser().parse(ParseStart.COMPILATION_UNIT, p);
+    }
+
+    /**
+     * Issue: "When there is a String constant "\\" compilationUnit ignores all further comments"
+     */
+    @Test
+    public void issue290() throws IOException {
+        ParseResult result = parseSample("Issue290");
+        CommentsCollection cc = (CommentsCollection) result.getCommentsCollection().get();
+        assertEquals(1, cc.getLineComments().size());
+        assertEquals(1, cc.getJavadocComments().size());
+    }
+
+    @Test
+    public void issue624() throws IOException {
+        parseResource(makeFilename("Issue624"));
+        // Should not fail
+    }
+
+    @Test
+    public void issue200EnumConstantsWithCommentsForceVerticalAlignment() {
+        CompilationUnit cu = parse("public enum X {" + EOL +
+                "    /** const1 javadoc */" + EOL +
+                "    BORDER_CONSTANT," + EOL +
+                "    /** const2 javadoc */" + EOL +
+                "    ANOTHER_CONSTANT" + EOL +
+                "}");
+        assertEqualsNoEol("public enum X {\n" +
+                "\n" +
+                "    /**\n" +
+                "     * const1 javadoc\n" +
+                "     */\n" +
+                "    BORDER_CONSTANT,\n" +
+                "    /**\n" +
+                "     * const2 javadoc\n" +
+                "     */\n" +
+                "    ANOTHER_CONSTANT\n" +
+                "}\n", cu.toString());
+    }
+
+    @Test
+    public void issue234LosingCommentsInArrayInitializerExpr() {
+        CompilationUnit cu = parse("@Anno(stuff={" + EOL +
+                "    // Just," + EOL +
+                "    // an," + EOL +
+                "    // example" + EOL +
+                "})" + EOL +
+                "class ABC {" + EOL +
+                "" + EOL +
+                "}");
+
+        assertEqualsNoEol("@Anno(stuff = {// Just,\n" +
+                "// an,\n" +
+                "// example\n" +
+                "})\n" +
+                "class ABC {\n" +
+                "}\n", cu.toString());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/GeneratedJavaParserTokenManagerTest.java b/javaparser-testing/src/test/java/com/github/javaparser/GeneratedJavaParserTokenManagerTest.java
new file mode 100644
index 0000000..fdecede
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/GeneratedJavaParserTokenManagerTest.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class GeneratedJavaParserTokenManagerTest {
+    private String makeFilename(String sampleName) {
+        return "com/github/javaparser/issue_samples/" + sampleName + ".java.txt";
+    }
+
+    @Test
+    public void issue1003() throws IOException {
+        JavaParser.parseResource(makeFilename("issue1003"));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/JavaParserTest.java b/javaparser-testing/src/test/java/com/github/javaparser/JavaParserTest.java
new file mode 100644
index 0000000..7302e95
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/JavaParserTest.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.LambdaExpr;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.IntersectionType;
+import com.github.javaparser.ast.type.Type;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.Range.range;
+import static com.github.javaparser.utils.CodeGenerationUtils.mavenModuleRoot;
+import static com.github.javaparser.utils.TestUtils.assertInstanceOf;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class JavaParserTest {
+
+    @Test
+    public void rangeOfAnnotationMemberDeclarationIsCorrect() {
+        String code = "@interface AD { String foo(); }";
+        CompilationUnit cu = JavaParser.parse(code);
+        AnnotationMemberDeclaration memberDeclaration = cu.getAnnotationDeclarationByName("AD").get().getMember(0).asAnnotationMemberDeclaration();
+        assertEquals(true, memberDeclaration.getRange().isPresent());
+        assertEquals(new Range(new Position(1, 17), new Position(1, 29)), memberDeclaration.getRange().get());
+    }
+
+    @Test
+    public void rangeOfAnnotationMemberDeclarationWithArrayTypeIsCorrect() {
+        String code = "@interface AD { String[] foo(); }";
+        CompilationUnit cu = JavaParser.parse(code);
+        AnnotationMemberDeclaration memberDeclaration = cu.getAnnotationDeclarationByName("AD").get().getMember(0).asAnnotationMemberDeclaration();
+        assertEquals(true, memberDeclaration.getRange().isPresent());
+        assertEquals(new Range(new Position(1, 17), new Position(1, 31)), memberDeclaration.getRange().get());
+    }
+
+    @Test
+    public void rangeOfArrayCreationLevelWithExpressionIsCorrect() {
+        String code = "new int[123][456]";
+        ArrayCreationExpr expression = JavaParser.parseExpression(code);
+        Optional<Range> range;
+
+        range = expression.getLevels().get(0).getRange();
+        assertEquals(true, range.isPresent());
+        assertEquals(new Range(new Position(1, 8), new Position(1, 12)), range.get());
+
+        range = expression.getLevels().get(1).getRange();
+        assertEquals(true, range.isPresent());
+        assertEquals(new Range(new Position(1, 13), new Position(1, 17)), range.get());
+    }
+
+    @Test
+    public void rangeOfArrayCreationLevelWithoutExpressionIsCorrect() {
+        String code = "new int[][]";
+        ArrayCreationExpr expression = JavaParser.parseExpression(code);
+        Optional<Range> range;
+
+        range = expression.getLevels().get(0).getRange();
+        assertEquals(true, range.isPresent());
+        assertEquals(new Range(new Position(1, 8), new Position(1, 9)), range.get());
+
+        range = expression.getLevels().get(1).getRange();
+        assertEquals(true, range.isPresent());
+        assertEquals(new Range(new Position(1, 10), new Position(1, 11)), range.get());
+    }
+
+    @Test
+    public void parseErrorContainsLocation() {
+        ParseResult<CompilationUnit> result = new JavaParser().parse(COMPILATION_UNIT, provider("class X { // blah"));
+
+        Problem problem = result.getProblem(0);
+        assertEquals(range(1, 9, 1, 17), problem.getLocation().get().toRange().get());
+        assertEquals("Parse error. Found <EOF>, expected one of  \";\" \"<\" \"@\" \"abstract\" \"boolean\" \"byte\" \"char\" \"class\" \"default\" \"double\" \"enum\" \"exports\" \"final\" \"float\" \"int\" \"interface\" \"long\" \"module\" \"native\" \"open\" \"opens\" \"private\" \"protected\" \"provides\" \"public\" \"requires\" \"short\" \"static\" \"strictfp\" \"synchronized\" \"to\" \"transient\" \"transitive\" \"uses\" \"void\" \"volatile\" \"with\" \"{\" \"}\" <IDENTIFIER>", problem.getMessage());
+        assertInstanceOf(ParseException.class, problem.getCause().get());
+    }
+
+    @Test
+    public void parseIntersectionType() {
+        String code = "(Runnable & Serializable) (() -> {})";
+        Expression expression = JavaParser.parseExpression(code);
+        Type type = expression.asCastExpr().getType();
+
+        assertTrue(type instanceof IntersectionType);
+        IntersectionType intersectionType = type.asIntersectionType();
+        assertEquals(2, intersectionType.getElements().size());
+        assertTrue(intersectionType.getElements().get(0) instanceof ClassOrInterfaceType);
+        assertEquals("Runnable", intersectionType.getElements().get(0).asClassOrInterfaceType().getNameAsString());
+        assertTrue(intersectionType.getElements().get(1) instanceof ClassOrInterfaceType);
+        assertEquals("Serializable", intersectionType.getElements().get(1).asClassOrInterfaceType().getNameAsString());
+    }
+
+    @Test
+    public void rangeOfIntersectionType() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt();
+        CastExpr castExpr = returnStmt.getExpression().get().asCastExpr();
+        Type type = castExpr.getType();
+        assertEquals(range(3, 13, 3, 54), type.getRange().get());
+    }
+
+    @Test
+    public void rangeOfCast() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt();
+        CastExpr castExpr = returnStmt.getExpression().get().asCastExpr();
+        assertEquals(range(3, 12, 3, 101), castExpr.getRange().get());
+    }
+
+    @Test
+    public void rangeOfCastNonIntersection() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>>               )(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt();
+        CastExpr castExpr = returnStmt.getExpression().get().asCastExpr();
+        assertEquals(range(3, 12, 3, 101), castExpr.getRange().get());
+    }
+
+    @Test
+    public void rangeOfLambda() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt();
+        CastExpr castExpr = returnStmt.getExpression().get().asCastExpr();
+        LambdaExpr lambdaExpr = castExpr.getExpression().asLambdaExpr();
+        assertEquals(range(3, 56, 3, 101), lambdaExpr.getRange().get());
+        assertEquals(GeneratedJavaParserConstants.LPAREN, lambdaExpr.getTokenRange().get().getBegin().getKind());
+        assertEquals(GeneratedJavaParserConstants.RPAREN, lambdaExpr.getTokenRange().get().getEnd().getKind());
+    }
+
+    @Test
+    public void rangeOfLambdaBody() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodDeclaration methodDeclaration = cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        ReturnStmt returnStmt = methodDeclaration.getBody().get().getStatement(0).asReturnStmt();
+        CastExpr castExpr = returnStmt.getExpression().get().asCastExpr();
+        LambdaExpr lambdaExpr = castExpr.getExpression().asLambdaExpr();
+        Statement lambdaBody = lambdaExpr.getBody();
+        assertEquals(range(3, 68, 3, 101), lambdaBody.getRange().get());
+    }
+
+    @Test
+    public void testNotStoringTokens() {
+        JavaParser javaParser = new JavaParser(new ParserConfiguration().setStoreTokens(false));
+        ParseResult<CompilationUnit> result = javaParser.parse(ParseStart.COMPILATION_UNIT, provider("class X{}"));
+        assertEquals(false, result.getTokens().isPresent());
+    }
+
+    @Test(expected = ParseProblemException.class)
+    public void trailingCodeIsAnError() {
+        JavaParser.parseBlock("{} efijqoifjqefj");
+    }
+
+    @Test
+    public void trailingWhitespaceIsIgnored() {
+        BlockStmt blockStmt = JavaParser.parseBlock("{} // hello");
+        assertEquals("{}", blockStmt.getTokenRange().get().toString());
+    }
+
+    @Test
+    public void everyTokenHasACategory() throws IOException {
+        final int tokenCount = GeneratedJavaParserConstants.tokenImage.length;
+        Path tokenTypesPath = mavenModuleRoot(JavaParserTest.class).resolve("../javaparser-core/src/main/java/com/github/javaparser/TokenTypes.java");
+        CompilationUnit tokenTypesCu = JavaParser.parse(tokenTypesPath);
+        // -1 to take off the default: case.
+        int switchEntries = tokenTypesCu.findAll(SwitchEntryStmt.class).size()-1;
+        // The amount of "case XXX:" in TokenTypes.java should be equal to the amount of tokens JavaCC knows about:
+        assertEquals(tokenCount, switchEntries);
+    }
+
+    @Test
+    public void parsingInitializedAndUnitializedVarsInForStmt() {
+        ForStmt forStmt = JavaParser.parseStatement("for(int a,b=0;;){}").asForStmt();
+        assertEquals(1, forStmt.getInitialization().size());
+        assertEquals(true, forStmt.getInitialization().get(0).isVariableDeclarationExpr());
+        assertEquals(2, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().size());
+        assertEquals("a", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getNameAsString());
+        assertEquals("b", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getNameAsString());
+        assertEquals(false, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getInitializer().isPresent());
+        assertEquals(true, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getInitializer().isPresent());
+    }
+
+    @Test
+    public void parsingInitializedAndUnitializedVarsInForStmtComplexCase() {
+        // See issue 1281
+        ForStmt forStmt = JavaParser.parseStatement("for(int i, j = array2.length - 1;;){}").asForStmt();
+        assertEquals(1, forStmt.getInitialization().size());
+        assertEquals(true, forStmt.getInitialization().get(0).isVariableDeclarationExpr());
+        assertEquals(2, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().size());
+        assertEquals("i", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getNameAsString());
+        assertEquals("j", forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getNameAsString());
+        assertEquals(false, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(0).getInitializer().isPresent());
+        assertEquals(true, forStmt.getInitialization().get(0).asVariableDeclarationExpr().getVariables().get(1).getInitializer().isPresent());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/JavaTokenTest.java b/javaparser-testing/src/test/java/com/github/javaparser/JavaTokenTest.java
new file mode 100644
index 0000000..e69a76a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/JavaTokenTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.expr.Expression;
+import org.junit.Test;
+
+import java.util.Iterator;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.*;
+import static com.github.javaparser.JavaToken.Category.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.Range.range;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class JavaTokenTest {
+
+    @Test
+    public void testAFewTokens() {
+        ParseResult<Expression> result = new JavaParser().parse(ParseStart.EXPRESSION, provider("1 +/*2*/1 "));
+        Iterator<JavaToken> iterator = result.getResult().get().getTokenRange().get().iterator();
+        assertToken("1", range(1, 1, 1, 1), INTEGER_LITERAL, LITERAL, iterator.next());
+        assertToken(" ", range(1, 2, 1, 2), SPACE, WHITESPACE_NO_EOL, iterator.next());
+        assertToken("+", range(1, 3, 1, 3), PLUS, OPERATOR, iterator.next());
+        assertToken("/*2*/", range(1, 4, 1, 8), MULTI_LINE_COMMENT, COMMENT, iterator.next());
+        assertToken("1", range(1, 9, 1, 9), INTEGER_LITERAL, LITERAL, iterator.next());
+        assertToken(" ", range(1, 10, 1, 10), SPACE, WHITESPACE_NO_EOL, iterator.next());
+        assertToken("", range(1, 10, 1, 10), EOF, WHITESPACE_NO_EOL, iterator.next());
+        assertEquals(false, iterator.hasNext());
+    }
+
+    private void assertToken(String image, Range range, int kind, JavaToken.Category category, JavaToken token) {
+        assertEquals(image, token.getText());
+        assertEquals(range, token.getRange().get());
+        assertEquals(kind, token.getKind());
+        assertEquals(category, token.getCategory());
+        token.getNextToken().ifPresent(nt -> assertEquals(token, nt.getPreviousToken().get()));
+        token.getPreviousToken().ifPresent(pt -> assertEquals(token, pt.getNextToken().get()));
+        assertTrue(token.getNextToken().isPresent() || token.getPreviousToken().isPresent());
+    }
+
+    @Test
+    public void testAFewImagesForTokenKinds() {
+        assertEquals("=", new JavaToken(ASSIGN).getText());
+        // TODO this shouldn't be a space.
+        assertEquals(" ", new JavaToken(EOF).getText());
+        assertEquals("*/", new JavaToken(JAVADOC_COMMENT).getText());
+    }
+
+    @Test
+    public void testKindEnum() {
+        JavaToken.Kind kind = JavaToken.Kind.valueOf(GeneratedJavaParserConstants.ASSERT);
+
+        assertEquals(JavaToken.Kind.ASSERT, kind);
+        assertEquals(GeneratedJavaParserConstants.ASSERT, kind.getKind());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/JavadocParserTest.java b/javaparser-testing/src/test/java/com/github/javaparser/JavadocParserTest.java
new file mode 100644
index 0000000..99e138e
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/JavadocParserTest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.javadoc.Javadoc;
+import com.github.javaparser.javadoc.JavadocBlockTag;
+import com.github.javaparser.javadoc.description.JavadocDescription;
+import org.junit.Assert;
+import org.junit.Test;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class JavadocParserTest {
+
+    @Test
+    public void parseSimplestContent() {
+        Assert.assertEquals(new Javadoc(JavadocDescription.parseText("A simple line of text")),
+                JavadocParser.parse("A simple line of text"));
+    }
+
+    @Test
+    public void parseSingleLineWithSpacing() {
+        assertEquals(new Javadoc(JavadocDescription.parseText("The line number of the first character of this Token.")),
+                JavadocParser.parse(" The line number of the first character of this Token. "));
+    }
+
+    @Test
+    public void parseSingleLineWithNewLines() {
+        assertEquals(new Javadoc(JavadocDescription.parseText("The string image of the token.")),
+                JavadocParser.parse(EOL +
+                        "   * The string image of the token." + EOL +
+                        "   "));
+    }
+
+    @Test
+    public void parseCommentWithNewLines() {
+        String text = EOL +
+                "   * The version identifier for this Serializable class." + EOL +
+                "   * Increment only if the <i>serialized</i> form of the" + EOL +
+                "   * class changes." + EOL +
+                "   ";
+        assertEquals(new Javadoc(JavadocDescription.parseText("The version identifier for this Serializable class." + EOL +
+                        "Increment only if the <i>serialized</i> form of the" + EOL +
+                        "class changes.")),
+                JavadocParser.parse(text));
+    }
+
+    @Test
+    public void parseCommentWithIndentation() {
+        String text = "Returns a new Token object, by default." + EOL +
+                "   * However, if you want, you can create and return subclass objects based on the value of ofKind." + EOL +
+                "   *" + EOL +
+                "   *    case MyParserConstants.ID : return new IDToken(ofKind, image);" + EOL +
+                "   *" + EOL +
+                "   * to the following switch statement. Then you can cast matchedToken";
+        assertEquals(new Javadoc(JavadocDescription.parseText("Returns a new Token object, by default." + EOL +
+                        "However, if you want, you can create and return subclass objects based on the value of ofKind." + EOL +
+                        EOL +
+                        "   case MyParserConstants.ID : return new IDToken(ofKind, image);" + EOL +
+                        EOL +
+                        "to the following switch statement. Then you can cast matchedToken")),
+                JavadocParser.parse(text));
+    }
+
+    @Test
+    public void parseBlockTagsAndEmptyDescription() {
+        String text = EOL +
+                "   * @deprecated" + EOL +
+                "   * @see #getEndColumn" + EOL +
+                "   ";
+        assertEquals(new Javadoc(JavadocDescription.parseText(""))
+                .addBlockTag(new JavadocBlockTag(JavadocBlockTag.Type.DEPRECATED, ""))
+                .addBlockTag(new JavadocBlockTag(JavadocBlockTag.Type.SEE, "#getEndColumn")), JavadocParser.parse(text));
+    }
+
+    @Test
+    public void parseBlockTagsAndProvideTagName() {
+        String expectedText = EOL +
+                "   * @unofficial" + EOL + " " +
+                "   ";
+
+        Javadoc underTest = new Javadoc(JavadocDescription.parseText(""))
+                .addBlockTag(new JavadocBlockTag("unofficial", ""));
+
+
+        assertEquals(underTest, JavadocParser.parse(expectedText));
+        assertEquals(1, underTest.getBlockTags().size());
+        assertEquals("unofficial", underTest.getBlockTags().get(0).getTagName());
+    }
+
+    @Test
+    public void parseParamBlockTags() {
+        String text = EOL +
+                "     * Add a field to this and automatically add the import of the type if needed" + EOL +
+                "     *" + EOL +
+                "     * @param typeClass the type of the field" + EOL +
+                "     * @param name the name of the field" + EOL +
+                "     * @param modifiers the modifiers like {@link Modifier#PUBLIC}" + EOL +
+                "     * @return the {@link FieldDeclaration} created" + EOL +
+                "     ";
+        Javadoc res = JavadocParser.parse(text);
+        assertEquals(new Javadoc(JavadocDescription.parseText("Add a field to this and automatically add the import of the type if needed"))
+                .addBlockTag(JavadocBlockTag.createParamBlockTag("typeClass", "the type of the field"))
+                .addBlockTag(JavadocBlockTag.createParamBlockTag("name", "the name of the field"))
+                .addBlockTag(JavadocBlockTag.createParamBlockTag("modifiers", "the modifiers like {@link Modifier#PUBLIC}"))
+                .addBlockTag(new JavadocBlockTag(JavadocBlockTag.Type.RETURN, "the {@link FieldDeclaration} created")), res);
+    }
+
+    @Test
+    public void parseMultilineParamBlockTags() {
+        String text = EOL +
+                "     * Add a field to this and automatically add the import of the type if needed" + EOL +
+                "     *" + EOL +
+                "     * @param typeClass the type of the field" + EOL +
+                "     *     continued in a second line" + EOL +
+                "     * @param name the name of the field" + EOL +
+                "     * @param modifiers the modifiers like {@link Modifier#PUBLIC}" + EOL +
+                "     * @return the {@link FieldDeclaration} created" + EOL +
+                "     ";
+        Javadoc res = JavadocParser.parse(text);
+        assertEquals(new Javadoc(JavadocDescription.parseText("Add a field to this and automatically add the import of the type if needed"))
+                .addBlockTag(JavadocBlockTag.createParamBlockTag("typeClass", "the type of the field" + EOL + "    continued in a second line"))
+                .addBlockTag(JavadocBlockTag.createParamBlockTag("name", "the name of the field"))
+                .addBlockTag(JavadocBlockTag.createParamBlockTag("modifiers", "the modifiers like {@link Modifier#PUBLIC}"))
+                .addBlockTag(new JavadocBlockTag(JavadocBlockTag.Type.RETURN, "the {@link FieldDeclaration} created")), res);
+    }
+
+    @Test
+    public void startsWithAsteriskEmpty() {
+        assertEquals(-1, JavadocParser.startsWithAsterisk(""));
+    }
+
+    @Test
+    public void startsWithAsteriskNoAsterisk() {
+        assertEquals(-1, JavadocParser.startsWithAsterisk(" ciao"));
+    }
+
+    @Test
+    public void startsWithAsteriskAtTheBeginning() {
+        assertEquals(0, JavadocParser.startsWithAsterisk("* ciao"));
+    }
+
+    @Test
+    public void startsWithAsteriskAfterSpaces() {
+        assertEquals(3, JavadocParser.startsWithAsterisk("   * ciao"));
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ParseErrorRecoveryTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ParseErrorRecoveryTest.java
new file mode 100644
index 0000000..b41c28b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ParseErrorRecoveryTest.java
@@ -0,0 +1,42 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.LabeledStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.ast.Node.Parsedness.UNPARSABLE;
+import static org.junit.Assert.assertEquals;
+
+public class ParseErrorRecoveryTest {
+    private final JavaParser parser = new JavaParser();
+
+    @Test
+    public void compilationUnitRecovery() {
+        CompilationUnit cu = parser.parse(ParseStart.COMPILATION_UNIT, provider("XXX")).getResult().get();
+        assertEquals(UNPARSABLE, cu.getParsed());
+    }
+
+    @Test
+    public void bodystatementSemicolonRecovery() {
+        MethodDeclaration cu = parser.parse(ParseStart.CLASS_BODY, provider("int x(){X X X;}")).getResult().get().asMethodDeclaration();
+        Statement xxx = cu.getBody().get().getStatements().get(0);
+        assertEquals(UNPARSABLE, xxx.getParsed());
+    }
+
+    @Test
+    public void bodystatementClosingBraceRecovery() {
+        MethodDeclaration cu = parser.parse(ParseStart.CLASS_BODY, provider("int x(){X X X}")).getResult().get().asMethodDeclaration();
+        Statement xxx = cu.getBody().get();
+        assertEquals(UNPARSABLE, xxx.getParsed());
+    }
+
+    @Test
+    public void labeledStatementSemicolonRecovery() {
+        CompilationUnit cu = parser.parse(ParseStart.COMPILATION_UNIT, provider("class X{int x(){aaa:X X X;}}")).getResult().get();
+        LabeledStmt xxx = cu.getClassByName("X").get().getMethods().get(0).getBody().get().getStatements().get(0).asLabeledStmt();
+        assertEquals(UNPARSABLE, xxx.getStatement().getParsed());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ParserConfigurationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ParserConfigurationTest.java
new file mode 100644
index 0000000..abc4009
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ParserConfigurationTest.java
@@ -0,0 +1,33 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ParserConfigurationTest {
+    @Test
+    public void storeNoTokens() {
+        ParseResult<CompilationUnit> result = new JavaParser(new ParserConfiguration().setStoreTokens(false)).parse(ParseStart.COMPILATION_UNIT, provider("class X{}"));
+
+        assertFalse(result.getResult().get().getTokenRange().isPresent());
+        assertTrue(result.getResult().get().findAll(Node.class).stream().noneMatch(node -> node.getTokenRange().isPresent()));
+    }
+
+    @Test
+    public void noProblemsHere() {
+        ParseResult<Statement> result =
+                new JavaParser(new ParserConfiguration().setLanguageLevel(RAW))
+                        .parse(STATEMENT, provider("try{}"));
+        assertEquals(true, result.isSuccessful());
+    }
+
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ProblemTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ProblemTest.java
new file mode 100644
index 0000000..0654344
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ProblemTest.java
@@ -0,0 +1,32 @@
+package com.github.javaparser;
+
+import org.junit.Test;
+
+import static com.github.javaparser.Range.range;
+import static com.github.javaparser.utils.TestUtils.assertInstanceOf;
+import static org.junit.Assert.assertEquals;
+
+public class ProblemTest {
+    @Test
+    public void testSimpleGetters() {
+        Problem problem = new Problem("Parse error", TokenRange.INVALID, new Exception());
+
+        assertEquals(TokenRange.INVALID, problem.getLocation().get());
+        assertEquals("Parse error", problem.getMessage());
+        assertInstanceOf(Exception.class, problem.getCause().get());
+    }
+
+    @Test
+    public void testVerboseMessage() {
+        Problem problem = new Problem("Parse error", TokenRange.INVALID, null);
+
+        assertEquals("(line ?,col ?) Parse error", problem.getVerboseMessage());
+    }
+
+    @Test
+    public void testVerboseMessageWithoutLocation() {
+        Problem problem = new Problem("Parse error", null, null);
+
+        assertEquals("Parse error", problem.getVerboseMessage());
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ProvidersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ProvidersTest.java
new file mode 100644
index 0000000..14b351a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ProvidersTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+import static org.junit.Assert.*;
+
+public class ProvidersTest {
+
+    @Test
+    public void testResourceProvider() throws IOException {
+        Provider provider = Providers.resourceProvider("com/github/javaparser/issue_samples/Issue290.java.txt");
+        assertNotNull(provider);
+        JavaParser parser = new JavaParser();
+        ParseResult<CompilationUnit> parse = parser.parse(ParseStart.COMPILATION_UNIT, provider);
+        assertTrue(parse.isSuccessful());
+    }
+
+    @Test
+    public void testResourceProviderWithWrongEncoding() throws IOException {
+        Provider provider = Providers.resourceProvider("com/github/javaparser/TestFileIso88591.java");
+        assertNotNull(provider);
+        JavaParser parser = new JavaParser();
+        ParseResult<CompilationUnit> parse = parser.parse(ParseStart.COMPILATION_UNIT, provider);
+        assertFalse(parse.isSuccessful());
+    }
+
+    @Test
+    public void testResourceProviderWithEncoding() throws IOException {
+        Provider provider = Providers.resourceProvider(
+                "com/github/javaparser/TestFileIso88591.java",
+                Charset.forName("ISO-8859-1")
+        );
+        assertNotNull(provider);
+        JavaParser parser = new JavaParser();
+        ParseResult<CompilationUnit> parse = parser.parse(ParseStart.COMPILATION_UNIT, provider);
+        assertTrue(parse.isSuccessful());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/RangeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/RangeTest.java
new file mode 100644
index 0000000..1d2b49a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/RangeTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+
+public class RangeTest {
+
+    @Test
+    public void aRangeContainsItself() throws IOException {
+        Range r = Range.range(1, 1, 3, 10);
+        assertEquals(true, r.contains(r));
+    }
+
+    @Test
+    public void aRangeDoesNotStrictlyContainsItself() throws IOException {
+        Range r = Range.range(1, 1, 3, 10);
+        assertEquals(false, r.strictlyContains(r));
+    }
+
+    @Test
+    public void overlappingButNotContainedRangesAreNotOnContains() throws IOException {
+        Range r1 = Range.range(1, 1, 3, 10);
+        Range r2 = Range.range(2, 1, 7, 10);
+        assertEquals(false, r1.contains(r2));
+        assertEquals(false, r2.contains(r1));
+    }
+
+    @Test
+    public void overlappingButNotContainedRangesAreNotOnStrictlyContains() throws IOException {
+        Range r1 = Range.range(1, 1, 3, 10);
+        Range r2 = Range.range(2, 1, 7, 10);
+        assertEquals(false, r1.strictlyContains(r2));
+        assertEquals(false, r2.strictlyContains(r1));
+    }
+
+    @Test
+    public void unrelatedRangesAreNotOnContains() throws IOException {
+        Range r1 = Range.range(1, 1, 3, 10);
+        Range r2 = Range.range(5, 1, 7, 10);
+        assertEquals(false, r1.contains(r2));
+        assertEquals(false, r2.contains(r1));
+    }
+
+    @Test
+    public void unrelatedRangesAreNotOnStrictlyContains() throws IOException {
+        Range r1 = Range.range(1, 1, 3, 10);
+        Range r2 = Range.range(5, 1, 7, 10);
+        assertEquals(false, r1.strictlyContains(r2));
+        assertEquals(false, r2.strictlyContains(r1));
+    }
+
+    @Test
+    public void strictlyContainedRangesOnContains() throws IOException {
+        Range r1 = Range.range(1, 1, 3, 10);
+        Range r2 = Range.range(2, 1, 3, 4);
+        assertEquals(true, r1.contains(r2));
+        assertEquals(false, r2.contains(r1));
+    }
+
+    @Test
+    public void strictlyContainedRangesOnStrictlyContains() throws IOException {
+        Range r1 = Range.range(1, 1, 3, 10);
+        Range r2 = Range.range(2, 1, 3, 4);
+        assertEquals(true, r1.strictlyContains(r2));
+        assertEquals(false, r2.strictlyContains(r1));
+    }
+
+    @Test
+    public void containsConsiderLines() {
+        Range r1 = Range.range(22, 9, 22, 29);
+        Range r2 = Range.range(26, 19, 26, 28);
+        assertEquals(false, r1.contains(r2));
+        assertEquals(false, r2.contains(r1));
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/TokenRangeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/TokenRangeTest.java
new file mode 100644
index 0000000..d067c8e
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/TokenRangeTest.java
@@ -0,0 +1,14 @@
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TokenRangeTest {
+    @Test
+    public void toStringWorks() {
+        CompilationUnit cu = JavaParser.parse("class X {\n\tX(){\n// hello\n}\n}");
+        assertEquals("X(){\n// hello\n}", cu.getClassByName("X").get().getDefaultConstructor().get().getTokenRange().get().toString());
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/CompilationUnitTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/CompilationUnitTest.java
new file mode 100644
index 0000000..ec17e39
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/CompilationUnitTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.JavaParser;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static com.github.javaparser.JavaParser.parse;
+import static com.github.javaparser.utils.CodeGenerationUtils.mavenModuleRoot;
+import static org.junit.Assert.assertEquals;
+
+public class CompilationUnitTest {
+    @Test
+    public void issue578TheFirstCommentIsWithinTheCompilationUnit() {
+        CompilationUnit compilationUnit = parse("// This is my class, with my comment\n" +
+                "class A {\n" +
+                "    static int a;\n" +
+                "}");
+
+        assertEquals(1, compilationUnit.getAllContainedComments().size());
+    }
+
+    @Test
+    public void testGetSourceRoot() throws IOException {
+        Path sourceRoot = mavenModuleRoot(CompilationUnitTest.class).resolve(Paths.get("src", "test", "resources")).normalize();
+        Path testFile = sourceRoot.resolve(Paths.get("com", "github", "javaparser", "storage", "Z.java"));
+
+        CompilationUnit cu = parse(testFile);
+        Path sourceRoot1 = cu.getStorage().get().getSourceRoot();
+        assertEquals(sourceRoot, sourceRoot1);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testGetSourceRootWithBadPackageDeclaration() throws IOException {
+        Path sourceRoot = mavenModuleRoot(CompilationUnitTest.class).resolve(Paths.get("src", "test", "resources")).normalize();
+        Path testFile = sourceRoot.resolve(Paths.get("com", "github", "javaparser", "storage", "A.java"));
+
+        CompilationUnit cu = parse(testFile);
+        cu.getStorage().get().getSourceRoot();
+    }
+
+    @Test
+    public void testGetSourceRootInDefaultPackage() throws IOException {
+        Path sourceRoot = mavenModuleRoot(CompilationUnitTest.class).resolve(Paths.get("src", "test", "resources", "com", "github", "javaparser", "storage")).normalize();
+        Path testFile = sourceRoot.resolve(Paths.get("B.java"));
+
+        CompilationUnit cu = parse(testFile);
+        Path sourceRoot1 = cu.getStorage().get().getSourceRoot();
+        assertEquals(sourceRoot, sourceRoot1);
+    }
+    
+    @Test
+    public void testGetPrimaryTypeName() throws IOException {
+        Path sourceRoot = mavenModuleRoot(CompilationUnitTest.class).resolve(Paths.get("src", "test", "resources")).normalize();
+        Path testFile = sourceRoot.resolve(Paths.get("com", "github", "javaparser", "storage", "PrimaryType.java"));
+        CompilationUnit cu = JavaParser.parse(testFile);
+        
+        assertEquals("PrimaryType", cu.getPrimaryTypeName().get());
+    }
+
+    @Test
+    public void testNoPrimaryTypeName() {
+        CompilationUnit cu = JavaParser.parse("class PrimaryType{}");
+
+        assertEquals(false, cu.getPrimaryTypeName().isPresent());
+    }
+    @Test
+    public void testGetPrimaryType() throws IOException {
+        Path sourceRoot = mavenModuleRoot(CompilationUnitTest.class).resolve(Paths.get("src", "test", "resources")).normalize();
+        Path testFile = sourceRoot.resolve(Paths.get("com", "github", "javaparser", "storage", "PrimaryType.java"));
+        CompilationUnit cu = JavaParser.parse(testFile);
+
+        assertEquals("PrimaryType",     cu.getPrimaryType().get().getNameAsString());
+    }
+
+    @Test
+    public void testNoPrimaryType() throws IOException {
+        Path sourceRoot = mavenModuleRoot(CompilationUnitTest.class).resolve(Paths.get("src", "test", "resources")).normalize();
+        Path testFile = sourceRoot.resolve(Paths.get("com", "github", "javaparser", "storage", "PrimaryType2.java"));
+        CompilationUnit cu = JavaParser.parse(testFile);
+
+        assertEquals(false, cu.getPrimaryType().isPresent());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/DataKeyTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/DataKeyTest.java
new file mode 100644
index 0000000..9116365
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/DataKeyTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.expr.SimpleName;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+
+public class DataKeyTest {
+    public static final DataKey<String> ABC = new DataKey<String>() {
+    };
+    public static final DataKey<List<String>> LISTY = new DataKey<List<String>>() {
+    };
+    public static final DataKey<List<String>> DING = new DataKey<List<String>>() {
+    };
+
+    @Test
+    public void addAFewKeysAndSeeIfTheyAreStoredCorrectly() {
+        Node node = new SimpleName();
+
+        node.setData(ABC, "Hurray!");
+        node.setData(LISTY, Arrays.asList("a", "b"));
+        node.setData(ABC, "w00t");
+
+        assertThat(node.getData(ABC)).contains("w00t");
+        assertThat(node.getData(LISTY)).containsExactly("a", "b");
+        assertThat(node.getData(DING)).isNull();
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeListTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeListTest.java
new file mode 100644
index 0000000..8e4d568
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeListTest.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.observer.AstObserver;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.PrimitiveType;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import static com.github.javaparser.ast.NodeList.nodeList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class NodeListTest {
+
+    private AstObserver createObserver(List<String> changes) {
+        return new AstObserver() {
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add(String.format("change of property %s for %s: from '%s' to '%s'", property, observedNode, oldValue, newValue));
+            }
+
+            @Override
+            public void parentChange(Node observedNode, Node previousParent, Node newParent) {
+                changes.add(String.format("setting parent for %s: was %s, now is %s", observedNode, previousParent, newParent));
+            }
+
+            @Override
+            public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+                changes.add(String.format("'%s' %s in list at %d", nodeAddedOrRemoved, type, index));
+            }
+
+            @Override
+            public void listReplacement(NodeList observedNode, int index, Node oldNode, Node newNode) {
+                changes.add(String.format("'%s' %s in list at %d", oldNode, ListChangeType.REMOVAL, index));
+                changes.add(String.format("'%s' %s in list at %d", newNode, ListChangeType.ADDITION, index));
+            }
+        };
+    }
+
+    private FieldDeclaration createIntField(String name) {
+        return new FieldDeclaration(EnumSet.noneOf(Modifier.class), PrimitiveType.intType(), name);
+    }
+
+    @Test
+    public void addAllWithoutIndex() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { void foo(int p) { }}";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().addAll(Arrays.asList(createIntField("a"), createIntField("b"), createIntField("c")));
+        assertEquals(Arrays.asList("'int a;' ADDITION in list at 1",
+                "'int b;' ADDITION in list at 2",
+                "'int c;' ADDITION in list at 3"), changes);
+    }
+
+    @Test
+    public void addAllWithIndex() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { void foo(int p) { }}";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().addAll(0, Arrays.asList(createIntField("a"), createIntField("b"), createIntField("c")));
+        assertEquals(Arrays.asList("'int a;' ADDITION in list at 0",
+                "'int b;' ADDITION in list at 1",
+                "'int c;' ADDITION in list at 2"), changes);
+    }
+
+    @Test
+    public void clear() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().clear();
+        assertEquals(Arrays.asList("'int a;' REMOVAL in list at 0",
+                "'int b;' REMOVAL in list at 0",
+                "'int c;' REMOVAL in list at 0"), changes);
+    }
+
+    @Test
+    public void set() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().set(1, createIntField("d"));
+        assertEquals(Arrays.asList("'int b;' REMOVAL in list at 1",
+                "'int d;' ADDITION in list at 1"), changes);
+    }
+
+    @Test
+    public void removeNode() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; int d; int e; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().remove(cd.getFieldByName("c").get());
+        assertEquals(Arrays.asList("'int c;' REMOVAL in list at 2"), changes);
+    }
+
+    @Test
+    public void removeFirstNode() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; int d; int e; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().removeFirst();
+        assertEquals(Arrays.asList("'int a;' REMOVAL in list at 0"), changes);
+        assertEquals(cd.getMembers().size(), 4);
+
+        for (int i = 3; i >= 0; i--) {
+            assertTrue(cd.getMembers().removeFirst() != null);
+            assertEquals(cd.getMembers().size(), i);
+        }
+
+        assertEquals(cd.getMembers().size(), 0);
+    }
+
+    @Test
+    public void removeLastNode() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; int d; int e; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().removeLast();
+        assertEquals(Arrays.asList("'int e;' REMOVAL in list at 4"), changes);
+        assertEquals(cd.getMembers().size(), 4);
+
+        for (int i = 3; i >= 0; i--) {
+            assertTrue(cd.getMembers().removeLast() != null);
+            assertEquals(cd.getMembers().size(), i);
+        }
+
+        assertEquals(cd.getMembers().size(), 0);
+    }
+
+    @Test
+    public void removeObject() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; int d; int e; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().remove("hi");
+        assertEquals(Arrays.asList(), changes);
+    }
+
+    @Test
+    public void removeAll() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; int d; int e; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().removeAll(Arrays.asList(cd.getFieldByName("b").get(), "foo", cd.getFieldByName("d").get()));
+        assertEquals(Arrays.asList("'int b;' REMOVAL in list at 1",
+                "'int d;' REMOVAL in list at 2"), changes);
+    }
+
+    @Test
+    public void retainAll() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; int d; int e; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().retainAll(Arrays.asList(cd.getFieldByName("b").get(), "foo", cd.getFieldByName("d").get()));
+        assertEquals(Arrays.asList("'int a;' REMOVAL in list at 0",
+                "'int c;' REMOVAL in list at 1",
+                "'int e;' REMOVAL in list at 2"), changes);
+    }
+
+    @Test
+    public void replaceAll() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int b; int c; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().replaceAll(bodyDeclaration -> {
+            FieldDeclaration clone = (FieldDeclaration) bodyDeclaration.clone();
+            SimpleName id = clone.getVariable(0).getName();
+            id.setIdentifier(id.getIdentifier().toUpperCase());
+            return clone;
+        });
+        assertEquals(Arrays.asList("'int a;' REMOVAL in list at 0", "'int A;' ADDITION in list at 0",
+                "'int b;' REMOVAL in list at 1", "'int B;' ADDITION in list at 1",
+                "'int c;' REMOVAL in list at 2", "'int C;' ADDITION in list at 2"), changes);
+    }
+
+    @Test
+    public void removeIf() {
+        List<String> changes = new LinkedList<>();
+        String code = "class A { int a; int longName; int c; }";
+        CompilationUnit cu = JavaParser.parse(code);
+        ClassOrInterfaceDeclaration cd = cu.getClassByName("A").get();
+        cd.getMembers().register(createObserver(changes));
+
+        cd.getMembers().removeIf(m -> ((FieldDeclaration) m).getVariable(0).getName().getIdentifier().length() > 3);
+        assertEquals(Arrays.asList("'int longName;' REMOVAL in list at 1"), changes);
+    }
+
+    @Test
+    public void replace() {
+        final NodeList<Name> list = nodeList(new Name("a"), new Name("b"), new Name("c"));
+
+        final boolean replaced = list.replace(new Name("b"), new Name("z"));
+
+        assertEquals(true, replaced);
+        assertEquals(3, list.size());
+        assertEquals("a", list.get(0).asString());
+        assertEquals("z", list.get(1).asString());
+        assertEquals("c", list.get(2).asString());
+    }
+
+    @Test
+    public void toStringTest() {
+        final NodeList<Name> list = nodeList(new Name("abc"), new Name("bcd"), new Name("cde"));
+
+        assertEquals("[abc, bcd, cde]", list.toString());
+    }
+
+    @Test
+    public void addFirst() {
+        final NodeList<Name> list = nodeList(new Name("abc"), new Name("bcd"), new Name("cde"));
+
+        list.addFirst(new Name("xxx"));
+
+        assertEquals("[xxx, abc, bcd, cde]", list.toString());
+    }
+
+    @Test
+    public void addLast() {
+        final NodeList<Name> list = nodeList(new Name("abc"), new Name("bcd"), new Name("cde"));
+
+        list.addLast(new Name("xxx"));
+
+        assertEquals("[abc, bcd, cde, xxx]", list.toString());
+    }
+
+    @Test
+    public void addBefore() {
+        Name n = new Name("bcd");
+        final NodeList<Name> list = nodeList(new Name("abc"), n, new Name("cde"));
+
+        list.addBefore(new Name("xxx"), n);
+
+        assertEquals("[abc, xxx, bcd, cde]", list.toString());
+    }
+
+    @Test
+    public void addAfter() {
+        Name n = new Name("bcd");
+        final NodeList<Name> list = nodeList(new Name("abc"), n, new Name("cde"));
+
+        list.addAfter(new Name("xxx"), n);
+
+        assertEquals("[abc, bcd, xxx, cde]", list.toString());
+    }
+
+    @Test
+    public void addBeforeFirst() {
+        Name abc = new Name("abc");
+        final NodeList<Name> list = nodeList(abc, new Name("bcd"), new Name("cde"));
+
+        list.addBefore(new Name("xxx"), abc);
+
+        assertEquals("[xxx, abc, bcd, cde]", list.toString());
+    }
+
+    @Test
+    public void addAfterLast() {
+        Name cde = new Name("cde");
+        final NodeList<Name> list = nodeList(new Name("abc"), new Name("bcd"), cde);
+
+        list.addAfter(new Name("xxx"), cde);
+
+        assertEquals("[abc, bcd, cde, xxx]", list.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/NodePositionTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodePositionTest.java
new file mode 100644
index 0000000..5ce116d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodePositionTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.*;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class NodePositionTest {
+
+    private List<Node> getAllNodes(Node node) {
+        List<Node> nodes = new LinkedList<>();
+        nodes.add(node);
+        node.getChildNodes().forEach(c -> nodes.addAll(getAllNodes(c)));
+        return nodes;
+    }
+
+    @Test
+    public void packageProtectedClassShouldHavePositionSet() throws IOException {
+        ensureAllNodesHaveValidBeginPosition("class A { }");
+    }
+
+    @Test
+    public void packageProtectedInterfaceShouldHavePositionSet() throws IOException {
+        ensureAllNodesHaveValidBeginPosition("interface A { }");
+    }
+
+    @Test
+    public void packageProtectedEnumShouldHavePositionSet() throws IOException {
+        ensureAllNodesHaveValidBeginPosition("enum A { }");
+    }
+
+    @Test
+    public void packageProtectedAnnotationShouldHavePositionSet() throws IOException {
+        ensureAllNodesHaveValidBeginPosition("@interface A { }");
+    }
+
+    @Test
+    public void packageProtectedFieldShouldHavePositionSet() throws IOException {
+        ensureAllNodesHaveValidBeginPosition("public class A { int i; }");
+    }
+
+    @Test
+    public void packageProtectedMethodShouldHavePositionSet() throws IOException {
+      ensureAllNodesHaveValidBeginPosition("public class A { void foo() {} }");
+    }
+
+    @Test
+    public void packageProtectedConstructorShouldHavePositionSet() throws IOException {
+      ensureAllNodesHaveValidBeginPosition("public class A { A() {} }");
+    }
+
+    private void ensureAllNodesHaveValidBeginPosition(final String code) throws IOException {
+        ParseResult<CompilationUnit> res = new JavaParser().parse(ParseStart.COMPILATION_UNIT, Providers.provider(code));
+        assertTrue(res.getProblems().isEmpty());
+
+        CompilationUnit cu = res.getResult().get();
+        getAllNodes(cu).forEach(n -> {
+            assertNotNull(String.format("There should be no node without a range: %s (class: %s)",
+                    n, n.getClass().getCanonicalName()), n.getRange());
+            if (n.getBegin().get().line == 0 && !n.toString().isEmpty()) {
+                throw new IllegalArgumentException("There should be no node at line 0: " + n + " (class: "
+                        + n.getClass().getCanonicalName() + ")");
+            }
+        });
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java
new file mode 100644
index 0000000..3201b29
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.observer.AstObserver;
+import com.github.javaparser.ast.observer.AstObserverAdapter;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.type.PrimitiveType;
+import org.junit.Test;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.JavaParser.parse;
+import static com.github.javaparser.JavaParser.parseExpression;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.*;
+
+public class NodeTest {
+
+    @Test
+    public void registerSubTree() {
+        String code = "class A { int f; void foo(int p) { return 'z'; }}";
+        CompilationUnit cu = parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new AstObserverAdapter() {
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue));
+            }
+        };
+        cu.registerForSubtree(observer);
+
+        assertEquals(Arrays.asList(), changes);
+
+        cu.getClassByName("A").get().setName("MyCoolClass");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN));
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean",
+                "Parameter.name changed from p to myParam"), changes);
+    }
+
+    @Test
+    public void registerWithJustNodeMode() {
+        String code = "class A { int f; void foo(int p) { return 'z'; }}";
+        CompilationUnit cu = parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new AstObserverAdapter() {
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue));
+            }
+        };
+        cu.getClassByName("A").get().register(observer, Node.ObserverRegistrationMode.JUST_THIS_NODE);
+
+        assertEquals(Arrays.asList(), changes);
+
+        cu.getClassByName("A").get().setName("MyCoolClass");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN));
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes);
+
+        cu.getClassByName("MyCoolClass").get().addField("int", "bar").getVariables().get(0).setInitializer("0");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes);
+    }
+
+    @Test
+    public void registerWithNodeAndExistingDescendantsMode() {
+        String code = "class A { int f; void foo(int p) { return 'z'; }}";
+        CompilationUnit cu = parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new AstObserverAdapter() {
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue));
+            }
+        };
+        cu.getClassByName("A").get().register(observer, Node.ObserverRegistrationMode.THIS_NODE_AND_EXISTING_DESCENDANTS);
+
+        assertEquals(Arrays.asList(), changes);
+
+        cu.getClassByName("A").get().setName("MyCoolClass");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN));
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean",
+                "Parameter.name changed from p to myParam"), changes);
+
+        cu.getClassByName("MyCoolClass").get().addField("int", "bar").getVariables().get(0).setInitializer("0");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean",
+                "Parameter.name changed from p to myParam"), changes);
+    }
+
+    @Test
+    public void registerWithSelfPropagatingMode() {
+        String code = "class A { int f; void foo(int p) { return 'z'; }}";
+        CompilationUnit cu = parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new AstObserverAdapter() {
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue));
+            }
+        };
+        cu.getClassByName("A").get().register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING);
+
+        assertEquals(Arrays.asList(), changes);
+
+        cu.getClassByName("A").get().setName("MyCoolClass");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN));
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean"), changes);
+
+        cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean",
+                "Parameter.name changed from p to myParam"), changes);
+
+        cu.getClassByName("MyCoolClass").get()
+                .addField("int", "bar")
+                .getVariables().get(0).setInitializer("0");
+        assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass",
+                "FieldDeclaration.maximum_common_type changed from int to boolean",
+                "VariableDeclarator.type changed from int to boolean",
+                "Parameter.name changed from p to myParam",
+                "VariableDeclarator.initializer changed from null to 0"), changes);
+    }
+
+    @Test
+    public void deleteAParameterTriggerNotifications() {
+        String code = "class A { void foo(int p) { }}";
+        CompilationUnit cu = parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new AstObserverAdapter() {
+
+            @Override
+            public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+                changes.add("removing [" + nodeAddedOrRemoved + "] from index " + index);
+            }
+        };
+        cu.register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING);
+
+        cu.getClassByName("A").get().getMethodsByName("foo").get(0).getParameter(0).remove();
+        assertEquals(Arrays.asList("removing [int p] from index 0"), changes);
+    }
+
+    @Test
+    public void deleteClassNameDoesNotTriggerNotifications() {
+        String code = "class A { void foo(int p) { }}";
+        CompilationUnit cu = parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new AstObserverAdapter() {
+
+            @Override
+            public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+                changes.add("removing [" + nodeAddedOrRemoved + "] from index " + index);
+            }
+        };
+        cu.register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING);
+
+        // I cannot remove the name of a type
+        assertEquals(false, cu.getClassByName("A").get().getName().remove());
+        assertEquals(Arrays.asList(), changes);
+    }
+
+    @Test
+    public void deleteMethodBodyDoesTriggerNotifications() {
+        String code = "class A { void foo(int p) { }}";
+        CompilationUnit cu = parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new AstObserverAdapter() {
+
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add("setting [" + property + "] to " + newValue);
+            }
+
+            @Override
+            public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) {
+                changes.add("removing [" + nodeAddedOrRemoved + "] from index " + index);
+            }
+        };
+        cu.register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING);
+
+        assertEquals(true, cu.getClassByName("A").get().getMethodsByName("foo").get(0).getBody().get().remove());
+        assertEquals(Arrays.asList("setting [BODY] to null"), changes);
+    }
+
+    @Test
+    public void removeOrphanCommentPositiveCase() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), false, "A");
+        Comment c = new LineComment("A comment");
+        decl.addOrphanComment(c);
+        assertEquals(1, decl.getOrphanComments().size());
+        assertTrue(decl == c.getParentNode().get());
+        assertTrue(decl.removeOrphanComment(c));
+        assertEquals(0, decl.getOrphanComments().size());
+        assertFalse(c.getParentNode().isPresent());
+    }
+
+    @Test
+    public void removeOrphanCommentNegativeCase() {
+        ClassOrInterfaceDeclaration aClass = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), false, "A");
+        FieldDeclaration aField = new FieldDeclaration(EnumSet.noneOf(Modifier.class), new VariableDeclarator(PrimitiveType.intType(), "f"));
+        aClass.getMembers().add(aField);
+        Comment c = new LineComment("A comment");
+        aField.addOrphanComment(c);
+        // the comment is an orphan comment of the field, so trying to remove it on the class should not work
+        assertFalse(aClass.removeOrphanComment(c));
+        assertEquals(1, aField.getOrphanComments().size());
+        assertTrue(c.getParentNode().isPresent());
+    }
+
+    @Test
+    public void hasJavaDocCommentPositiveCaseWithSetJavaDocComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.setJavadocComment("A comment");
+        assertEquals(true, decl.hasJavaDocComment());
+    }
+
+    @Test
+    public void hasJavaDocCommentPositiveCaseWithSetComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.setComment(new JavadocComment("A comment"));
+        assertEquals(true, decl.hasJavaDocComment());
+    }
+
+    @Test
+    public void hasJavaDocCommentNegativeCaseNoComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        assertEquals(false, decl.hasJavaDocComment());
+    }
+
+    @Test
+    public void hasJavaDocCommentNegativeCaseLineComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.setComment(new LineComment("foo"));
+        assertEquals(false, decl.hasJavaDocComment());
+    }
+
+    @Test
+    public void hasJavaDocCommentNegativeCaseBlockComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.setComment(new BlockComment("foo"));
+        assertEquals(false, decl.hasJavaDocComment());
+    }
+
+    @Test
+    public void removeAllOnRequiredProperty() {
+        CompilationUnit cu = parse("class X{ void x(){}}");
+        MethodDeclaration methodDeclaration = cu.getType(0).getMethods().get(0);
+        methodDeclaration.getName().removeForced();
+        // Name is required, so to remove it the whole method is removed.
+        assertEquals(String.format("class X {%1$s}%1$s", EOL), cu.toString());
+    }
+
+    @Test
+    public void removingTheSecondOfAListOfIdenticalStatementsDoesNotMessUpTheParents() {
+        CompilationUnit unit = parse(String.format("public class Example {%1$s" +
+                "  public static void example() {%1$s" +
+                "    boolean swapped;%1$s" +
+                "    swapped=false;%1$s" +
+                "    swapped=false;%1$s" +
+                "  }%1$s" +
+                "}%1$s", EOL));
+        // remove the second swapped=false
+        Node target = unit.getChildNodes().get(0).getChildNodes().get(1).getChildNodes().get(2).getChildNodes().get(2);
+        target.remove();
+        // This will throw an exception if the parents are bad.
+        System.out.println(unit.toString());
+    }
+
+    @Test
+    public void findCompilationUnit() {
+        CompilationUnit cu = parse("class X{int x;}");
+        VariableDeclarator x = cu.getClassByName("X").get().getMember(0).asFieldDeclaration().getVariables().get(0);
+        assertEquals(cu, x.findCompilationUnit().get());
+    }
+
+    @Test
+    public void findParent() {
+        CompilationUnit cu = parse("class X{int x;}");
+        SimpleName x = cu.getClassByName("X").get().getMember(0).asFieldDeclaration().getVariables().get(0).getName();
+        assertEquals("int x;", x.findParent(FieldDeclaration.class).get().toString());
+    }
+
+    @Test
+    public void cantFindCompilationUnit() {
+        VariableDeclarator x = new VariableDeclarator();
+        assertFalse(x.findCompilationUnit().isPresent());
+    }
+
+    @Test
+    public void genericWalk() {
+        Expression e = parseExpression("1+1");
+        StringBuilder b = new StringBuilder();
+        e.walk(n -> b.append(n.toString()));
+        assertEquals("1 + 111", b.toString());
+    }
+
+    @Test
+    public void classSpecificWalk() {
+        Expression e = parseExpression("1+1");
+        StringBuilder b = new StringBuilder();
+        e.walk(IntegerLiteralExpr.class, n -> b.append(n.toString()));
+        assertEquals("11", b.toString());
+    }
+
+    @Test
+    public void conditionalFindAll() {
+        Expression e = parseExpression("1+2+3");
+        List<IntegerLiteralExpr> ints = e.findAll(IntegerLiteralExpr.class, n -> n.asInt() > 1);
+        assertEquals("[2, 3]", ints.toString());
+    }
+
+    @Test
+    public void typeOnlyFindAll() {
+        Expression e = parseExpression("1+2+3");
+        List<IntegerLiteralExpr> ints = e.findAll(IntegerLiteralExpr.class);
+        assertEquals("[1, 2, 3]", ints.toString());
+    }
+
+    @Test
+    public void typeOnlyFindAllMatchesSubclasses() {
+        Expression e = parseExpression("1+2+3");
+        List<Node> ints = e.findAll(Node.class);
+        assertEquals("[1 + 2 + 3, 1 + 2, 1, 2, 3]", ints.toString());
+    }
+
+    @Test
+    public void conditionalTypedFindFirst() {
+        Expression e = parseExpression("1+2+3");
+        Optional<IntegerLiteralExpr> ints = e.findFirst(IntegerLiteralExpr.class, n -> n.asInt() > 1);
+        assertEquals("Optional[2]", ints.toString());
+    }
+
+    @Test
+    public void typeOnlyFindFirst() {
+        Expression e = parseExpression("1+2+3");
+        Optional<IntegerLiteralExpr> ints = e.findFirst(IntegerLiteralExpr.class);
+        assertEquals("Optional[1]", ints.toString());
+    }
+    
+    @Test
+    public void stream() {
+        Expression e = parseExpression("1+2+3");
+        List<IntegerLiteralExpr> ints = e.stream()
+                .filter(n -> n instanceof IntegerLiteralExpr)
+                .map(IntegerLiteralExpr.class::cast)
+                .filter(i -> i.asInt() > 1)
+                .collect(Collectors.toList());
+        assertEquals("[2, 3]", ints.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/ParseResultTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/ParseResultTest.java
new file mode 100644
index 0000000..45d7725
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/ParseResultTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.Problem;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.ast.Node.Parsedness.PARSED;
+import static com.github.javaparser.ast.Node.Parsedness.UNPARSABLE;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ParseResultTest {
+    private final JavaParser javaParser = new JavaParser(new ParserConfiguration());
+
+    @Test
+    public void whenParsingSucceedsThenWeGetResultsAndNoProblems() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{}"));
+
+        assertThat(result.getResult().isPresent()).isTrue();
+        assertThat(result.getResult().get().getParsed()).isEqualTo(PARSED);
+        assertThat(result.getProblems()).isEmpty();
+        assertThat(result.getTokens().isPresent()).isTrue();
+
+        assertThat(result.toString()).isEqualTo("Parsing successful");
+    }
+
+    @Test
+    public void whenParsingFailsThenWeGetProblemsAndABadResult() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class {"));
+
+        assertThat(result.getResult().isPresent()).isTrue();
+        assertThat(result.getResult().get().getParsed()).isEqualTo(UNPARSABLE);
+        assertThat(result.getProblems().size()).isEqualTo(1);
+
+        Problem problem = result.getProblem(0);
+        assertThat(problem.getMessage()).isEqualTo("Parse error. Found \"{\", expected one of  \"enum\" \"exports\" \"module\" \"open\" \"opens\" \"provides\" \"requires\" \"strictfp\" \"to\" \"transitive\" \"uses\" \"with\" <IDENTIFIER>");
+        assertThat(result.getTokens().isPresent()).isTrue();
+
+        assertThat(result.toString()).startsWith("Parsing failed:" + EOL + "(line 1,col 1) Parse error.");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/ReplaceNodeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/ReplaceNodeTest.java
new file mode 100644
index 0000000..4e93efc
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/ReplaceNodeTest.java
@@ -0,0 +1,32 @@
+package com.github.javaparser.ast;
+
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parse;
+import static com.github.javaparser.JavaParser.parsePackageDeclaration;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class ReplaceNodeTest {
+    @Test
+    public void testSimplePropertyWithGenericReplace() {
+        CompilationUnit cu = parse("package x; class Y {}");
+        cu.replace(cu.getPackageDeclaration().get(), parsePackageDeclaration("package z;"));
+        assertEquals(String.format("package z;%1$s" +
+                "%1$s" +
+                "class Y {%1$s" +
+                "}%1$s", EOL), cu.toString());
+    }
+
+    @Test
+    public void testListProperty() {
+        CompilationUnit cu = parse("package x; class Y {}");
+        cu.replace(cu.getClassByName("Y").get(), parse("class B{int y;}").getClassByName("B").get());
+        assertEquals(String.format("package x;%1$s" +
+                "%1$s" +
+                "class B {%1$s" +
+                "%1$s" +
+                "    int y;%1$s" +
+                "}%1$s", EOL), cu.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/body/AnnotationMemberDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/AnnotationMemberDeclarationTest.java
new file mode 100644
index 0000000..e133b50
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/AnnotationMemberDeclarationTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class AnnotationMemberDeclarationTest {
+
+    @Test
+    public void whenSettingNameTheParentOfNameIsAssigned() {
+        AnnotationMemberDeclaration decl = new AnnotationMemberDeclaration();
+        SimpleName name = new SimpleName("foo");
+        decl.setName(name);
+        assertTrue(name.getParentNode().isPresent());
+        assertTrue(decl == name.getParentNode().get());
+    }
+
+    @Test
+    public void removeDefaultValueWhenNoDefaultValueIsPresent() {
+        AnnotationMemberDeclaration decl = new AnnotationMemberDeclaration();
+        SimpleName name = new SimpleName("foo");
+        decl.setName(name);
+
+        decl.removeDefaultValue();
+
+        assertFalse(decl.getDefaultValue().isPresent());
+    }
+
+    @Test
+    public void removeDefaultValueWhenDefaultValueIsPresent() {
+        AnnotationMemberDeclaration decl = new AnnotationMemberDeclaration();
+        SimpleName name = new SimpleName("foo");
+        decl.setName(name);
+        Expression defaultValue = new IntegerLiteralExpr("2");
+        decl.setDefaultValue(defaultValue);
+
+        decl.removeDefaultValue();
+
+        assertFalse(defaultValue.getParentNode().isPresent());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclarationTest.java
new file mode 100644
index 0000000..52c77f1
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/ClassOrInterfaceDeclarationTest.java
@@ -0,0 +1,60 @@
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class ClassOrInterfaceDeclarationTest {
+    @Test
+    public void staticNestedClass() {
+        CompilationUnit cu = JavaParser.parse("class X{static class Y{}}");
+        ClassOrInterfaceDeclaration y = cu.getClassByName("X").get().getMembers().get(0).asClassOrInterfaceDeclaration();
+
+        assertFalse(y.isInnerClass());
+        assertTrue(y.isNestedType());
+        assertFalse(y.isLocalClassDeclaration());
+    }
+
+    @Test
+    public void nestedInterface() {
+        CompilationUnit cu = JavaParser.parse("class X{interface Y{}}");
+        ClassOrInterfaceDeclaration y = cu.getClassByName("X").get().getMembers().get(0).asClassOrInterfaceDeclaration();
+
+        assertFalse(y.isInnerClass());
+        assertTrue(y.isNestedType());
+        assertFalse(y.isLocalClassDeclaration());
+    }
+
+    @Test
+    public void nonStaticNestedClass() {
+        CompilationUnit cu = JavaParser.parse("class X{class Y{}}");
+        ClassOrInterfaceDeclaration y = cu.getClassByName("X").get().getMembers().get(0).asClassOrInterfaceDeclaration();
+
+        assertTrue(y.isInnerClass());
+        assertTrue(y.isNestedType());
+        assertFalse(y.isLocalClassDeclaration());
+    }
+
+    @Test
+    public void topClass() {
+        CompilationUnit cu = JavaParser.parse("class X{}");
+        ClassOrInterfaceDeclaration y = cu.getClassByName("X").get();
+
+        assertFalse(y.isInnerClass());
+        assertFalse(y.isNestedType());
+        assertFalse(y.isLocalClassDeclaration());
+    }
+
+    @Test
+    public void localClass() {
+        MethodDeclaration method= (MethodDeclaration)JavaParser.parseBodyDeclaration("void x(){class X{};}");
+        ClassOrInterfaceDeclaration x = method.findFirst(ClassOrInterfaceDeclaration.class).get();
+
+        assertFalse(x.isInnerClass());
+        assertFalse(x.isNestedType());
+        assertTrue(x.isLocalClassDeclaration());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/body/ConstructorDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/ConstructorDeclarationTest.java
new file mode 100644
index 0000000..34d3b62
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/ConstructorDeclarationTest.java
@@ -0,0 +1,23 @@
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.CLASS_BODY;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class ConstructorDeclarationTest {
+    @Test
+    public void acceptsSuper() {
+        ConstructorDeclaration cons = new ConstructorDeclaration("Cons");
+        cons.createBody().addStatement("super();");
+
+        assertEquals(String.format("public Cons() {%1$s" +
+                "    super();%1$s" +
+                "}", EOL), cons.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/body/FieldDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/FieldDeclarationTest.java
new file mode 100644
index 0000000..0e263a4
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/FieldDeclarationTest.java
@@ -0,0 +1,24 @@
+package com.github.javaparser.ast.body;
+
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parse;
+import static org.junit.Assert.assertEquals;
+
+public class FieldDeclarationTest {
+    @Test
+    public void wofjweoifj() {
+        CompilationUnit compilationUnit = parse("" +
+                "class A {\n" +
+                "    int a, b;\n" +
+                "}");
+
+        BodyDeclaration<?> declaration = compilationUnit.getType(0).getMembers().get(0);
+        FieldDeclaration fieldDeclaration = declaration.asFieldDeclaration();
+        VariableDeclarator var1 = fieldDeclaration.getVariables().get(0);
+        VariableDeclarator var2 = fieldDeclaration.getVariables().get(1);
+        assertEquals(var1, var1.getType().getParentNode().get());
+        assertEquals(var2, var2.getType().getParentNode().get());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/body/MethodDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/MethodDeclarationTest.java
new file mode 100644
index 0000000..1cbab66
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/body/MethodDeclarationTest.java
@@ -0,0 +1,87 @@
+package com.github.javaparser.ast.body;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseBodyDeclaration;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+
+public class MethodDeclarationTest {
+    @Test
+    public void annotationsAllowedAfterGenericsAndBeforeReturnType() {
+        parseBodyDeclaration("public <T> @Abc String method() {return null;}");
+    }
+
+    @Test
+    public void annotationsAllowedBeforeGenerics() {
+        parseBodyDeclaration("public @Abc <T> String method() {return null;}");
+    }
+
+    @Test
+    public void explicitReceiverParameters1() {
+        MethodDeclaration method = parseBodyDeclaration("void InnerInner(@mypackage.Anno Source.@mypackage.Anno Inner Source.Inner.this) { }").asMethodDeclaration();
+        assertEquals("Source.Inner.this", method.getReceiverParameter().get().getNameAsString());
+    }
+
+    @Test
+    public void explicitReceiverParameters2() {
+        MethodDeclaration method = parseBodyDeclaration("void x(A this) { }").asMethodDeclaration();
+        assertEquals("this", method.getReceiverParameter().get().getNameAsString());
+    }
+
+    @Test
+    public void explicitReceiverParameters3() {
+        MethodDeclaration method = parseBodyDeclaration("void x(A that) { }").asMethodDeclaration();
+        assertFalse(method.getReceiverParameter().isPresent());
+    }
+
+    @Test
+    public void signaturesEqual() {
+        MethodDeclaration method1 = parseBodyDeclaration("void x(String a) { }").asMethodDeclaration();
+        MethodDeclaration method2 = parseBodyDeclaration("int x(String z);").asMethodDeclaration();
+        assertEquals(method1.getSignature(), method2.getSignature());
+    }
+
+    @Test
+    public void signaturesEqualWhenGenericsDiffer() {
+        MethodDeclaration method1 = parseBodyDeclaration("void x(List<Long> a) { }").asMethodDeclaration();
+        MethodDeclaration method2 = parseBodyDeclaration("void x(List<Integer> a) { }").asMethodDeclaration();
+        assertEquals(method1.getSignature(), method2.getSignature());
+    }
+
+    @Test
+    public void signaturesEqualWhenAnnotationsDiffer() {
+        MethodDeclaration method1 = parseBodyDeclaration("void x(@A @B List a) { }").asMethodDeclaration();
+        MethodDeclaration method2 = parseBodyDeclaration("void x(@C List a) { }").asMethodDeclaration();
+        assertEquals(method1.getSignature(), method2.getSignature());
+    }
+
+    @Test
+    public void signaturesDifferentName() {
+        MethodDeclaration method1 = parseBodyDeclaration("void x(String a) { }").asMethodDeclaration();
+        MethodDeclaration method2 = parseBodyDeclaration("int y(String z);").asMethodDeclaration();
+        assertNotEquals(method1.getSignature(), method2.getSignature());
+    }
+
+    @Test
+    public void signaturesDifferentTypes() {
+        MethodDeclaration method1 = parseBodyDeclaration("void x(String a) { }").asMethodDeclaration();
+        MethodDeclaration method2 = parseBodyDeclaration("int x(int z);").asMethodDeclaration();
+        assertNotEquals(method1.getSignature(), method2.getSignature());
+    }
+
+    @Test
+    public void signaturesDifferentVarargs() {
+        MethodDeclaration method1 = parseBodyDeclaration("int x(int z);").asMethodDeclaration();
+        MethodDeclaration method2 = parseBodyDeclaration("int x(int... z);").asMethodDeclaration();
+        assertNotEquals(method1.getSignature(), method2.getSignature());
+    }
+
+    @Test
+    public void signatureToString() {
+        MethodDeclaration method1 = parseBodyDeclaration("int x(int z, String q);").asMethodDeclaration();
+        assertEquals("x(int, String)", method1.getSignature().toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/comments/CommentTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/comments/CommentTest.java
new file mode 100644
index 0000000..946b76a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/comments/CommentTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.comments;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.Name;
+import org.junit.Test;
+
+import java.util.EnumSet;
+
+import static com.github.javaparser.JavaParser.parse;
+import static com.github.javaparser.JavaParser.parseName;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class CommentTest {
+
+    @Test
+    public void removeOrphanComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), false, "A");
+        Comment c = new LineComment("A comment");
+        decl.addOrphanComment(c);
+        assertEquals(1, decl.getOrphanComments().size());
+        assertTrue(c.remove());
+        assertEquals(0, decl.getOrphanComments().size());
+    }
+
+    @Test
+    public void removeAssociatedComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), false, "A");
+        Comment c = new LineComment("A comment");
+        decl.setComment(c);
+        assertEquals(true, decl.getComment().isPresent());
+        assertTrue(c.remove());
+        assertEquals(false, decl.getComment().isPresent());
+    }
+
+    @Test
+    public void cannotRemoveCommentNotUsedAnywhere() {
+        Comment c = new LineComment("A comment");
+        assertFalse(c.remove());
+    }
+
+    @Test
+    public void unicodeEscapesArePreservedInComments() {
+        CompilationUnit cu = parse("// xxx\\u2122xxx");
+        Comment comment = cu.getAllContainedComments().get(0);
+        assertEquals(" xxx\\u2122xxx", comment.getContent());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/AssignExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/AssignExprTest.java
new file mode 100644
index 0000000..55e87f5
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/AssignExprTest.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.ast.expr;
+
+import org.junit.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class AssignExprTest {
+    @Test
+    public void convertOperator() {
+        assertEquals(BinaryExpr.Operator.PLUS, AssignExpr.Operator.PLUS.toBinaryOperator().get());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/BinaryExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/BinaryExprTest.java
new file mode 100644
index 0000000..9975ef3
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/BinaryExprTest.java
@@ -0,0 +1,12 @@
+package com.github.javaparser.ast.expr;
+
+import org.junit.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class BinaryExprTest {
+    @Test
+    public void convertOperator() {
+        assertEquals(AssignExpr.Operator.PLUS, BinaryExpr.Operator.PLUS.toAssignOperator().get());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/DoubleLiteralExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/DoubleLiteralExprTest.java
new file mode 100644
index 0000000..9c54643
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/DoubleLiteralExprTest.java
@@ -0,0 +1,37 @@
+package com.github.javaparser.ast.expr;
+
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+
+public class DoubleLiteralExprTest {
+    @Test
+    public void test1() {
+        float x = 0x0.00_00_02p-126f;
+        parseExpression("0x0.00_00_02p-126f");
+    }
+
+    @Test
+    public void test2() {
+        double x = 0x0.000_000_000_000_1p-1_022;
+        parseExpression("0x0.000_000_000_000_1p-1_022");
+    }
+
+    @Test
+    public void test3() {
+        double a = 0x1.p+1;
+        parseExpression("0x1.p+1");
+    }
+
+    @Test
+    public void test4() {
+        double a = 0x.0p0;
+        parseExpression("0x.0p0");
+    }
+
+    @Test
+    public void test5() {
+        double x = 0x0_0.0_0p-1_0;
+        parseExpression("0x0_0.0_0p-1_0");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/InstanceOfExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/InstanceOfExprTest.java
new file mode 100644
index 0000000..0d8a5b9
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/InstanceOfExprTest.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.JavaParser;
+import org.junit.Test;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+
+public class InstanceOfExprTest {
+    @Test
+    public void annotationsOnTheType() {
+        InstanceOfExpr expr = JavaParser.parseExpression("s instanceof @A @DA String");
+
+        assertThat(expr.getType().getAnnotations()).containsExactly(new MarkerAnnotationExpr("A"), new MarkerAnnotationExpr("DA"));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/LambdaExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/LambdaExprTest.java
new file mode 100644
index 0000000..082906b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/LambdaExprTest.java
@@ -0,0 +1,41 @@
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.TokenRange;
+import com.github.javaparser.ast.Node;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+import static org.junit.Assert.*;
+
+public class LambdaExprTest {
+    @Test
+    public void lambdaRange1(){
+        Expression expression = parseExpression("x -> y");
+        assertRange("x", "y", expression);
+    }
+
+    @Test
+    public void lambdaRange2(){
+        Expression expression = parseExpression("(x) -> y");
+        assertRange("(", "y", expression);
+    }
+
+    private void assertRange(String startToken, String endToken, Node node) {
+        TokenRange tokenRange = node.getTokenRange().get();
+        assertEquals(startToken, tokenRange.getBegin().asString());
+        assertEquals(endToken, tokenRange.getEnd().asString());
+    }
+
+    @Test
+    public void getExpressionBody(){
+        LambdaExpr lambdaExpr = parseExpression("x -> y").asLambdaExpr();
+        assertEquals("Optional[y]", lambdaExpr.getExpressionBody().toString());
+    }
+
+    @Test
+    public void getNoExpressionBody(){
+        LambdaExpr lambdaExpr = parseExpression("x -> {y;}").asLambdaExpr();
+        assertEquals("Optional.empty", lambdaExpr.getExpressionBody().toString());
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/LiteralStringValueExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/LiteralStringValueExprTest.java
new file mode 100644
index 0000000..1b9dfef
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/LiteralStringValueExprTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.JavaParser;
+import org.assertj.core.data.Percentage;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SuppressWarnings("OctalInteger")
+public class LiteralStringValueExprTest {
+
+    @Test
+    public void trivialLiteralsAreConverted() {
+        assertThat(new CharLiteralExpr('\t').getValue()).isEqualTo("\\t");
+        assertThat(new CharLiteralExpr('\b').getValue()).isEqualTo("\\b");
+        assertThat(new CharLiteralExpr('\f').getValue()).isEqualTo("\\f");
+        assertThat(new CharLiteralExpr('\r').getValue()).isEqualTo("\\r");
+        assertThat(new CharLiteralExpr('\n').getValue()).isEqualTo("\\n");
+        assertThat(new CharLiteralExpr('\\').getValue()).isEqualTo("\\\\");
+        assertThat(new CharLiteralExpr('\"').getValue()).isEqualTo("\\\"");
+
+        assertThat(new IntegerLiteralExpr("0B0").asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr("0b0").asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr("0X0").asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr("0x0").asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr(0).asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr(00).asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr(0B0).asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr(0b0).asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr(0X0).asInt()).isEqualTo(0);
+        assertThat(new IntegerLiteralExpr(0x0).asInt()).isEqualTo(0);
+
+        assertThat(new LongLiteralExpr("0B0L").asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr("0b0L").asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr("0X0L").asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr("0x0L").asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr(0L).asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr(00L).asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr(0B0L).asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr(0b0L).asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr(0X0L).asLong()).isEqualTo(0);
+        assertThat(new LongLiteralExpr(0x0L).asLong()).isEqualTo(0);
+
+        assertThat(new DoubleLiteralExpr("0.0f").asDouble()).isEqualTo(0.0);
+        assertThat(new DoubleLiteralExpr("0.0F").asDouble()).isEqualTo(0.0);
+        assertThat(new DoubleLiteralExpr("0.0d").asDouble()).isEqualTo(0.0);
+        assertThat(new DoubleLiteralExpr("0.0D").asDouble()).isEqualTo(0.0);
+        assertThat(new DoubleLiteralExpr(0.0F).asDouble()).isEqualTo(0.0);
+        assertThat(new DoubleLiteralExpr(0.0f).asDouble()).isEqualTo(0.0);
+        assertThat(new DoubleLiteralExpr(0.0D).asDouble()).isEqualTo(0.0);
+        assertThat(new DoubleLiteralExpr(0.0d).asDouble()).isEqualTo(0.0);
+    }
+
+    @Test
+    public void lowerAndUpperBoundIntegersAreConverted() {
+        IntegerLiteralExpr dec = parseExpression("2147483647");
+        IntegerLiteralExpr posOct = parseExpression("0177_7777_7777");
+        IntegerLiteralExpr negOct = parseExpression("0377_7777_7777");
+        IntegerLiteralExpr posHex = parseExpression("0x7fff_ffff");
+        IntegerLiteralExpr negHex = parseExpression("0xffff_ffff");
+        IntegerLiteralExpr posBin = parseExpression("0b0111_1111_1111_1111_1111_1111_1111_1111");
+        IntegerLiteralExpr negBin = parseExpression("0b1000_0000_0000_0000_0000_0000_0000_0000");
+
+        assertThat(dec.asInt()).isEqualTo(2147483647);
+        assertThat(posOct.asInt()).isEqualTo(2147483647); // 0177_7777_7777
+        assertThat(negOct.asInt()).isEqualTo(-1); // 0377_7777_7777
+        assertThat(posHex.asInt()).isEqualTo(0x7fff_ffff);
+        assertThat(negHex.asInt()).isEqualTo(0xffff_ffff);
+        assertThat(posBin.asInt()).isEqualTo(0b0111_1111_1111_1111_1111_1111_1111_1111);
+        assertThat(negBin.asInt()).isEqualTo(0b1000_0000_0000_0000_0000_0000_0000_0000);
+    }
+
+    @Test
+    public void lowerAndUpperBoundLongsAreConverted() {
+        LongLiteralExpr dec = parseExpression("9223372036854775807L");
+        LongLiteralExpr posOct = parseExpression("07_7777_7777_7777_7777_7777L");
+        LongLiteralExpr negOct = parseExpression("010_0000_0000_0000_0000_0000L");
+        LongLiteralExpr posHex = parseExpression("0x7fff_ffff_ffff_ffffL");
+        LongLiteralExpr negHex = parseExpression("0xffff_ffff_ffff_ffffL");
+        LongLiteralExpr posBin = parseExpression("0b0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L");
+        LongLiteralExpr negBin = parseExpression("0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000L");
+
+        assertThat(dec.asLong()).isEqualTo(9223372036854775807L);
+        assertThat(posOct.asLong()).isEqualTo(9223372036854775807L); // 07_7777_7777_7777_7777_7777L
+        assertThat(negOct.asLong()).isEqualTo(-9223372036854775808L); // 010_0000_0000_0000_0000_0000L
+        assertThat(posHex.asLong()).isEqualTo(0x7fff_ffff_ffff_ffffL);
+        assertThat(negHex.asLong()).isEqualTo(0xffff_ffff_ffff_ffffL);
+        assertThat(posBin.asLong()).isEqualTo(0b0111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111_1111L);
+        assertThat(negBin.asLong()).isEqualTo(0b1000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000L);
+    }
+
+    @Test
+    public void charLiteralsAreConverted() {
+        CharLiteralExpr a = parseExpression("'a'");
+        CharLiteralExpr percent = parseExpression("'%'");
+        CharLiteralExpr tab = parseExpression("'\\t'");
+        CharLiteralExpr newLine = parseExpression("'\\n'");
+        CharLiteralExpr slash = parseExpression("'\\\\'");
+        CharLiteralExpr quote = parseExpression("'\\''");
+        CharLiteralExpr omega = parseExpression("'\\u03a9'");
+        CharLiteralExpr unicode = parseExpression("'\\uFFFF'");
+        CharLiteralExpr ascii = parseExpression("'\\177'");
+        CharLiteralExpr trademark = parseExpression("'™'");
+
+        assertThat(a.asChar()).isEqualTo('a');
+        assertThat(percent.asChar()).isEqualTo('%');
+        assertThat(tab.asChar()).isEqualTo('\t');
+        assertThat(newLine.asChar()).isEqualTo('\n');
+        assertThat(slash.asChar()).isEqualTo('\\');
+        assertThat(quote.asChar()).isEqualTo('\'');
+        assertThat(omega.asChar()).isEqualTo('\u03a9');
+        assertThat(unicode.asChar()).isEqualTo('\uFFFF');
+        assertThat(ascii.asChar()).isEqualTo('\177');
+        assertThat(trademark.asChar()).isEqualTo('™');
+    }
+
+    @Test
+    public void lowerAndUpperBoundDoublesAreConverted() {
+        DoubleLiteralExpr posFloat = parseExpression("3.4028235e38f");
+        DoubleLiteralExpr negFloat = parseExpression("1.40e-45f");
+        DoubleLiteralExpr posDouble = parseExpression("1.7976931348623157e308");
+        DoubleLiteralExpr negDouble = parseExpression("4.9e-324");
+        DoubleLiteralExpr posHexFloat = parseExpression("0x1.fffffffffffffp1023");
+        DoubleLiteralExpr negHexFloat = parseExpression("0x0.0000000000001P-1022");
+
+        assertThat(posFloat.asDouble()).isCloseTo(3.4028235e38f, Percentage.withPercentage(1));
+        assertThat(negFloat.asDouble()).isCloseTo(1.40e-45f, Percentage.withPercentage(1));
+        assertThat(posDouble.asDouble()).isEqualTo(1.7976931348623157e308);
+        assertThat(negDouble.asDouble()).isEqualTo(4.9e-324);
+        assertThat(posHexFloat.asDouble()).isEqualTo(0x1.fffffffffffffp1023);
+        assertThat(negHexFloat.asDouble()).isEqualTo(0x0.0000000000001P-1022);
+    }
+
+    @Test
+    public void specialCharactersInStringsAreEscaped() {
+        assertThat(new StringLiteralExpr("\n").getValue()).isEqualTo("\\n");
+        assertThat(new StringLiteralExpr("\r").getValue()).isEqualTo("\\r");
+        assertThat(new StringLiteralExpr("").setEscapedValue("\n").getValue()).isEqualTo("\\n");
+        assertThat(new StringLiteralExpr("").setEscapedValue("\r").getValue()).isEqualTo("\\r");
+        assertThat(new StringLiteralExpr("").setEscapedValue("\n").asString()).isEqualTo("\n");
+        assertThat(new StringLiteralExpr("").setEscapedValue("\r").asString()).isEqualTo("\r");
+        assertThat(new StringLiteralExpr("Hello\nWorld\rHello\"World\'").asString()).isEqualTo("Hello\nWorld\rHello\"World\'");
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/MethodCallExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/MethodCallExprTest.java
new file mode 100644
index 0000000..2585764
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/MethodCallExprTest.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.ast.expr;
+
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+import static java.util.Optional.empty;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class MethodCallExprTest {
+    
+    @Test
+    public void replaceLambdaIssue1290() {
+        MethodCallExpr methodCallExpr = parseExpression("callSomeFun(r -> r instanceof SomeType)").asMethodCallExpr();
+        LambdaExpr lambdaExpr = methodCallExpr.getArgument(0).asLambdaExpr();
+        MethodCallExpr lambdaWrapper = new MethodCallExpr("lambdaWrapper");
+        lambdaExpr.replace(lambdaWrapper);
+        
+        assertEquals(2, methodCallExpr.getChildNodes().size());
+        assertEquals(empty(), lambdaExpr.getParentNode());
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/MethodReferenceExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/MethodReferenceExprTest.java
new file mode 100644
index 0000000..6f0643b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/MethodReferenceExprTest.java
@@ -0,0 +1,114 @@
+package com.github.javaparser.ast.expr;
+
+import org.junit.Test;
+
+import static com.github.javaparser.utils.TestUtils.assertExpressionValid;
+import static org.junit.Assert.assertTrue;
+
+public class MethodReferenceExprTest {
+
+    @Test
+    public void methodReferenceExprHasAlwaysAScope() {
+        assertTrue(new MethodReferenceExpr().getScope() != null);
+    }
+
+    @Test
+    public void reference1() {
+        assertExpressionValid("String::length");
+    }
+        
+    @Test
+    public void reference2() {
+        assertExpressionValid("System::currentTimeMillis // static method");
+    }
+        
+    @Test
+    public void reference3() {
+        assertExpressionValid("List<String>::size // explicit type arguments for generic type");
+    }
+        
+    @Test
+    public void reference4() {
+        assertExpressionValid("List::size // inferred type arguments for generic type");
+    }
+        
+    @Test
+    public void reference5() {
+        assertExpressionValid("int[]::clone");
+    }
+        
+    @Test
+    public void reference6() {
+        assertExpressionValid("T::tvarMember");
+    }
+        
+    @Test
+    public void reference7() {
+        assertExpressionValid("System.out::println");
+    }
+        
+    @Test
+    public void reference8() {
+        assertExpressionValid("\"abc\"::length");
+    }
+        
+    @Test
+    public void reference9() {
+        assertExpressionValid("foo[x]::bar");
+    }
+        
+    @Test
+    public void reference10() {
+        assertExpressionValid("(test ? list.replaceAll(String::trim) : list) :: iterator");
+    }
+        
+    @Test
+    public void reference10Annotated1() {
+        assertExpressionValid("(test ? list.replaceAll(@A String::trim) : list) :: iterator");
+    }
+        
+    @Test
+    public void reference11() {
+        assertExpressionValid("String::valueOf // overload resolution needed");
+    }
+        
+    @Test
+    public void reference12() {
+        assertExpressionValid("Arrays::sort // type arguments inferred from context");
+    }
+        
+    @Test
+    public void reference13() {
+        assertExpressionValid("Arrays::<String>sort // explicit type arguments");
+    }
+        
+    @Test
+    public void reference14() {
+        assertExpressionValid("ArrayList<String>::new // constructor for parameterized type");
+    }
+        
+    @Test
+    public void reference15() {
+        assertExpressionValid("ArrayList::new // inferred type arguments");
+    }
+        
+    @Test
+    public void reference16() {
+        assertExpressionValid("Foo::<Integer>new // explicit type arguments");
+    }
+        
+    @Test
+    public void reference17() {
+        assertExpressionValid("Bar<String>::<Integer>new // generic class, generic constructor");
+    }
+        
+    @Test
+    public void reference18() {
+        assertExpressionValid("Outer.Inner::new // inner class constructor");
+    }
+        
+    @Test
+    public void reference19() {
+        assertExpressionValid("int[]::new // array creation");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/NameTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/NameTest.java
new file mode 100644
index 0000000..6df3a68
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/NameTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.expr;
+
+import com.github.javaparser.ParseProblemException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.ImportDeclaration;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.junit.Assert.assertEquals;
+
+public class NameTest {
+    @Test
+    public void outerNameExprIsTheRightMostIdentifier() {
+        Name name = parseName("a.b.c");
+        assertEquals("c", name.getIdentifier());
+    }
+
+    @Test
+    public void parsingAndUnparsingWorks() {
+        Name name = parseName("a.b.c");
+        assertEquals("a.b.c", name.asString());
+    }
+
+    @Test(expected = ParseProblemException.class)
+    public void parsingEmptyNameThrowsException() {
+        parseName("");
+    }
+
+    @Test
+    public void nameCanHaveAnnotationsInside() {
+        Name name = parseName("a.@A b. @C c");
+        assertEquals("a.b.c", name.asString());
+        assertThat(name.getAnnotations()).containsExactly(new MarkerAnnotationExpr("C"));
+        assertThat(name.getQualifier().get().getAnnotations()).containsExactly(new MarkerAnnotationExpr("A"));
+
+        assertEquals("a.@A b.@C c", name.toString());
+        assertEquals("a.@A b.@C c", ConcreteSyntaxModel.genericPrettyPrint(name));
+    }
+
+    @Test
+    public void importName() {
+        ImportDeclaration importDeclaration = parseImport("import java.@Abc util.List;");
+
+        assertThat(importDeclaration.getName().getQualifier().get().getAnnotations()).containsExactly(new MarkerAnnotationExpr("Abc"));
+
+        assertEquals("import java.@Abc util.List;" + EOL, importDeclaration.toString());
+        assertEquals("import java.@Abc util.List;" + EOL, ConcreteSyntaxModel.genericPrettyPrint(importDeclaration));
+    }
+
+    @Test
+    public void packageName() {
+        CompilationUnit cu = parse("package @Abc p1.p2;");
+
+        assertThat(cu.getPackageDeclaration().get().getName().getQualifier().get().getAnnotations()).containsExactly(new MarkerAnnotationExpr("Abc"));
+
+        assertEquals("package @Abc p1.p2;" + EOL + EOL, cu.toString());
+        assertEquals("package @Abc p1.p2;" + EOL + EOL, ConcreteSyntaxModel.genericPrettyPrint(cu));
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/SimpleNameTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/SimpleNameTest.java
new file mode 100644
index 0000000..f7e0285
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/SimpleNameTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.expr;
+
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseSimpleName;
+import static junit.framework.TestCase.assertEquals;
+
+public class SimpleNameTest {
+
+    @Test
+    public void defaultConstructorSetsIdentifierToEmpty() {
+        assertEquals("empty", new SimpleName().getIdentifier());
+    }
+
+    @Test(expected = AssertionError.class)
+    public void identifierMustNotBeEmpty() {
+        new SimpleName("");
+    }
+
+    @Test(expected = AssertionError.class)
+    public void identifierMustNotBeNull() {
+        new SimpleName(null);
+    }
+
+    @Test
+    public void unicodeEscapesArePreservedInIdentifiers() {
+        SimpleName name = parseSimpleName("xxx\\u2122xxx");
+        assertEquals("xxx\\u2122xxx", name.asString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/StringLiteralExprTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/StringLiteralExprTest.java
new file mode 100644
index 0000000..50a9bfc
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/expr/StringLiteralExprTest.java
@@ -0,0 +1,14 @@
+package com.github.javaparser.ast.expr;
+
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+import static org.junit.Assert.*;
+
+public class StringLiteralExprTest {
+    @Test
+    public void unicodeEscapesArePreservedInStrings() {
+        StringLiteralExpr omega = parseExpression("\"xxx\\u03a9xxx\"");
+        assertEquals("xxx\\u03a9xxx", omega.getValue());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/imports/ImportDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/imports/ImportDeclarationTest.java
new file mode 100644
index 0000000..ca821fb
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/imports/ImportDeclarationTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.imports;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.ImportDeclaration;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ImportDeclarationTest {
+    @Test
+    public void singleTypeImportDeclaration() {
+        ImportDeclaration i = JavaParser.parseImport("import a.b.c.X;");
+        assertEquals("a.b.c.X", i.getNameAsString());
+    }
+
+    @Test
+    public void typeImportOnDemandDeclaration() {
+        ImportDeclaration i = JavaParser.parseImport("import a.b.c.D.*;");
+        assertEquals("a.b.c.D", i.getName().toString());
+        assertEquals("D", i.getName().getIdentifier());
+    }
+
+    @Test
+    public void singleStaticImportDeclaration() {
+        ImportDeclaration i = JavaParser.parseImport("import static a.b.c.X.def;");
+        assertEquals("a.b.c.X", i.getName().getQualifier().get().asString());
+        assertEquals("def", i.getName().getIdentifier());
+    }
+
+    @Test
+    public void staticImportOnDemandDeclaration() {
+        ImportDeclaration i = JavaParser.parseImport("import static a.b.c.X.*;");
+        assertEquals("a.b.c.X", i.getNameAsString());
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithJavadocTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithJavadocTest.java
new file mode 100644
index 0000000..37728e7
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithJavadocTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import org.junit.Test;
+
+import java.util.EnumSet;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class NodeWithJavadocTest {
+
+    @Test
+    public void removeJavaDocNegativeCaseNoComment() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        assertEquals(false, decl.removeJavaDocComment());
+    }
+
+    @Test
+    public void removeJavaDocNegativeCaseCommentNotJavaDoc() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.setComment(new LineComment("A comment"));
+        assertEquals(false, decl.removeJavaDocComment());
+        assertTrue(decl.getComment().isPresent());
+    }
+
+    @Test
+    public void removeJavaDocPositiveCase() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.setComment(new JavadocComment("A comment"));
+        assertEquals(true, decl.removeJavaDocComment());
+        assertFalse(decl.getComment().isPresent());
+    }
+
+    @Test
+    public void getJavadocOnMethodWithLineCommentShouldReturnEmptyOptional() {
+        MethodDeclaration method = new MethodDeclaration();
+        method.setLineComment("Lorem Ipsum.");
+
+        assertFalse(method.getJavadocComment().isPresent());
+        assertFalse(method.getJavadoc().isPresent());
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithModifiersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithModifiersTest.java
new file mode 100644
index 0000000..20c302d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithModifiersTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.observer.AstObserverAdapter;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import org.junit.Test;
+
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class NodeWithModifiersTest {
+
+    @Test
+    public void addModifierWorks() {
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.addModifier(Modifier.PUBLIC);
+        assertEquals(EnumSet.of(Modifier.PUBLIC), decl.getModifiers());
+    }
+
+    @Test
+    public void addModifierTriggerNotification() {
+        List<String> changes = new LinkedList<>();
+        ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class),
+                false, "Foo");
+        decl.register(new AstObserverAdapter() {
+            @Override
+            public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add("property " + property.name() + " is changed to " + newValue);
+            }
+        });
+        decl.addModifier(Modifier.PUBLIC);
+        assertEquals(1, changes.size());
+        assertEquals("property MODIFIERS is changed to [PUBLIC]", changes.get(0));
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalScopeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalScopeTest.java
new file mode 100644
index 0000000..ad7e8bd
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithOptionalScopeTest.java
@@ -0,0 +1,28 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.expr.*;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class NodeWithOptionalScopeTest {
+
+    @Test
+    public void commonExpressionWhichHaveInterfaceNodeWithOptionalScope() {
+        NodeWithOptionalScope methodCallExpr = new MethodCallExpr(new NameExpr("A"), "call");
+        NodeWithOptionalScope objectCreationExpr = new ObjectCreationExpr();
+
+        assertTrue(methodCallExpr.getScope().isPresent());
+        assertFalse(objectCreationExpr.getScope().isPresent());
+    }
+
+    @Test
+    public void removeScope() {
+        MethodCallExpr methodCallExpr = new MethodCallExpr(new NameExpr("A"), "method");
+
+        methodCallExpr.removeScope();
+
+        assertFalse(methodCallExpr.getScope().isPresent());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithTraversableScopeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithTraversableScopeTest.java
new file mode 100644
index 0000000..59aaf4e
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithTraversableScopeTest.java
@@ -0,0 +1,23 @@
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+import static com.github.javaparser.utils.TestUtils.assertInstanceOf;
+import static org.junit.Assert.assertFalse;
+
+public class NodeWithTraversableScopeTest {
+    @Test
+    public void traverse1() {
+        NodeWithTraversableScope expression = parseExpression("getAddress().name.startsWith(\"abc\")");
+
+        assertInstanceOf(MethodCallExpr.class, expression);
+        expression = (NodeWithTraversableScope) expression.traverseScope().get();
+        assertInstanceOf(FieldAccessExpr.class, expression);
+        expression = (NodeWithTraversableScope) expression.traverseScope().get();
+        assertInstanceOf(MethodCallExpr.class, expression);
+        assertFalse(expression.traverseScope().isPresent());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithVariablesTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithVariablesTest.java
new file mode 100644
index 0000000..b736333
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/nodeTypes/NodeWithVariablesTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.nodeTypes;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.type.PrimitiveType;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.*;
+import static org.junit.Assert.assertEquals;
+
+public class NodeWithVariablesTest {
+
+    @Test
+    public void getCommonTypeWorksForNormalVariables() {
+        VariableDeclarationExpr declaration = parseVariableDeclarationExpr("int a,b");
+        assertEquals(PrimitiveType.intType(), declaration.getCommonType());
+    }
+
+    @Test
+    public void getCommonTypeWorksForArrayTypes() {
+        parseVariableDeclarationExpr("int a[],b[]").getCommonType();
+    }
+
+    @Test(expected = AssertionError.class)
+    public void getCommonTypeFailsOnArrayDifferences() {
+        parseVariableDeclarationExpr("int a[],b[][]").getCommonType();
+    }
+
+    @Test(expected = AssertionError.class)
+    public void getCommonTypeFailsOnDodgySetterUsage() {
+        VariableDeclarationExpr declaration = parseVariableDeclarationExpr("int a,b");
+        declaration.getVariable(1).setType(String.class);
+        declaration.getCommonType();
+    }
+
+    @Test(expected = AssertionError.class)
+    public void getCommonTypeFailsOnInvalidEmptyVariableList() {
+        VariableDeclarationExpr declaration = parseVariableDeclarationExpr("int a");
+        declaration.getVariables().clear();
+        declaration.getCommonType();
+    }
+
+    @Test
+    public void getElementTypeWorksForNormalVariables() {
+        VariableDeclarationExpr declaration = parseVariableDeclarationExpr("int a,b");
+        assertEquals(PrimitiveType.intType(), declaration.getElementType());
+    }
+
+    @Test
+    public void getElementTypeWorksForArrayTypes() {
+        VariableDeclarationExpr declaration = parseVariableDeclarationExpr("int a[],b[]");
+        assertEquals(PrimitiveType.intType(), declaration.getElementType());
+    }
+
+    @Test
+    public void getElementTypeIsOkayWithArrayDifferences() {
+        parseVariableDeclarationExpr("int a[],b[][]").getElementType();
+    }
+
+    @Test(expected = AssertionError.class)
+    public void getElementTypeFailsOnDodgySetterUsage() {
+        VariableDeclarationExpr declaration = parseVariableDeclarationExpr("int a,b");
+        declaration.getVariable(1).setType(String.class);
+        declaration.getElementType();
+    }
+
+    @Test(expected = AssertionError.class)
+    public void getElementTypeFailsOnInvalidEmptyVariableList() {
+        VariableDeclarationExpr declaration = parseVariableDeclarationExpr("int a");
+        declaration.getVariables().clear();
+        declaration.getElementType();
+    }
+
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/observer/PropagatingAstObserverTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/observer/PropagatingAstObserverTest.java
new file mode 100644
index 0000000..b590f32
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/observer/PropagatingAstObserverTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.observer;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class PropagatingAstObserverTest {
+    @Test
+    public void verifyPropagation() {
+        String code = "class A {  }";
+        CompilationUnit cu = JavaParser.parse(code);
+        List<String> changes = new ArrayList<>();
+        AstObserver observer = new PropagatingAstObserver() {
+            @Override
+            public void concretePropertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) {
+                changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue));
+            }
+        };
+        cu.registerForSubtree(observer);
+
+        assertEquals(Arrays.asList(), changes);
+
+        FieldDeclaration fieldDeclaration = cu.getClassByName("A").get().addField("String", "foo");
+        assertEquals(Arrays.asList(), changes);
+        assertEquals(true, fieldDeclaration.isRegistered(observer));
+
+        cu.getClassByName("A").get().getFieldByName("foo").get().getVariables().get(0).setName("Bar");
+        assertEquals(Arrays.asList("VariableDeclarator.name changed from foo to Bar"), changes);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/BlockStmtTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/BlockStmtTest.java
new file mode 100644
index 0000000..5e5976a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/BlockStmtTest.java
@@ -0,0 +1,21 @@
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import org.junit.Test;
+
+public class BlockStmtTest {
+    @Test
+    public void issue748AddingIdenticalStatementsDoesParentingRight() {
+        BlockStmt blockStmt = new BlockStmt();
+        Expression exp = new NameExpr("x");
+        MethodCallExpr expression = new MethodCallExpr(exp, "y");
+
+        blockStmt.addStatement(expression);
+        blockStmt.addStatement(expression.clone());
+        // This fails when the issue exists:
+        String s = blockStmt.toString();
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/IfElseStmtTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/IfElseStmtTest.java
new file mode 100644
index 0000000..5775bd0
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/IfElseStmtTest.java
@@ -0,0 +1,37 @@
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class IfElseStmtTest {
+
+    @Test
+    public void issue1247withElseSingleStmt() {
+        IfStmt ifStmt = (IfStmt) JavaParser.parseStatement("if (cond) doSomething(); else doSomethingElse();");
+        assertEquals(false, ifStmt.hasElseBlock());
+        assertEquals(true, ifStmt.hasElseBranch());
+        assertEquals(false, ifStmt.hasCascadingIfStmt());
+    }
+
+    @Test
+    public void issue1247withElseBlockStmt() {
+        IfStmt ifStmt = (IfStmt) JavaParser.parseStatement("if (cond) doSomething(); else { doSomethingElse(); }");
+        assertEquals(true, ifStmt.hasElseBlock());
+        assertEquals(true, ifStmt.hasElseBranch());
+        assertEquals(false, ifStmt.hasCascadingIfStmt());
+    }
+
+    @Test
+    public void issue1247withElseSingleStmtWhichIsAnIf() {
+        IfStmt ifStmt = (IfStmt) JavaParser.parseStatement("if (cond1) doSomething(); else if (cond2) doSomethingElse();");
+        assertEquals(false, ifStmt.hasElseBlock());
+        assertEquals(true, ifStmt.hasElseBranch());
+        assertEquals(true, ifStmt.hasCascadingIfStmt());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/TryStmtTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/TryStmtTest.java
new file mode 100644
index 0000000..1a63b21
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/stmt/TryStmtTest.java
@@ -0,0 +1,81 @@
+package com.github.javaparser.ast.stmt;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParseStart;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.validator.Java9Validator;
+import org.junit.Test;
+
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertInstanceOf;
+import static org.junit.Assert.assertTrue;
+
+public class TryStmtTest {
+    @Test
+    public void simpleTest() {
+        TryStmt tryStmt = parse9("try(Reader x = new FileReader()){}");
+        assertInstanceOf(VariableDeclarationExpr.class, tryStmt.getResources().get(0));
+    }
+
+    @Test
+    public void multipleTest() {
+        TryStmt tryStmt = parse9("try(Reader x = new FileReader(); Reader x = new FileReader()){}");
+        assertInstanceOf(VariableDeclarationExpr.class, tryStmt.getResources().get(0));
+
+    }
+
+    @Test
+    public void modifiersTest() {
+        TryStmt tryStmt = parse9("try(final @A Reader x = new FileReader()){}");
+        assertInstanceOf(VariableDeclarationExpr.class, tryStmt.getResources().get(0));
+
+    }
+
+    @Test
+    public void simpleVariable() {
+        TryStmt tryStmt = parse9("try(a){}");
+        assertInstanceOf(NameExpr.class, tryStmt.getResources().get(0));
+
+    }
+
+    @Test
+    public void twoSimpleVariables() {
+        TryStmt tryStmt = parse9("try(a;b){}");
+        assertInstanceOf(NameExpr.class, tryStmt.getResources().get(0));
+        assertInstanceOf(NameExpr.class, tryStmt.getResources().get(1));
+
+    }
+
+    @Test
+    public void complexVariable() {
+        TryStmt tryStmt = parse9("try(a.b.c){}");
+        assertInstanceOf(FieldAccessExpr.class, tryStmt.getResources().get(0));
+
+    }
+
+    @Test
+    public void superAccess() {
+        TryStmt tryStmt = parse9("try(super.a){}");
+        assertInstanceOf(FieldAccessExpr.class, tryStmt.getResources().get(0));
+
+    }
+
+    @Test
+    public void outerClassAccess() {
+        TryStmt tryStmt = parse9("try(X.this.a){}");
+        assertInstanceOf(FieldAccessExpr.class, tryStmt.getResources().get(0));
+
+    }
+
+    private <T> T parse9(String code) {
+        JavaParser parser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_9));
+        ParseResult<Statement> result = parser.parse(ParseStart.STATEMENT, provider(code));
+        assertTrue(result.toString(), result.isSuccessful());
+        return (T) result.getResult().get();
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/type/ArrayTypeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/type/ArrayTypeTest.java
new file mode 100644
index 0000000..3fdee8e
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/type/ArrayTypeTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import org.assertj.core.api.Assertions;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+
+public class ArrayTypeTest {
+    @Test
+    public void getFieldDeclarationWithArrays() {
+        FieldDeclaration fieldDeclaration = parseBodyDeclaration("@C int @A[] @B[] a @X[] @Y[];").asFieldDeclaration();
+
+        ArrayType arrayType1 = fieldDeclaration.getVariable(0).getType().asArrayType();
+        ArrayType arrayType2 = arrayType1.getComponentType().asArrayType();
+        ArrayType arrayType3 = arrayType2.getComponentType().asArrayType();
+        ArrayType arrayType4 = arrayType3.getComponentType().asArrayType();
+        PrimitiveType elementType = arrayType4.getComponentType().asPrimitiveType();
+
+        assertThat(arrayType1.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("A")));
+        assertThat(arrayType2.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("B")));
+        assertThat(arrayType3.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("X")));
+        assertThat(arrayType4.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("Y")));
+
+        assertThat(elementType.getType()).isEqualTo(PrimitiveType.Primitive.INT);
+        assertThat(fieldDeclaration.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("C")));
+
+        assertThat(arrayType1.getParentNode().get().getParentNode().get()).isSameAs(fieldDeclaration);
+    }
+
+    @Test
+    public void getVariableDeclarationWithArrays() {
+        ExpressionStmt variableDeclarationStatement = parseStatement("@C int @A[] @B[] a @X[] @Y[];").asExpressionStmt();
+        VariableDeclarationExpr variableDeclarationExpr = variableDeclarationStatement.getExpression().asVariableDeclarationExpr();
+
+        ArrayType arrayType1 = variableDeclarationExpr.getVariable(0).getType().asArrayType();
+        ArrayType arrayType2 = arrayType1.getComponentType().asArrayType();
+        ArrayType arrayType3 = arrayType2.getComponentType().asArrayType();
+        ArrayType arrayType4 = arrayType3.getComponentType().asArrayType();
+        PrimitiveType elementType = arrayType4.getComponentType().asPrimitiveType();
+
+        assertThat(arrayType1.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("A")));
+        assertThat(arrayType2.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("B")));
+        assertThat(arrayType3.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("X")));
+        assertThat(arrayType4.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("Y")));
+
+        assertThat(elementType.getType()).isEqualTo(PrimitiveType.Primitive.INT);
+        assertThat(variableDeclarationExpr.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("C")));
+
+        assertThat(arrayType1.getParentNode().get().getParentNode().get()).isSameAs(variableDeclarationExpr);
+    }
+
+    @Test
+    public void getMethodDeclarationWithArrays() {
+        MethodDeclaration methodDeclaration = parseBodyDeclaration("@C int @A[] a() @B[] {}").asMethodDeclaration();
+
+        ArrayType arrayType1 = methodDeclaration.getType().asArrayType();
+        ArrayType arrayType2 = arrayType1.getComponentType().asArrayType();
+        Type elementType = arrayType2.getComponentType();
+        assertThat(elementType).isInstanceOf(PrimitiveType.class);
+
+        assertThat(arrayType1.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("A")));
+        assertThat(arrayType2.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("B")));
+        assertThat(methodDeclaration.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("C")));
+
+        assertThat(methodDeclaration.getType().getParentNode().get()).isSameAs(methodDeclaration);
+    }
+
+    @Test
+    public void getParameterWithArrays() {
+        MethodDeclaration methodDeclaration = parseBodyDeclaration("void a(@C int @A[] a @B[]) {}").asMethodDeclaration();
+
+        Parameter parameter = methodDeclaration.getParameter(0);
+
+        ArrayType outerArrayType = parameter.getType().asArrayType();
+
+        ArrayType innerArrayType = outerArrayType.getComponentType().asArrayType();
+        PrimitiveType elementType = innerArrayType.getComponentType().asPrimitiveType();
+
+        assertThat(elementType).isInstanceOf(PrimitiveType.class);
+        assertThat(outerArrayType.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("A")));
+        assertThat(innerArrayType.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("B")));
+        assertThat(parameter.getAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("C")));
+
+        assertThat(parameter.getType().getParentNode().get()).isSameAs(parameter);
+    }
+
+    @Test
+    public void setVariableDeclarationWithArrays() {
+        ExpressionStmt variableDeclarationStatement = parseStatement("@C int @A[] @B[] a @X[] @Y[];").asExpressionStmt();
+        VariableDeclarationExpr variableDeclarationExpr = variableDeclarationStatement.getExpression().asVariableDeclarationExpr();
+
+        variableDeclarationExpr.getVariable(0).setType(new ArrayType(new ArrayType(PrimitiveType.intType())));
+        assertEquals("@C int[][] a;", variableDeclarationStatement.toString());
+    }
+
+    @Test
+    public void setFieldDeclarationWithArrays() {
+        FieldDeclaration fieldDeclaration = parseBodyDeclaration("int[][] a[][];").asFieldDeclaration();
+        fieldDeclaration.getVariable(0).setType(new ArrayType(new ArrayType(parseClassOrInterfaceType("Blob"))));
+
+        assertEquals("Blob[][] a;", fieldDeclaration.toString());
+    }
+
+    @Test
+    public void setMethodDeclarationWithArrays() {
+        MethodDeclaration method = parseBodyDeclaration("int[][] a()[][] {}").asMethodDeclaration();
+        method.setType(new ArrayType(new ArrayType(parseClassOrInterfaceType("Blob"))));
+
+        assertEquals("Blob[][] a() {" + EOL + "}", method.toString());
+    }
+
+    @Test
+    public void fieldDeclarationWithArraysHasCorrectOrigins() {
+        FieldDeclaration fieldDeclaration = parseBodyDeclaration("int[] a[];").asFieldDeclaration();
+
+        Type outerType = fieldDeclaration.getVariables().get(0).getType();
+        assertEquals(ArrayType.Origin.TYPE, outerType.asArrayType().getOrigin());
+        assertEquals(ArrayType.Origin.NAME, outerType.asArrayType().getComponentType().asArrayType().getOrigin());
+    }
+
+    @Test
+    public void methodDeclarationWithArraysHasCorrectOrigins() {
+        MethodDeclaration method = (MethodDeclaration) parseBodyDeclaration("int[] a()[] {}");
+
+        Type outerType = method.getType();
+        assertEquals(ArrayType.Origin.TYPE, outerType.asArrayType().getOrigin());
+        assertEquals(ArrayType.Origin.NAME, outerType.asArrayType().getComponentType().asArrayType().getOrigin());
+    }
+
+    @Test
+    public void setParameterWithArrays() {
+        MethodDeclaration method = parseBodyDeclaration("void a(int[][] a[][]) {}").asMethodDeclaration();
+        method.getParameter(0).setType(new ArrayType(new ArrayType(parseClassOrInterfaceType("Blob"))));
+
+        assertEquals("void a(Blob[][] a) {" + EOL + "}", method.toString());
+    }
+
+    @Test
+    public void getArrayCreationType() {
+        ArrayCreationExpr expr = parseExpression("new int[]");
+        ArrayType outerType = expr.createdType().asArrayType();
+        Type innerType = outerType.getComponentType();
+        assertThat(innerType).isEqualTo(expr.getElementType());
+    }
+    
+    @Test
+    public void ellipsisCanHaveAnnotationsToo() {
+        Parameter p = parseParameter("int[]@X...a[]");
+
+        assertThat(p.getVarArgsAnnotations()).containsExactly(new MarkerAnnotationExpr(parseName("X")));
+        assertEquals("int[][]@X ... a", p.toString());
+        assertEquals("int[][]@X... a", ConcreteSyntaxModel.genericPrettyPrint(p));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/type/TypeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/type/TypeTest.java
new file mode 100644
index 0000000..17244f3
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/type/TypeTest.java
@@ -0,0 +1,68 @@
+package com.github.javaparser.ast.type;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseProblemException;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.validator.Java5Validator;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseType;
+import static com.github.javaparser.JavaParser.parseVariableDeclarationExpr;
+import static com.github.javaparser.ParseStart.VARIABLE_DECLARATION_EXPR;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static org.junit.Assert.*;
+
+public class TypeTest {
+    @Test
+    public void asString() {
+        assertEquals("int", typeAsString("int x"));
+        assertEquals("List<Long>", typeAsString("List<Long> x"));
+        assertEquals("String", typeAsString("@A String x"));
+        assertEquals("List<? extends Object>", typeAsString("List<? extends Object> x"));
+    }
+
+    @Test(expected = ParseProblemException.class)
+    public void primitiveTypeArgumentDefaultValidator() {
+        typeAsString("List<long> x;");
+    }
+
+    @Test
+    public void primitiveTypeArgumentLenientValidator() {
+        ParserConfiguration config = new ParserConfiguration()
+                .setLanguageLevel(RAW);
+        config.getPostProcessors().add(new Java5Validator() {{
+            remove(noPrimitiveGenericArguments);
+        }}.postProcessor());
+
+        ParseResult<VariableDeclarationExpr> result = new JavaParser(config).parse(
+                VARIABLE_DECLARATION_EXPR, provider("List<long> x"));
+        assertTrue(result.isSuccessful());
+
+        VariableDeclarationExpr decl = result.getResult().get();
+        assertEquals("List<long>", decl.getVariable(0).getType().asString());
+    }
+
+    private String typeAsString(String s) {
+        return parseVariableDeclarationExpr(s).getVariable(0).getType().asString();
+    }
+
+    @Test
+    public void arrayType() {
+        Type type = parseType("int[]");
+        assertTrue(type.isArrayType());
+        ArrayType arrayType = type.asArrayType();
+        final ArrayType[] s = new ArrayType[1];
+        type.ifArrayType(t -> s[0] = t);
+        assertNotNull(s[0]);
+    }
+
+    @Test
+    public void issue1251() {
+        final Type type = parseType("TypeUtilsTest<String>.Tester");
+        assertEquals("TypeUtilsTest<String>.Tester", type.toString());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java10ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java10ValidatorTest.java
new file mode 100644
index 0000000..8c2b935
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java10ValidatorTest.java
@@ -0,0 +1,108 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.CLASS_BODY;
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_10;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java10ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_10));
+
+    @Test
+    public void varAllowedInLocalVariableDeclaration() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var a = 5;"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void varAllowedInForEach() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("for(var a : as){}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void varAllowedInOldFor() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("for(var a = 5;a<9;a++){}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void varNotAllowedInCast() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("int a = (var)20;"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void varNotAllowedInTryWithResources() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try(var f = new FileReader(\"\")){ }catch (Exception e){ }"));
+        assertProblems(result, "(line 1,col 5) \"var\" is not allowed here.");
+    }
+
+    @Test
+    public void varNotAllowedInField() {
+        ParseResult<BodyDeclaration<?>> result = javaParser.parse(CLASS_BODY, provider("var a = 20;"));
+        assertProblems(result, "(line 1,col 1) \"var\" is not allowed here.");
+    }
+
+    @Test
+    public void varNotAllowedInTypeArguments() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("new X<var>();"));
+        assertProblems(result, "(line 1,col 7) \"var\" is not allowed here.");
+    }
+
+    @Test
+    public void varNotAllowedInLambdaParameters() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("x((var x) -> null);"));
+        assertProblems(result, "(line 1,col 4) \"var\" is not allowed here.");
+    }
+
+    @Test
+    public void emptyInitializerNotAllowed() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var a;"));
+        assertProblems(result, "(line 1,col 1) \"var\" needs an initializer.");
+    }
+
+    @Test
+    public void multipleVariablesNotAllowed() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var a=1, b=2;"));
+        assertProblems(result, "(line 1,col 1) \"var\" only takes a single variable.");
+    }
+
+    @Test
+    public void nullVariablesNotAllowed() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var a=null;"));
+        assertProblems(result, "(line 1,col 1) \"var\" cannot infer type from just null.");
+    }
+
+    @Test
+    public void arrayDimensionBracketsNotAllowed() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var a=new String[]{};"));
+        assertProblems(result, "(line 1,col 1) \"var\" cannot infer array types.");
+    }
+
+    // This is pretty hard to impossible to implement correctly with just the AST.
+    @Ignore
+    @Test
+    public void selfReferenceNotAllowed() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var a=a;"));
+        assertProblems(result, "");
+    }
+
+    // Can be implemented once https://github.com/javaparser/javaparser/issues/1434 is implemented.
+    @Ignore
+    @Test
+    public void polyExpressionAsInitializerNotAllowed() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var a=new ArrayList<>();"));
+        assertProblems(result, "");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java11ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java11ValidatorTest.java
new file mode 100644
index 0000000..1e1f8c0
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java11ValidatorTest.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_11_PREVIEW;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+
+public class Java11ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_11_PREVIEW));
+
+    @Test
+    public void varAllowedInLocalVariableDeclaration() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("x((var x, var y) -> x+y);"));
+        assertNoProblems(result);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_0ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_0ValidatorTest.java
new file mode 100644
index 0000000..7160bcf
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_0ValidatorTest.java
@@ -0,0 +1,98 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.Problem;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.PrimitiveType;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.github.javaparser.ParseStart.*;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+import static org.junit.Assert.assertEquals;
+
+public class Java1_0ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_1_0));
+
+    @Test
+    public void tryWithoutResources() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try(X x=new Y()){}"));
+        assertProblems(result,
+                "(line 1,col 1) Catch with resource is not supported.",
+                "(line 1,col 1) Try has no finally and no catch.");
+    }
+
+    @Test
+    public void classExtendingMoreThanOne() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X extends Y, Z {}"));
+        assertProblems(result, "(line 1,col 20) A class cannot extend more than one other class.");
+    }
+
+    @Test
+    public void interfaceUsingImplements() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X implements Y {}"));
+        assertProblems(result, "(line 1,col 24) An interface cannot implement other interfaces.");
+    }
+
+    @Test
+    public void interfaceWithInitializer() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X {{}}"));
+        assertProblems(result, "(line 1,col 14) An interface cannot have initializers.");
+    }
+
+    @Test
+    public void defaultInClass() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X {default void a(){};}"));
+        assertProblems(result, "(line 1,col 10) 'default' is not allowed here.");
+    }
+
+    @Test
+    public void leftHandAssignmentCannotBeAConditional() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("(1==2)=3"));
+        assertProblems(result, "(line 1,col 1) Illegal left hand side of an assignment.");
+    }
+
+    @Test
+    public void leftHandAssignmentCannotBeEmptyBraces() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("()=3"));
+        assertProblems(result,
+                "(line 1,col 1) Illegal left hand side of an assignment.",
+                "(line 1,col 1) Lambdas are not supported.");
+    }
+
+    @Test
+    public void leftHandAssignmentCanBeInBraces() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("(i) += (i) += 1"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void noInnerClasses() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{class Y{}}"));
+        assertProblems(result, "(line 1,col 9) inner classes or interfaces are not supported.");
+    }
+
+    @Test
+    public void noReflection() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("Abc.class"));
+        assertProblems(result, "(line 1,col 1) Reflection is not supported.");
+    }
+
+    @Test
+    public void nonEmptyList() {
+        ArrayCreationExpr expr = new ArrayCreationExpr(PrimitiveType.booleanType());
+        List<Problem> problems= new ArrayList<>();
+        new Java1_0Validator().accept(expr, new ProblemReporter(problems::add));
+        assertEquals("ArrayCreationExpr.levels can not be empty.", problems.get(0).getMessage());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_1ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_1ValidatorTest.java
new file mode 100644
index 0000000..6331d9a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_1ValidatorTest.java
@@ -0,0 +1,292 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.ParseStart.EXPRESSION;
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java1_1ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_1_1));
+
+    public static final String allModifiers = "public protected private abstract static final transient volatile synchronized native strictfp transitive default ";
+
+    @Test
+    public void topClass() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider(allModifiers + "class X{}"));
+        assertProblems(result,
+                "(line 1,col 1) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 1) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 1) 'transient' is not allowed here.",
+                "(line 1,col 1) 'default' is not allowed here.",
+                "(line 1,col 1) 'volatile' is not allowed here.",
+                "(line 1,col 1) 'strictfp' is not allowed here.",
+                "(line 1,col 1) 'private' is not allowed here.",
+                "(line 1,col 1) 'protected' is not allowed here.",
+                "(line 1,col 1) 'synchronized' is not allowed here.",
+                "(line 1,col 1) 'native' is not allowed here.",
+                "(line 1,col 1) 'transitive' is not allowed here.",
+                "(line 1,col 1) 'static' is not allowed here."
+        );
+    }
+
+    @Test
+    public void nestedClass() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "class I{}}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void localClass() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{ void x() {" + allModifiers + "class I{}}}"));
+        assertProblems(result,
+                "(line 1,col 20) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 20) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 20) 'transient' is not allowed here.",
+                "(line 1,col 20) 'volatile' is not allowed here.",
+                "(line 1,col 20) 'default' is not allowed here.",
+                "(line 1,col 20) 'synchronized' is not allowed here.",
+                "(line 1,col 20) 'native' is not allowed here.",
+                "(line 1,col 20) 'transitive' is not allowed here.",
+                "(line 1,col 20) 'strictfp' is not allowed here.",
+                "(line 1,col 20) 'static' is not allowed here.",
+                "(line 1,col 20) 'public' is not allowed here.",
+                "(line 1,col 20) 'private' is not allowed here.",
+                "(line 1,col 20) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void topInterface() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider(allModifiers + "interface X{}"));
+        assertProblems(result,
+                "(line 1,col 1) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 1) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 1) 'transient' is not allowed here.",
+                "(line 1,col 1) 'volatile' is not allowed here.",
+                "(line 1,col 1) 'default' is not allowed here.",
+                "(line 1,col 1) 'strictfp' is not allowed here.",
+                "(line 1,col 1) 'synchronized' is not allowed here.",
+                "(line 1,col 1) 'native' is not allowed here.",
+                "(line 1,col 1) 'transitive' is not allowed here.",
+                "(line 1,col 1) 'static' is not allowed here.",
+                "(line 1,col 1) 'final' is not allowed here.",
+                "(line 1,col 1) 'private' is not allowed here.",
+                "(line 1,col 1) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void nestedInterface() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "interface I{}}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'final' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void constructor() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "X(){};}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'final' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'abstract' is not allowed here.",
+                "(line 1,col 9) 'static' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void constructorParameter() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{X(" + allModifiers + " int i){};}"));
+        assertProblems(result,
+                "(line 1,col 11) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 11) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 11) 'transient' is not allowed here.",
+                "(line 1,col 11) 'volatile' is not allowed here.",
+                "(line 1,col 11) 'synchronized' is not allowed here.",
+                "(line 1,col 11) 'native' is not allowed here.",
+                "(line 1,col 11) 'strictfp' is not allowed here.",
+                "(line 1,col 11) 'default' is not allowed here.",
+                "(line 1,col 11) 'abstract' is not allowed here.",
+                "(line 1,col 11) 'static' is not allowed here.",
+                "(line 1,col 11) 'transitive' is not allowed here.",
+                "(line 1,col 11) 'private' is not allowed here.",
+                "(line 1,col 11) 'public' is not allowed here.",
+                "(line 1,col 11) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void classMethod() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "int x(){};}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Cannot be 'abstract' and also 'private', 'static', 'final', 'native', 'strictfp', 'synchronized'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void interfaceMethod() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X{" + allModifiers + "int x(){};}"));
+        assertProblems(result,
+                "(line 1,col 13) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 13) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 13) Cannot be 'abstract' and also 'private', 'static', 'final', 'native', 'strictfp', 'synchronized'.",
+                "(line 1,col 13) 'transient' is not allowed here.",
+                "(line 1,col 13) 'strictfp' is not allowed here.",
+                "(line 1,col 13) 'volatile' is not allowed here.",
+                "(line 1,col 13) 'default' is not allowed here.",
+                "(line 1,col 13) 'transitive' is not allowed here.",
+                "(line 1,col 13) 'private' is not allowed here.",
+                "(line 1,col 13) 'static' is not allowed here."
+        );
+    }
+
+    @Test
+    public void methodParameter() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{int x(" + allModifiers + " int i){};}"));
+        assertProblems(result,
+                "(line 1,col 15) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 15) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 15) 'transient' is not allowed here.",
+                "(line 1,col 15) 'volatile' is not allowed here.",
+                "(line 1,col 15) 'synchronized' is not allowed here.",
+                "(line 1,col 15) 'native' is not allowed here.",
+                "(line 1,col 15) 'strictfp' is not allowed here.",
+                "(line 1,col 15) 'abstract' is not allowed here.",
+                "(line 1,col 15) 'default' is not allowed here.",
+                "(line 1,col 15) 'static' is not allowed here.",
+                "(line 1,col 15) 'transitive' is not allowed here.",
+                "(line 1,col 15) 'private' is not allowed here.",
+                "(line 1,col 15) 'public' is not allowed here.",
+                "(line 1,col 15) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void field() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "int i;}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'abstract' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void localVariable() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{int x(){" + allModifiers + "int i;}}"));
+        assertProblems(result,
+                "(line 1,col 17) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 17) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 17) 'transient' is not allowed here.",
+                "(line 1,col 17) 'volatile' is not allowed here.",
+                "(line 1,col 17) 'synchronized' is not allowed here.",
+                "(line 1,col 17) 'native' is not allowed here.",
+                "(line 1,col 17) 'default' is not allowed here.",
+                "(line 1,col 17) 'strictfp' is not allowed here.",
+                "(line 1,col 17) 'abstract' is not allowed here.",
+                "(line 1,col 17) 'static' is not allowed here.",
+                "(line 1,col 17) 'transitive' is not allowed here.",
+                "(line 1,col 17) 'private' is not allowed here.",
+                "(line 1,col 17) 'public' is not allowed here.",
+                "(line 1,col 17) 'protected' is not allowed here."
+        );
+    }
+
+
+    @Test
+    public void catchParameter() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{int x(){ try{}catch(" + allModifiers + " Integer x){}}}"));
+        assertProblems(result,
+                "(line 1,col 144) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 144) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 144) 'transient' is not allowed here.",
+                "(line 1,col 144) 'volatile' is not allowed here.",
+                "(line 1,col 144) 'synchronized' is not allowed here.",
+                "(line 1,col 144) 'native' is not allowed here.",
+                "(line 1,col 144) 'default' is not allowed here.",
+                "(line 1,col 144) 'strictfp' is not allowed here.",
+                "(line 1,col 144) 'abstract' is not allowed here.",
+                "(line 1,col 144) 'static' is not allowed here.",
+                "(line 1,col 144) 'transitive' is not allowed here.",
+                "(line 1,col 144) 'private' is not allowed here.",
+                "(line 1,col 144) 'public' is not allowed here.",
+                "(line 1,col 144) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void innerClasses() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{class Y{}}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void localInterface() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{ void x() {" + allModifiers + "interface I{}}}"));
+        assertProblems(result, "(line 1,col 20) There is no such thing as a local interface."
+        );
+    }
+
+    @Test
+    public void reflection() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("Abc.class"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void strictfpAllowedAsIdentifier() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("int strictfp;"));
+        assertNoProblems(result);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_2ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_2ValidatorTest.java
new file mode 100644
index 0000000..3ae7018
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_2ValidatorTest.java
@@ -0,0 +1,275 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java1_2ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_1_2));
+
+    private final String allModifiers = "public protected private abstract static final transient volatile synchronized native strictfp transitive default ";
+
+    @Test
+    public void topClass() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider(allModifiers + "class X{}"));
+        assertProblems(result,
+                "(line 1,col 1) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 1) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 1) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 1) 'transient' is not allowed here.",
+                "(line 1,col 1) 'default' is not allowed here.",
+                "(line 1,col 1) 'volatile' is not allowed here.",
+                "(line 1,col 1) 'private' is not allowed here.",
+                "(line 1,col 1) 'protected' is not allowed here.",
+                "(line 1,col 1) 'synchronized' is not allowed here.",
+                "(line 1,col 1) 'native' is not allowed here.",
+                "(line 1,col 1) 'transitive' is not allowed here.",
+                "(line 1,col 1) 'static' is not allowed here."
+        );
+    }
+
+    @Test
+    public void nestedClass() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "class I{}}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void localClass() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{ void x() {" + allModifiers + "class I{}}}"));
+        assertProblems(result,
+                "(line 1,col 20) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 20) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 20) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 20) 'transient' is not allowed here.",
+                "(line 1,col 20) 'volatile' is not allowed here.",
+                "(line 1,col 20) 'default' is not allowed here.",
+                "(line 1,col 20) 'synchronized' is not allowed here.",
+                "(line 1,col 20) 'native' is not allowed here.",
+                "(line 1,col 20) 'transitive' is not allowed here.",
+                "(line 1,col 20) 'static' is not allowed here.",
+                "(line 1,col 20) 'public' is not allowed here.",
+                "(line 1,col 20) 'private' is not allowed here.",
+                "(line 1,col 20) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void topInterface() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider(allModifiers + "interface X{}"));
+        assertProblems(result,
+                "(line 1,col 1) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 1) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 1) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 1) 'transient' is not allowed here.",
+                "(line 1,col 1) 'volatile' is not allowed here.",
+                "(line 1,col 1) 'default' is not allowed here.",
+                "(line 1,col 1) 'synchronized' is not allowed here.",
+                "(line 1,col 1) 'native' is not allowed here.",
+                "(line 1,col 1) 'transitive' is not allowed here.",
+                "(line 1,col 1) 'static' is not allowed here.",
+                "(line 1,col 1) 'final' is not allowed here.",
+                "(line 1,col 1) 'private' is not allowed here.",
+                "(line 1,col 1) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void nestedInterface() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "interface I{}}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'final' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void constructor() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "X(){};}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'final' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'abstract' is not allowed here.",
+                "(line 1,col 9) 'static' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void constructorParameter() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{X(" + allModifiers + " int i){};}"));
+        assertProblems(result,
+                "(line 1,col 11) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 11) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 11) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 11) 'transient' is not allowed here.",
+                "(line 1,col 11) 'volatile' is not allowed here.",
+                "(line 1,col 11) 'synchronized' is not allowed here.",
+                "(line 1,col 11) 'native' is not allowed here.",
+                "(line 1,col 11) 'strictfp' is not allowed here.",
+                "(line 1,col 11) 'default' is not allowed here.",
+                "(line 1,col 11) 'abstract' is not allowed here.",
+                "(line 1,col 11) 'static' is not allowed here.",
+                "(line 1,col 11) 'transitive' is not allowed here.",
+                "(line 1,col 11) 'private' is not allowed here.",
+                "(line 1,col 11) 'public' is not allowed here.",
+                "(line 1,col 11) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void classMethod() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "int x(){};}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 9) Cannot be 'abstract' and also 'private', 'static', 'final', 'native', 'strictfp', 'synchronized'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void interfaceMethod() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X{" + allModifiers + "int x(){};}"));
+        assertProblems(result,
+                "(line 1,col 13) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 13) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 13) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 13) Cannot be 'abstract' and also 'private', 'static', 'final', 'native', 'strictfp', 'synchronized'.",
+                "(line 1,col 13) 'transient' is not allowed here.",
+                "(line 1,col 13) 'volatile' is not allowed here.",
+                "(line 1,col 13) 'default' is not allowed here.",
+                "(line 1,col 13) 'transitive' is not allowed here.",
+                "(line 1,col 13) 'private' is not allowed here.",
+                "(line 1,col 13) 'static' is not allowed here."
+        );
+    }
+
+    @Test
+    public void methodParameter() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{int x(" + allModifiers + " int i){};}"));
+        assertProblems(result,
+                "(line 1,col 15) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 15) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 15) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 15) 'transient' is not allowed here.",
+                "(line 1,col 15) 'volatile' is not allowed here.",
+                "(line 1,col 15) 'synchronized' is not allowed here.",
+                "(line 1,col 15) 'native' is not allowed here.",
+                "(line 1,col 15) 'strictfp' is not allowed here.",
+                "(line 1,col 15) 'abstract' is not allowed here.",
+                "(line 1,col 15) 'default' is not allowed here.",
+                "(line 1,col 15) 'static' is not allowed here.",
+                "(line 1,col 15) 'transitive' is not allowed here.",
+                "(line 1,col 15) 'private' is not allowed here.",
+                "(line 1,col 15) 'public' is not allowed here.",
+                "(line 1,col 15) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void field() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "int i;}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'strictfp' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'abstract' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void localVariable() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{int x(){" + allModifiers + "int i;}}"));
+        assertProblems(result,
+                "(line 1,col 17) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 17) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 17) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 17) 'transient' is not allowed here.",
+                "(line 1,col 17) 'volatile' is not allowed here.",
+                "(line 1,col 17) 'synchronized' is not allowed here.",
+                "(line 1,col 17) 'native' is not allowed here.",
+                "(line 1,col 17) 'default' is not allowed here.",
+                "(line 1,col 17) 'strictfp' is not allowed here.",
+                "(line 1,col 17) 'abstract' is not allowed here.",
+                "(line 1,col 17) 'static' is not allowed here.",
+                "(line 1,col 17) 'transitive' is not allowed here.",
+                "(line 1,col 17) 'private' is not allowed here.",
+                "(line 1,col 17) 'public' is not allowed here.",
+                "(line 1,col 17) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void catchParameter() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{int x(){ try{}catch(" + allModifiers + " Integer x){}}}"));
+        assertProblems(result,
+                "(line 1,col 144) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 144) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 144) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 144) 'transient' is not allowed here.",
+                "(line 1,col 144) 'volatile' is not allowed here.",
+                "(line 1,col 144) 'synchronized' is not allowed here.",
+                "(line 1,col 144) 'native' is not allowed here.",
+                "(line 1,col 144) 'default' is not allowed here.",
+                "(line 1,col 144) 'strictfp' is not allowed here.",
+                "(line 1,col 144) 'abstract' is not allowed here.",
+                "(line 1,col 144) 'static' is not allowed here.",
+                "(line 1,col 144) 'transitive' is not allowed here.",
+                "(line 1,col 144) 'private' is not allowed here.",
+                "(line 1,col 144) 'public' is not allowed here.",
+                "(line 1,col 144) 'protected' is not allowed here."
+        );
+    }
+    
+    @Test
+    public void strictfpNotAllowedAsIdentifier() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("int strictfp;"));
+        assertProblems(result, "(line 1,col 5) 'strictfp' cannot be used as an identifier as it is a keyword.");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_3ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_3ValidatorTest.java
new file mode 100644
index 0000000..b10114a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_3ValidatorTest.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java1_3ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_1_3));
+
+    @Test
+    public void noAssert() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("assert a;"));
+        assertProblems(result, "(line 1,col 1) 'assert' keyword is not supported.");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_4ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_4ValidatorTest.java
new file mode 100644
index 0000000..ed0be99
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java1_4ValidatorTest.java
@@ -0,0 +1,70 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.*;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java1_4ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_1_4));
+
+    @Test
+    public void yesAssert() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("assert a;"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void noGenerics() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X<A>{List<String> b;}"));
+        assertProblems(result,
+                "(line 1,col 12) Generics are not supported.",
+                "(line 1,col 1) Generics are not supported."
+        );
+    }
+
+    @Test
+    public void noAnnotations() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("@Abc @Def() @Ghi(a=3) @interface X{}"));
+        assertProblems(result,
+                "(line 1,col 6) Annotations are not supported.",
+                "(line 1,col 13) Annotations are not supported.",
+                "(line 1,col 1) Annotations are not supported."
+        );
+    }
+
+    @Test
+    public void novarargs() {
+        ParseResult<Parameter> result = javaParser.parse(PARAMETER, provider("String... x"));
+        assertProblems(result, "(line 1,col 1) Varargs are not supported.");
+    }
+
+    @Test
+    public void noforeach() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("for(X x: xs){}"));
+        assertProblems(result, "(line 1,col 1) For-each loops are not supported.");
+    }
+
+    @Test
+    public void staticImport() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("import static x;import static x.*;import x.X;import x.*;"));
+        assertProblems(result,
+                "(line 1,col 17) Static imports are not supported.",
+                "(line 1,col 1) Static imports are not supported.");
+    }
+
+    @Test
+    public void enumAllowedAsIdentifier() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("int enum;"));
+        assertNoProblems(result);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java5ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java5ValidatorTest.java
new file mode 100644
index 0000000..315167f
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java5ValidatorTest.java
@@ -0,0 +1,155 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParseStart;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.*;
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.ast.validator.Java1_1ValidatorTest.allModifiers;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java5ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_5));
+
+    @Test
+    public void genericsWithoutDiamond() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X<A>{List<String> b = new ArrayList<>();}"));
+        assertProblems(result, "(line 1,col 33) The diamond operator is not supported.");
+    }
+
+    @Test
+    public void topAnnotationDeclaration() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider(allModifiers + "@interface X{}"));
+        assertProblems(result,
+                "(line 1,col 1) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 1) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 1) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 1) 'transient' is not allowed here.",
+                "(line 1,col 1) 'volatile' is not allowed here.",
+                "(line 1,col 1) 'synchronized' is not allowed here.",
+                "(line 1,col 1) 'default' is not allowed here.",
+                "(line 1,col 1) 'native' is not allowed here.",
+                "(line 1,col 1) 'transitive' is not allowed here.",
+                "(line 1,col 1) 'static' is not allowed here.",
+                "(line 1,col 1) 'final' is not allowed here.",
+                "(line 1,col 1) 'private' is not allowed here.",
+                "(line 1,col 1) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void nestedAnnotationDeclaration() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "@interface I{}}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'final' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void annotationMember() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("@interface X{" + allModifiers + "int x();}"));
+        assertProblems(result,
+                "(line 1,col 14) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 14) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 14) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 14) 'transient' is not allowed here.",
+                "(line 1,col 14) 'volatile' is not allowed here.",
+                "(line 1,col 14) 'final' is not allowed here.",
+                "(line 1,col 14) 'synchronized' is not allowed here.",
+                "(line 1,col 14) 'default' is not allowed here.",
+                "(line 1,col 14) 'native' is not allowed here.",
+                "(line 1,col 14) 'protected' is not allowed here.",
+                "(line 1,col 14) 'private' is not allowed here.",
+                "(line 1,col 14) 'strictfp' is not allowed here.",
+                "(line 1,col 14) 'static' is not allowed here.",
+                "(line 1,col 14) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void topEnum() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider(allModifiers + "enum X{}"));
+        assertProblems(result,
+                "(line 1,col 1) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 1) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 1) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 1) 'transient' is not allowed here.",
+                "(line 1,col 1) 'volatile' is not allowed here.",
+                "(line 1,col 1) 'synchronized' is not allowed here.",
+                "(line 1,col 1) 'default' is not allowed here.",
+                "(line 1,col 1) 'native' is not allowed here.",
+                "(line 1,col 1) 'transitive' is not allowed here.",
+                "(line 1,col 1) 'static' is not allowed here.",
+                "(line 1,col 1) 'abstract' is not allowed here.",
+                "(line 1,col 1) 'final' is not allowed here.",
+                "(line 1,col 1) 'private' is not allowed here.",
+                "(line 1,col 1) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void nestedEnum() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{" + allModifiers + "enum I{}}"));
+        assertProblems(result,
+                "(line 1,col 9) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 9) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 9) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 9) 'transient' is not allowed here.",
+                "(line 1,col 9) 'volatile' is not allowed here.",
+                "(line 1,col 9) 'default' is not allowed here.",
+                "(line 1,col 9) 'abstract' is not allowed here.",
+                "(line 1,col 9) 'final' is not allowed here.",
+                "(line 1,col 9) 'synchronized' is not allowed here.",
+                "(line 1,col 9) 'native' is not allowed here.",
+                "(line 1,col 9) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void varargs() {
+        ParseResult<Parameter> result = javaParser.parse(PARAMETER, provider("String... x"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void foreach() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("for(X x: xs){}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void staticImport() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("import static x;import static x.*;import x.X;import x.*;"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void noPrimitiveTypeArguments() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X extends Y<int> {}"));
+        assertProblems(result, "(line 1,col 17) Type arguments may not be primitive.");
+    }
+
+    @Test
+    public void enumAllowedAsIdentifier() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("int enum;"));
+        assertProblems(result, "(line 1,col 5) 'enum' cannot be used as an identifier as it is a keyword.");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java6ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java6ValidatorTest.java
new file mode 100644
index 0000000..d066abe
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java6ValidatorTest.java
@@ -0,0 +1,42 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.EXPRESSION;
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java6ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_6));
+
+    @Test
+    public void noStringsInSwitch() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("switch(x){case \"abc\": ;}"));
+        assertProblems(result, "(line 1,col 16) Strings in switch statements are not supported.");
+    }
+
+    @Test
+    public void nobinaryIntegerLiterals() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("0b01"));
+        assertProblems(result, "(line 1,col 1) Binary literal values are not supported.");
+    }
+
+    @Test
+    public void noUnderscoresInIntegerLiterals() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("1_000_000"));
+        assertProblems(result, "(line 1,col 1) Underscores in literal values are not supported.");
+    }
+
+    @Test
+    public void noMultiCatch() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try{}catch(Abc|Def e){}"));
+        assertProblems(result, "(line 1,col 12) Multi-catch is not supported.");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java7ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java7ValidatorTest.java
new file mode 100644
index 0000000..a2a03f8
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java7ValidatorTest.java
@@ -0,0 +1,107 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.Problem;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.UnionType;
+import org.junit.Test;
+
+import java.util.*;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.ParseStart.EXPRESSION;
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java7ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_7));
+
+    @Test
+    public void generics() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X<A>{List<String> b = new ArrayList<>();}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void defaultMethodWithoutBody() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X {default void a();}"));
+        assertProblems(result, "(line 1,col 14) 'default' is not allowed here.");
+    }
+
+    @Test
+    public void tryWithoutAnything() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try{}"));
+        assertProblems(result, "(line 1,col 1) Try has no finally, no catch, and no resources.");
+    }
+
+    @Test
+    public void tryWithResourceVariableDeclaration() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try(Reader r = new Reader()){}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void tryWithResourceReference() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try(a.b.c){}"));
+        assertProblems(result, "(line 1,col 1) Try with resources only supports variable declarations.");
+    }
+
+    @Test
+    public void stringsInSwitch() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("switch(x){case \"abc\": ;}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void binaryIntegerLiterals() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("0b01"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void underscoresInIntegerLiterals() {
+        ParseResult<Expression> result = javaParser.parse(EXPRESSION, provider("1_000_000"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void multiCatch() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try{}catch(Abc|Def e){}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void multiCatchWithoutElements() {
+        UnionType unionType = new UnionType();
+
+        List<Problem> problems = new ArrayList<>();
+        new Java7Validator().accept(unionType, new ProblemReporter(problems::add));
+        
+        assertProblems(problems, "UnionType.elements can not be empty.");
+    }
+
+    @Test
+    public void multiCatchWithOneElement() {
+        UnionType unionType = new UnionType();
+        unionType.getElements().add(new ClassOrInterfaceType());
+
+        List<Problem> problems = new ArrayList<>();
+        new Java7Validator().accept(unionType, new ProblemReporter(problems::add));
+        
+        assertProblems(problems, "Union type (multi catch) must have at least two elements.");
+    }
+
+    @Test
+    public void noLambdas() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("a(() -> 1);"));
+        assertProblems(result, "(line 1,col 3) Lambdas are not supported.");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java8ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java8ValidatorTest.java
new file mode 100644
index 0000000..216fb5b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java8ValidatorTest.java
@@ -0,0 +1,82 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.ast.validator.Java1_1ValidatorTest.allModifiers;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java8ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_8));
+
+    @Test
+    public void localInterface() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X {void a(){interface I{}};}"));
+        assertProblems(result, "(line 1,col 19) There is no such thing as a local interface.");
+    }
+
+    @Test
+    public void lambdaParameter() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("class X{int x(){ a((" + allModifiers + " Integer x) -> 10);}}"));
+        assertProblems(result,
+                "(line 1,col 21) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 21) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 21) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 21) 'transient' is not allowed here.",
+                "(line 1,col 21) 'volatile' is not allowed here.",
+                "(line 1,col 21) 'synchronized' is not allowed here.",
+                "(line 1,col 21) 'strictfp' is not allowed here.",
+                "(line 1,col 21) 'default' is not allowed here.",
+                "(line 1,col 21) 'native' is not allowed here.",
+                "(line 1,col 21) 'strictfp' is not allowed here.",
+                "(line 1,col 21) 'abstract' is not allowed here.",
+                "(line 1,col 21) 'static' is not allowed here.",
+                "(line 1,col 21) 'transitive' is not allowed here.",
+                "(line 1,col 21) 'private' is not allowed here.",
+                "(line 1,col 21) 'public' is not allowed here.",
+                "(line 1,col 21) 'protected' is not allowed here."
+        );
+    }
+
+    @Test
+    public void interfaceMethod() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X{" + allModifiers + "int x(){};}"));
+        assertProblems(result,
+                "(line 1,col 13) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 13) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 13) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 13) Cannot be 'abstract' and also 'private', 'static', 'final', 'native', 'strictfp', 'synchronized'.",
+                "(line 1,col 13) 'transient' is not allowed here.",
+                "(line 1,col 13) 'volatile' is not allowed here.",
+                "(line 1,col 13) 'transitive' is not allowed here.",
+                "(line 1,col 13) 'private' is not allowed here."
+        );
+    }
+
+    @Test
+    public void defaultMethodWithoutBody() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X {default void a();}"));
+        assertProblems(result, "(line 1,col 14) 'default' methods must have a body.");
+    }
+
+    @Test
+    public void lambdas() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("a(() -> 1);"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void noModules() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("open module x {}"));
+        assertProblems(result, "(line 1,col 1) Modules are not supported.");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java9ValidatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java9ValidatorTest.java
new file mode 100644
index 0000000..911f6a9
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/validator/Java9ValidatorTest.java
@@ -0,0 +1,79 @@
+package com.github.javaparser.ast.validator;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.Test;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.ast.validator.Java1_1ValidatorTest.allModifiers;
+import static com.github.javaparser.utils.TestUtils.assertNoProblems;
+import static com.github.javaparser.utils.TestUtils.assertProblems;
+
+public class Java9ValidatorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_9));
+
+    @Test
+    public void underscoreIdentifiers() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("a.b._.c.d = act(_, _ -> _);"));
+        assertProblems(result,
+                "(line 1,col 5) '_' is a reserved keyword.",
+                "(line 1,col 17) '_' is a reserved keyword.",
+                "(line 1,col 20) '_' is a reserved keyword.",
+                "(line 1,col 25) '_' is a reserved keyword."
+        );
+    }
+
+    @Test
+    public void moduleRequires() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("module x{requires " + allModifiers + " a;}"));
+        assertProblems(result,
+                "(line 1,col 10) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 10) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 10) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 10) 'transient' is not allowed here.",
+                "(line 1,col 10) 'volatile' is not allowed here.",
+                "(line 1,col 10) 'final' is not allowed here.",
+                "(line 1,col 10) 'synchronized' is not allowed here.",
+                "(line 1,col 10) 'default' is not allowed here.",
+                "(line 1,col 10) 'native' is not allowed here.",
+                "(line 1,col 10) 'private' is not allowed here.",
+                "(line 1,col 10) 'protected' is not allowed here.",
+                "(line 1,col 10) 'strictfp' is not allowed here.",
+                "(line 1,col 10) 'abstract' is not allowed here.",
+                "(line 1,col 10) 'public' is not allowed here."
+        );
+    }
+
+    @Test
+    public void interfaceMethod() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("interface X{" + allModifiers + "int x(){};}"));
+        assertProblems(result,
+                "(line 1,col 13) Can have only one of 'public', 'protected', 'private'.",
+                "(line 1,col 13) Can have only one of 'final', 'abstract'.",
+                "(line 1,col 13) Can have only one of 'native', 'strictfp'.",
+                "(line 1,col 13) Cannot be 'abstract' and also 'private', 'static', 'final', 'native', 'strictfp', 'synchronized'.",
+                "(line 1,col 13) 'transient' is not allowed here.",
+                "(line 1,col 13) 'volatile' is not allowed here.",
+                "(line 1,col 13) 'transitive' is not allowed here."
+        );
+    }
+
+    @Test
+    public void modules() {
+        ParseResult<CompilationUnit> result = javaParser.parse(COMPILATION_UNIT, provider("open module x {}"));
+        assertNoProblems(result);
+    }
+
+    @Test
+    public void tryWithResourceReference() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("try(a.b.c){}"));
+        assertNoProblems(result);
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/CloneVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/CloneVisitorTest.java
new file mode 100644
index 0000000..e596611
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/CloneVisitorTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.type.Type;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Iterator;
+
+import static com.github.javaparser.JavaParser.*;
+import static org.junit.Assert.assertEquals;
+
+public class CloneVisitorTest {
+    CompilationUnit cu;
+
+    @Before
+    public void setUp() {
+        cu = new CompilationUnit();
+    }
+
+    @After
+    public void teardown() {
+        cu = null;
+    }
+
+    @Test
+    public void cloneJavaDocTest() {
+        NodeList<BodyDeclaration<?>> bodyDeclarationList = new NodeList<>();
+        bodyDeclarationList.add(new AnnotationMemberDeclaration().setJavadocComment("javadoc"));
+        bodyDeclarationList.add(new ConstructorDeclaration().setJavadocComment("javadoc"));
+        bodyDeclarationList.add(new EnumConstantDeclaration().setJavadocComment("javadoc"));
+        bodyDeclarationList.add(new FieldDeclaration().setJavadocComment("javadoc"));
+        bodyDeclarationList.add(new InitializerDeclaration().setJavadocComment("javadoc"));
+        bodyDeclarationList.add(new MethodDeclaration().setJavadocComment("javadoc"));
+
+        NodeList<TypeDeclaration<?>> typeDeclarationList = new NodeList<>();
+        AnnotationDeclaration annotationDeclaration = new AnnotationDeclaration();
+        annotationDeclaration.setName("nnotationDeclarationTest");
+        typeDeclarationList.add(annotationDeclaration.setJavadocComment("javadoc"));
+
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration2 = new ClassOrInterfaceDeclaration();
+        classOrInterfaceDeclaration2.setName("emptyTypeDeclarationTest");
+        typeDeclarationList.add(classOrInterfaceDeclaration2.setJavadocComment("javadoc"));
+
+        EnumDeclaration enumDeclaration = new EnumDeclaration();
+        enumDeclaration.setName("enumDeclarationTest");
+        typeDeclarationList.add(enumDeclaration.setJavadocComment("javadoc"));
+
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration = new ClassOrInterfaceDeclaration();
+        classOrInterfaceDeclaration.setName("classOrInterfaceDeclarationTest");
+        typeDeclarationList.add(classOrInterfaceDeclaration.setJavadocComment("javadoc"));
+
+        ClassOrInterfaceDeclaration classOrInterfaceDeclaration1 = new ClassOrInterfaceDeclaration();
+        classOrInterfaceDeclaration1.setName("emptyTypeDeclarationTest1");
+        typeDeclarationList.add(classOrInterfaceDeclaration2.setMembers(bodyDeclarationList));
+
+        cu.setTypes(typeDeclarationList);
+        CompilationUnit cuClone = (CompilationUnit) new CloneVisitor().visit(cu, null);
+
+        NodeList<TypeDeclaration<?>> typeDeclarationListClone = cuClone.getTypes();
+        Iterator<TypeDeclaration<?>> typeItr = typeDeclarationListClone.iterator();
+        TypeDeclaration<?> typeDeclaration;
+        while (typeItr.hasNext()) {
+            typeDeclaration = typeItr.next();
+            if (typeDeclaration.getMembers() == null) {
+                assertEquals(typeDeclaration.getComment().get().getContent(), " javadoc");
+            } else {
+                Iterator<BodyDeclaration<?>> bodyItr = typeDeclaration.getMembers().iterator();
+                while (bodyItr.hasNext()) {
+                    BodyDeclaration<?> bodyDeclaration = bodyItr.next();
+                    assertEquals(bodyDeclaration.getComment().get().getContent(), " javadoc");
+                }
+            }
+        }
+    }
+    
+    @Test
+    public void cloneAnnotationOnWildcardTypeArgument() {
+        Type type = parseType("List<@C ? extends Object>").clone();
+        assertEquals("List<@C ? extends Object>", type.toString());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/HashCodeVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/HashCodeVisitorTest.java
new file mode 100644
index 0000000..679fb1d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/HashCodeVisitorTest.java
@@ -0,0 +1,24 @@
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class HashCodeVisitorTest {
+    @Test
+    public void testEquals() {
+        CompilationUnit p1 = JavaParser.parse("class X { }");
+        CompilationUnit p2 = JavaParser.parse("class X { }");
+        assertEquals(p1.hashCode(), p2.hashCode());
+    }
+
+    @Test
+    public void testNotEquals() {
+        CompilationUnit p1 = JavaParser.parse("class X { }");
+        CompilationUnit p2 = JavaParser.parse("class Y { }");
+        assertNotEquals(p1.hashCode(), p2.hashCode());
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/ModifierVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/ModifierVisitorTest.java
new file mode 100644
index 0000000..ada0c6f
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/ModifierVisitorTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseExpression;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class ModifierVisitorTest {
+    @Test
+    public void makeSureParentListsCanBeModified() {
+        NodeList<StringLiteralExpr> list = new NodeList<>();
+        list.add(new StringLiteralExpr("t"));
+        list.add(new StringLiteralExpr("a"));
+        list.add(new StringLiteralExpr("b"));
+        list.add(new StringLiteralExpr("c"));
+
+        list.accept(new ModifierVisitor<Void>() {
+            @Override
+            public Visitable visit(final StringLiteralExpr n, final Void arg) {
+                String v = n.getValue();
+
+                list.addFirst(new StringLiteralExpr("extra " + v));
+                list.remove(new StringLiteralExpr("t"));
+
+                if (v.equals("a")) {
+                    return new StringLiteralExpr("x");
+                }
+                if (v.equals("b")) {
+                    return null;
+                }
+
+                return n;
+            }
+        }, null);
+
+        assertEquals("extra c", list.get(0).getValue());
+        assertEquals("extra b", list.get(1).getValue());
+        assertEquals("extra a", list.get(2).getValue());
+        assertEquals("extra t", list.get(3).getValue());
+        assertEquals("x", list.get(4).getValue());
+        assertEquals("c", list.get(5).getValue());
+        assertEquals(6, list.size());
+    }
+
+    @Test
+    public void binaryExprReturnsLeftExpressionWhenRightSideIsRemoved() {
+        Expression expression = parseExpression("1+2");
+        Visitable result = expression.accept(new ModifierVisitor<Void>() {
+            public Visitable visit(IntegerLiteralExpr integerLiteralExpr, Void arg) {
+                if (integerLiteralExpr.getValue().equals("1")) {
+                    return null;
+                }
+                return integerLiteralExpr;
+            }
+        }, null);
+        assertEquals("2", result.toString());
+    }
+
+    @Test
+    public void binaryExprReturnsRightExpressionWhenLeftSideIsRemoved() {
+        final Expression expression = parseExpression("1+2");
+        final Visitable result = expression.accept(new ModifierVisitor<Void>() {
+            public Visitable visit(IntegerLiteralExpr integerLiteralExpr, Void arg) {
+                if (integerLiteralExpr.getValue().equals("2")) {
+                    return null;
+                }
+                return integerLiteralExpr;
+            }
+        }, null);
+        assertEquals("1", result.toString());
+    }
+
+    @Test
+    public void fieldDeclarationCantSurviveWithoutVariables() {
+        final BodyDeclaration<?> bodyDeclaration = JavaParser.parseBodyDeclaration("int x=1;");
+
+        final Visitable result = bodyDeclaration.accept(new ModifierVisitor<Void>() {
+            public Visitable visit(VariableDeclarator x, Void arg) {
+                return null;
+            }
+        }, null);
+
+        assertEquals(null, result);
+    }
+
+    @Test
+    public void variableDeclarationCantSurviveWithoutVariables() {
+        final BodyDeclaration<?> bodyDeclaration = JavaParser.parseBodyDeclaration("void x() {int x=1;}");
+
+        final Visitable result = bodyDeclaration.accept(new ModifierVisitor<Void>() {
+            public Visitable visit(VariableDeclarator x, Void arg) {
+                return null;
+            }
+        }, null);
+
+        assertEquals("void x() {" + EOL + "}", result.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitorTest.java
new file mode 100644
index 0000000..1e2cdf8
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/NoCommentEqualsVisitorTest.java
@@ -0,0 +1,54 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.ast.visitor;

+

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+

+import org.junit.Test;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ast.CompilationUnit;

+

+public class NoCommentEqualsVisitorTest {

+

+    @Test

+    public void testEquals() {

+        CompilationUnit p1 = JavaParser.parse("class X { }");

+        CompilationUnit p2 = JavaParser.parse("class X { }");

+        assertTrue(NoCommentEqualsVisitor.equals(p1, p2));

+    }

+

+    @Test

+    public void testEqualsWithDifferentComments() {

+        CompilationUnit p1 = JavaParser.parse("/* a */ class X { /** b */} //c");

+        CompilationUnit p2 = JavaParser.parse("/* b */ class X { }  //c");

+        assertTrue(NoCommentEqualsVisitor.equals(p1, p2));

+    }

+

+    @Test

+    public void testNotEquals() {

+        CompilationUnit p1 = JavaParser.parse("class X { }");

+        CompilationUnit p2 = JavaParser.parse("class Y { }");

+        assertFalse(NoCommentEqualsVisitor.equals(p1, p2));

+    }

+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitorTest.java
new file mode 100644
index 0000000..5065669
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/NoCommentHashCodeVisitorTest.java
@@ -0,0 +1,34 @@
+package com.github.javaparser.ast.visitor;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ast.CompilationUnit;

+import org.junit.Test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertNotEquals;

+

+public class NoCommentHashCodeVisitorTest {

+

+    @Test

+    public void testEquals() {

+        CompilationUnit p1 = JavaParser.parse("class X { }");

+        CompilationUnit p2 = JavaParser.parse("class X { }");

+        assertEquals(p1.hashCode(), p2.hashCode());

+    }

+

+    @Test

+    public void testEqualsWithDifferentComments() {

+        CompilationUnit p1 = JavaParser.parse("/* a */ class X { /** b */} //c");

+        CompilationUnit p2 = JavaParser.parse("/* b */ class X { }  //c");

+        assertEquals(p1.hashCode(), p2.hashCode());

+        assertEquals(p1.getComments().size(), 3);

+        assertEquals(p2.getComments().size(), 2);

+    }

+

+    @Test

+    public void testNotEquals() {

+        CompilationUnit p1 = JavaParser.parse("class X { }");

+        CompilationUnit p2 = JavaParser.parse("class Y { }");

+        assertNotEquals(p1.hashCode(), p2.hashCode());

+    }

+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/TreeVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/TreeVisitorTest.java
new file mode 100644
index 0000000..53d3753
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/TreeVisitorTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.ast.visitor;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.ArrayInitializerExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.SimpleName;
+import org.junit.Test;
+
+import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
+import static org.junit.Assert.assertEquals;
+
+public class TreeVisitorTest {
+    @Test
+    public void isValidBreadthFirstTraversal() {
+        Expression expression = JavaParser.parseExpression("(2+3)+(4+5)");
+
+        StringBuilder result = new StringBuilder();
+
+        TreeVisitor visitor = new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                result.append("<").append(node).append("> ");
+            }
+        };
+
+        visitor.visitBreadthFirst(expression);
+        assertEquals("<(2 + 3) + (4 + 5)> <(2 + 3)> <(4 + 5)> <2 + 3> <4 + 5> <2> <3> <4> <5> ", result.toString());
+    }
+
+    @Test
+    public void issue743ConcurrentModificationProblem() {
+        Expression expression = JavaParser.parseExpression("new int[]{1,2,3,4}");
+
+        StringBuilder result = new StringBuilder();
+        TreeVisitor visitor = new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                if (node instanceof IntegerLiteralExpr) {
+                    node.getParentNode().ifPresent(
+                            parent -> ((ArrayInitializerExpr) parent).getValues().add(new IntegerLiteralExpr("1")));
+                }
+                result.append("<").append(node).append("> ");
+            }
+        };
+        visitor.visitPreOrder(expression);
+        System.out.println(result);
+    }
+
+    @Test
+    public void isValidPreOrderTraversal() {
+        StringBuilder result = new StringBuilder();
+        new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                result.append("<").append(node).append("> ");
+            }
+        }.visitPreOrder(JavaParser.parseExpression("(2+3)+(4+5)"));
+        assertEquals("<(2 + 3) + (4 + 5)> <(2 + 3)> <2 + 3> <2> <3> <(4 + 5)> <4 + 5> <4> <5> ", result.toString());
+    }
+
+    @Test
+    public void isValidPostOrderTraversal() {
+        StringBuilder result = new StringBuilder();
+        new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                result.append("<").append(node).append("> ");
+            }
+        }.visitPostOrder(JavaParser.parseExpression("(2+3)+(4+5)"));
+        assertEquals("<2> <3> <2 + 3> <(2 + 3)> <4> <5> <4 + 5> <(4 + 5)> <(2 + 3) + (4 + 5)> ", result.toString());
+    }
+
+    @Test
+    public void preOrderConcurrentModificationIsOk() {
+        new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                if (node instanceof IntegerLiteralExpr) {
+                    node.getParentNode().ifPresent(
+                            parent -> ((ArrayInitializerExpr) parent).getValues().add(new IntegerLiteralExpr("1")));
+                }
+            }
+        }.visitPreOrder(JavaParser.parseExpression("new int[]{1,2,3,4}"));
+    }
+
+    @Test
+    public void postOrderConcurrentModificationIsOk() {
+        new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                if (node instanceof IntegerLiteralExpr) {
+                    node.getParentNode().ifPresent(
+                            parent -> ((ArrayInitializerExpr) parent).getValues().add(new IntegerLiteralExpr("1")));
+                }
+            }
+        }.visitPostOrder(JavaParser.parseExpression("new int[]{1,2,3,4}"));
+    }
+
+    @Test
+    public void parents() {
+        CompilationUnit cu = JavaParser.parse("class X{int x=1;}");
+        SimpleName x = cu.getClassByName("X").get().getMember(0).asFieldDeclaration().getVariable(0).getName();
+
+        Node.ParentsVisitor visitor = new Node.ParentsVisitor(x);
+        assertEquals("x = 1", visitor.next().toString());
+        assertEquals("int x = 1;", visitor.next().toString());
+        assertEqualsNoEol("class X {\n" +
+                "\n" +
+                "    int x = 1;\n" +
+                "}", visitor.next().toString());
+        assertEqualsNoEol("class X {\n" +
+                "\n" +
+                "    int x = 1;\n" +
+                "}\n", visitor.next().toString());
+        assertEquals(false, visitor.hasNext());
+    }
+
+    @Test
+    public void isValidDirectChildrenTraversal() {
+        Expression expression = JavaParser.parseExpression("(2+3)+(4+5)");
+
+        StringBuilder result = new StringBuilder();
+
+        TreeVisitor visitor = new TreeVisitor() {
+            @Override
+            public void process(Node node) {
+                result.append("<").append(node).append("> ");
+            }
+        };
+
+        visitor.visitDirectChildren(expression);
+        assertEquals("<(2 + 3)> <(4 + 5)> ", result.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/BasicJBehaveTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/BasicJBehaveTest.java
new file mode 100644
index 0000000..4e0fe6a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/BasicJBehaveTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.configuration.Configuration;
+import org.jbehave.core.configuration.MostUsefulConfiguration;
+import org.jbehave.core.failures.FailingUponPendingStep;
+import org.jbehave.core.io.LoadFromClasspath;
+import org.jbehave.core.io.StoryFinder;
+import org.jbehave.core.junit.JUnitStories;
+import org.jbehave.core.reporters.Format;
+import org.jbehave.core.reporters.StoryReporterBuilder;
+
+import java.util.List;
+
+import static org.jbehave.core.io.CodeLocations.codeLocationFromClass;
+
+abstract class BasicJBehaveTest extends JUnitStories {
+
+    private final String storiesPath;
+
+    public BasicJBehaveTest(String storiesPath) {
+        this.storiesPath = storiesPath;
+        JUnitReportingRunner.recommendedControls(configuredEmbedder());
+    }
+
+    @Override
+    public final Configuration configuration() {
+        return new MostUsefulConfiguration()
+                // where to find the stories
+                .useStoryLoader(new LoadFromClasspath(this.getClass()))
+                // Fails if Steps are not implemented
+                .usePendingStepStrategy(new FailingUponPendingStep())
+                // CONSOLE and HTML reporting
+                .useStoryReporterBuilder(new StoryReporterBuilder().withDefaultFormats()
+                        .withFormats(Format.CONSOLE, Format.HTML));
+    }
+
+    @Override
+    public final List<String> storyPaths() {
+        return new StoryFinder().findPaths(codeLocationFromClass(this.getClass()), storiesPath, "");
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/CommentParsingTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/CommentParsingTest.java
new file mode 100644
index 0000000..1ff3619
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/CommentParsingTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import com.github.javaparser.bdd.steps.CommentParsingSteps;
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.runner.RunWith;
+
+@RunWith(JUnitReportingRunner.class)
+public class CommentParsingTest extends BasicJBehaveTest {
+
+    @Override
+    public InjectableStepsFactory stepsFactory() {
+        return new InstanceStepsFactory(configuration(), new CommentParsingSteps());
+    }
+
+    public CommentParsingTest() {
+        super("**/bdd/comment*.story");
+    }
+}
+
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/ComparingTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/ComparingTest.java
new file mode 100644
index 0000000..4ecafd7
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/ComparingTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import com.github.javaparser.bdd.steps.ComparingSteps;
+import com.github.javaparser.bdd.steps.SharedSteps;
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(JUnitReportingRunner.class)
+public class ComparingTest extends BasicJBehaveTest {
+
+    @Override
+    public InjectableStepsFactory stepsFactory() {
+        Map<String, Object> state = new HashMap<>();
+
+        return new InstanceStepsFactory(configuration(),
+                new SharedSteps(state),
+                new ComparingSteps());
+    }
+
+    public ComparingTest() {
+        super("**/bdd/comparing*.story");
+    }
+}
+
+
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/ManipulationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/ManipulationTest.java
new file mode 100644
index 0000000..0f24632
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/ManipulationTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import com.github.javaparser.bdd.steps.ManipulationSteps;
+import com.github.javaparser.bdd.steps.SharedSteps;
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(JUnitReportingRunner.class)
+public class ManipulationTest extends BasicJBehaveTest {
+
+    @Override
+    public InjectableStepsFactory stepsFactory() {
+        Map<String, Object> state = new HashMap<>();
+
+        return new InstanceStepsFactory(configuration(),
+                new SharedSteps(state),
+                new ManipulationSteps(state));
+    }
+
+    public ManipulationTest() {
+        super("**/bdd/manipulation*.story");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/ParsingTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/ParsingTest.java
new file mode 100644
index 0000000..d05d57a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/ParsingTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import com.github.javaparser.bdd.steps.ParsingSteps;
+import com.github.javaparser.bdd.steps.SharedSteps;
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(JUnitReportingRunner.class)
+public class ParsingTest extends BasicJBehaveTest {
+
+    @Override
+    public InjectableStepsFactory stepsFactory() {
+        Map<String, Object> state = new HashMap<>();
+
+        return new InstanceStepsFactory(configuration(),
+                new SharedSteps(state),
+                new ParsingSteps(state));
+    }
+
+    public ParsingTest() {
+        super("**/bdd/parsing*.story");
+    }
+}
+
+
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/PositionRangeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/PositionRangeTest.java
new file mode 100644
index 0000000..e7f5b28
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/PositionRangeTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import com.github.javaparser.bdd.steps.PositionRangeSteps;
+import com.github.javaparser.bdd.steps.SharedSteps;
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(JUnitReportingRunner.class)
+public class PositionRangeTest extends BasicJBehaveTest {
+
+    @Override
+    public InjectableStepsFactory stepsFactory() {
+        Map<String, Object> state = new HashMap<>();
+
+        return new InstanceStepsFactory(configuration(),
+                new SharedSteps(state),
+                new PositionRangeSteps());
+    }
+
+    public PositionRangeTest() {
+        super("**/bdd/position_range*.story");
+    }
+}
+
+
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/PrettyPrintingTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/PrettyPrintingTest.java
new file mode 100644
index 0000000..7540d3b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/PrettyPrintingTest.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import com.github.javaparser.bdd.steps.PrettyPrintingSteps;
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.runner.RunWith;
+
+@RunWith(JUnitReportingRunner.class)
+public class PrettyPrintingTest extends BasicJBehaveTest {
+
+    @Override
+    public InjectableStepsFactory stepsFactory() {
+        return new InstanceStepsFactory(configuration(), new PrettyPrintingSteps());
+    }
+
+    public PrettyPrintingTest() {
+        super("**/bdd/pretty_printing*.story");
+    }
+}
+
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/TestUtils.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/TestUtils.java
new file mode 100644
index 0000000..784a113
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/TestUtils.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import java.io.InputStream;
+
+public class TestUtils {
+
+    public static InputStream getSampleStream(String sampleName) {
+        InputStream is = TestUtils.class.getClassLoader().getResourceAsStream("com/github/javaparser/bdd/samples/"
+                + sampleName + ".java");
+        if (is == null) {
+            throw new RuntimeException("Example not found, check your test. Sample name: " + sampleName);
+        }
+        return is;
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/VisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/VisitorTest.java
new file mode 100644
index 0000000..442c2ed
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/VisitorTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd;
+
+import com.github.javaparser.bdd.steps.SharedSteps;
+import com.github.javaparser.bdd.steps.VisitorSteps;
+import com.github.valfirst.jbehave.junit.monitoring.JUnitReportingRunner;
+import org.jbehave.core.steps.InjectableStepsFactory;
+import org.jbehave.core.steps.InstanceStepsFactory;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RunWith(JUnitReportingRunner.class)
+public class VisitorTest extends BasicJBehaveTest {
+
+    @Override
+    public InjectableStepsFactory stepsFactory() {
+        Map<String, Object> state = new HashMap<>();
+        return new InstanceStepsFactory(configuration(),
+                new SharedSteps(state),
+                new VisitorSteps(state));
+    }
+
+    public VisitorTest() {
+        super("**/bdd/visitor*.story");
+    }
+}
+
+
+
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/CommentParsingSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/CommentParsingSteps.java
new file mode 100644
index 0000000..3257c43
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/CommentParsingSteps.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.Range;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.*;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.printer.PrettyPrinter;
+import com.github.javaparser.printer.PrettyPrinterConfiguration;
+import org.jbehave.core.annotations.Alias;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+import org.jbehave.core.model.ExamplesTable;
+import org.jbehave.core.steps.Parameters;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Iterator;
+import java.util.Set;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.Range.range;
+import static com.github.javaparser.bdd.TestUtils.getSampleStream;
+import static com.github.javaparser.bdd.steps.SharedSteps.getMemberByTypeAndPosition;
+import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.text.IsEqualIgnoringWhiteSpace.equalToIgnoringWhiteSpace;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+public class CommentParsingSteps {
+
+    private CompilationUnit compilationUnit;
+    private CommentsCollection commentsCollection;
+    private String sourceUnderTest;
+    private ParserConfiguration configuration = new ParserConfiguration();
+    private PrettyPrinter prettyPrinter = new PrettyPrinter(new PrettyPrinterConfiguration());
+
+    @Given("the class:$classSrc")
+    public void givenTheClass(String classSrc) {
+        this.sourceUnderTest = classSrc.trim();
+    }
+
+    @When("read sample \"$sampleName\" using encoding \"$encoding\"")
+    public void givenTheClassWithEncoding(String sampleName, String encoding) throws IOException {
+        sourceUnderTest = null;
+        ParseResult<CompilationUnit> parseResult = new JavaParser(new ParserConfiguration()).parse(COMPILATION_UNIT, provider(getSampleStream(sampleName), Charset.forName(encoding)));
+        commentsCollection = parseResult.getCommentsCollection().orElse(new CommentsCollection());
+    }
+
+    @When("the class is parsed by the comment parser")
+    public void whenTheClassIsParsedByTheCommentParser() throws IOException {
+        ParseResult<CompilationUnit> parseResult = new JavaParser(new ParserConfiguration()).parse(COMPILATION_UNIT, provider(sourceUnderTest));
+        commentsCollection = parseResult.getCommentsCollection().orElse(new CommentsCollection());
+    }
+
+    @When("the do not consider annotations as node start for code attribution is $value on the Java parser")
+    public void whenTheDoNotConsiderAnnotationsAsNodeStartForCodeAttributionIsTrueOnTheJavaParser(boolean value) {
+        configuration.setDoNotConsiderAnnotationsAsNodeStartForCodeAttribution(value);
+    }
+
+    @When("the do not assign comments preceding empty lines is $value on the Java parser")
+    public void whenTheDoNotAssignCommentsPrecedingEmptyLinesIsTrueOnTheJavaParser(boolean value) {
+        configuration.setDoNotAssignCommentsPrecedingEmptyLines(value);
+    }
+
+    @When("the class is parsed by the Java parser")
+    public void whenTheClassIsParsedByTheJavaParser() {
+        ParseResult<CompilationUnit> result = new JavaParser(configuration).parse(COMPILATION_UNIT, provider(sourceUnderTest));
+        compilationUnit = result.getResult().get();
+    }
+
+    @Then("the Java parser cannot parse it because of an error")
+    public void javaParserCannotParseBecauseOfLexicalErrors() {
+        ParseResult<CompilationUnit> result = new JavaParser(configuration).parse(COMPILATION_UNIT, provider(sourceUnderTest));
+        if (result.isSuccessful()) {
+            fail("Lexical error expected");
+        }
+    }
+
+    @Then("the total number of comments is $expectedCount")
+    public void thenTheTotalNumberOfCommentsIs(int expectedCount) {
+        assertThat(commentsCollection.size(), is(expectedCount));
+    }
+
+    private <T extends Comment> T getCommentAt(Set<T> set, int index) {
+        Iterator<T> iterator = set.iterator();
+        T comment = null;
+        while (index >= 0) {
+            comment = iterator.next();
+            index--;
+        }
+        return comment;
+    }
+
+    @Then("line comment $position is \"$expectedContent\"")
+    public void thenLineCommentIs(int position, String expectedContent) {
+        LineComment lineCommentUnderTest = getCommentAt(commentsCollection.getLineComments(), position - 1);
+
+        assertThat(lineCommentUnderTest.getContent(), is(expectedContent));
+    }
+
+    @Then("block comment $position is \"$expectedContent\"")
+    public void thenBlockCommentIs(int position, String expectedContent) {
+        BlockComment lineCommentUnderTest = getCommentAt(commentsCollection.getBlockComments(), position - 1);
+
+        assertThat(lineCommentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("Javadoc comment $position is \"$expectedContent\"")
+    public void thenJavadocCommentIs(int position, String expectedContent) {
+        JavadocComment commentUnderTest = getCommentAt(commentsCollection.getJavadocComments(), position - 1);
+
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("the line comments have the following positions: $table")
+    public void thenTheLineCommentsHaveTheFollowingPositions(ExamplesTable examplesTable) {
+        int index = 0;
+        for (Parameters exampleRow : examplesTable.getRowsAsParameters()) {
+            Comment expectedLineComment = toComment(exampleRow, new LineComment());
+            Comment lineCommentUnderTest = getCommentAt(commentsCollection.getLineComments(), index);
+
+            Range underTestRange = lineCommentUnderTest.getRange().get();
+            Range expectedRange = expectedLineComment.getRange().get();
+
+            assertThat(underTestRange.begin.line, is(expectedRange.begin.line));
+            assertThat(underTestRange.begin.column, is(expectedRange.begin.column));
+            assertThat(underTestRange.end.line, is(expectedRange.end.line));
+            assertThat(underTestRange.end.column, is(expectedRange.end.column));
+            index++;
+        }
+    }
+
+    @Then("the block comments have the following positions: $table")
+    public void thenTheBlockCommentsHaveTheFollowingPositions(ExamplesTable examplesTable) {
+        int index = 0;
+        for (Parameters exampleRow : examplesTable.getRowsAsParameters()) {
+            Comment expectedLineComment = toComment(exampleRow, new BlockComment());
+            Comment lineCommentUnderTest = getCommentAt(commentsCollection.getBlockComments(), index);
+
+            Range underTestRange = lineCommentUnderTest.getRange().get();
+            Range expectedRange = expectedLineComment.getRange().get();
+
+            assertThat(underTestRange.begin.line, is(expectedRange.begin.line));
+            assertThat(underTestRange.begin.column, is(expectedRange.begin.column));
+            assertThat(underTestRange.end.line, is(expectedRange.end.line));
+            assertThat(underTestRange.end.column, is(expectedRange.end.column));
+            index++;
+        }
+    }
+
+    @Then("the Javadoc comments have the following positions: $table")
+    public void thenTheJavadocCommentsHaveTheFollowingPositions(ExamplesTable examplesTable) {
+        int index = 0;
+        for (Parameters exampleRow : examplesTable.getRowsAsParameters()) {
+            Comment expectedLineComment = toComment(exampleRow, new BlockComment());
+            Comment lineCommentUnderTest = getCommentAt(commentsCollection.getJavadocComments(), index);
+
+            Range underTestRange = lineCommentUnderTest.getRange().get();
+            Range expectedRange = expectedLineComment.getRange().get();
+
+            assertThat(underTestRange.begin.line, is(expectedRange.begin.line));
+            assertThat(underTestRange.begin.column, is(expectedRange.begin.column));
+            assertThat(underTestRange.end.line, is(expectedRange.end.line));
+            assertThat(underTestRange.end.column, is(expectedRange.end.column));
+            index++;
+        }
+    }
+
+    @Then("it is printed as:$src")
+    public void isPrintedAs(String src) {
+        assertThat(prettyPrinter.print(compilationUnit).trim(), is(src.trim()));
+    }
+
+    @Then("the compilation unit is not commented")
+    public void thenTheCompilationUnitIsNotCommented() {
+        assertEquals(false, compilationUnit.getComment().isPresent());
+    }
+
+    @Then("the compilation is commented \"$expectedContent\"")
+    public void thenTheCompilationIsCommentedCompilationUnitComment(String expectedContent) {
+        assertThat(compilationUnit.getComment().get().getContent(), is(expectedContent));
+    }
+
+    @Then("the compilation unit has $expectedCount contained comments")
+    public void thenTheCompilationUnitHasContainedComments(int expectedCount) {
+        assertThat(compilationUnit.getComments().size(), is(expectedCount));
+    }
+
+    @Then("the compilation unit has $expectedCount orphan comments")
+    public void thenTheCompilationUnitHasExpectedCountOrphanComments(int expectedCount) {
+        assertThat(compilationUnit.getOrphanComments().size(), is(expectedCount));
+    }
+
+    @Then("the compilation unit orphan comment $position is \"$expectedContent\"")
+    public void thenTheCompilationUnitOrphanCommentIs(int position, String expectedContent) {
+        Comment commentUnderTest = compilationUnit.getOrphanComments().get(position - 1);
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("comment $commentPosition in compilation unit is not an orphan")
+    public void thenCommentInCompilationUnitIsNotAnOrphan(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.isOrphan(), is(false));
+    }
+
+    @Then("comment $commentPosition in compilation unit is an orphan")
+    public void thenCommentInCompilationUnitIsAnOrphan(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.isOrphan(), is(true));
+    }
+
+    @Then("comment $commentPosition in compilation unit is \"$expectedContent\"")
+    public void thenCommentInCompilationUnitIs(int position, String expectedContent) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(position - 1);
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("class $position is not commented")
+    public void thenClassIsNotCommented(int position) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(position - 1);
+        assertEquals(false, classUnderTest.getComment().isPresent());
+    }
+
+    @Then("class $position is commented \"$expectedContent\"")
+    public void thenClassIsCommented(int position, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(position - 1);
+        assertThat(classUnderTest.getComment().get().getContent(), is(expectedContent));
+    }
+
+    @Then("class $position has $expectedCount total contained comments")
+    public void thenClassHasTotalContainedComments(int position, int expectedCount) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(position - 1);
+        assertThat(classUnderTest.getAllContainedComments().size(), is(expectedCount));
+    }
+
+    @Then("class $position has $expectedCount orphan comment")
+    @Alias("class $position has $expectedCount orphan comments")
+    public void thenClassHasOrphanComments(int position, int expectedCount) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(position - 1);
+        assertThat(classUnderTest.getOrphanComments().size(), is(expectedCount));
+    }
+
+    @Then("class $classPosition orphan comment $commentPosition is \"$expectedContent\"")
+    public void thenClassOrphanCommentIs(int classPosition, int commentPosition, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        Comment commentUnderTest = classUnderTest.getOrphanComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("method $methodPosition in class $classPosition is commented \"$expectedContent\"")
+    public void thenMethodInClassIsCommented(int methodPosition, int classPosition, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        assertThat(methodUnderTest.getComment().get().getContent(), equalToIgnoringWhiteSpace(expectedContent));
+    }
+
+    @Then("method $methodPosition in class $classPosition has $expectedCount total contained comments")
+    public void thenMethodInClassHasTotalContainedComments(int methodPosition, int classPosition, int expectedCount) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        assertThat(methodUnderTest.getAllContainedComments().size(), is(expectedCount));
+    }
+
+    @Then("comment $commentPosition in method $methodPosition in class $classPosition is \"$expectedContent\"")
+    public void thenCommentInMethodInClassIs(int commentPosition, int methodPosition, int classPosition, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        Comment commentUnderTest = methodUnderTest.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("method $methodPosition in class $classPosition has $expectedCount orphan comments")
+    public void thenMethodInClassHasOrphanComments(int methodPosition, int classPosition, int expectedCount) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        assertThat(methodUnderTest.getOrphanComments().size(), is(expectedCount));
+    }
+
+    @Then("block statement in method $methodPosition in class $classPosition has $expectedCount total contained comments")
+    public void thenBlockStatementInMethodInClassHasTotalContainedComments(int methodPosition, int classPosition, int expectedCount) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        BlockStmt blockStmtUnderTest = methodUnderTest.getBody().orElse(null);
+        assertThat(blockStmtUnderTest.getAllContainedComments().size(), is(expectedCount));
+    }
+
+    @Then("block statement in method $methodPosition in class $classPosition has $expectedCount orphan comments")
+    public void thenBlockStatementInMethodInClassHasOrphanComments(int methodPosition, int classPosition, int expectedCount) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        BlockStmt blockStmtUnderTest = methodUnderTest.getBody().orElse(null);
+        assertThat(blockStmtUnderTest.getOrphanComments().size(), is(expectedCount));
+    }
+
+    @Then("block statement in method $methodPosition in class $classPosition orphan comment $commentPosition is \"$expectedContent\"")
+    public void thenBlockStatementInMethodInClassIs(int methodPosition, int classPosition, int commentPosition, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        BlockStmt blockStmtUnderTest = methodUnderTest.getBody().orElse(null);
+        Comment commentUnderTest = blockStmtUnderTest.getOrphanComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("type of method $methodPosition in class $classPosition is commented \"$expectedContent\"")
+    public void thenTypeOfMethodInClassIsCommented(int methodPosition, int classPosition, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        MethodDeclaration methodUnderTest = getMemberByTypeAndPosition(classUnderTest, methodPosition - 1,
+                MethodDeclaration.class);
+        Comment commentUnderTest = methodUnderTest.getType().getComment().get();
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("field $fieldPosition in class $classPosition contains $expectedCount comments")
+    public void thenFieldInClassContainsComments(int fieldPosition, int classPosition, int expectedCount) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        FieldDeclaration fieldUnderTest = getMemberByTypeAndPosition(classUnderTest, fieldPosition - 1,
+                FieldDeclaration.class);
+        assertThat(fieldUnderTest.getAllContainedComments().size(), is(expectedCount));
+    }
+
+    @Then("field $fieldPosition in class $classPosition is not commented")
+    public void thenFieldInClassIsNotCommented(int fieldPosition, int classPosition) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        FieldDeclaration fieldUnderTest = getMemberByTypeAndPosition(classUnderTest, fieldPosition - 1,
+                FieldDeclaration.class);
+        assertEquals(false, fieldUnderTest.getComment().isPresent());
+    }
+
+    @Then("field $fieldPosition in class $classPosition is commented \"$expectedContent\"")
+    public void thenFieldInClassIsCommented(int fieldPosition, int classPosition, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        FieldDeclaration fieldUnderTest = getMemberByTypeAndPosition(classUnderTest, fieldPosition - 1,
+                FieldDeclaration.class);
+        Comment commentUnderTest = fieldUnderTest.getComment().get();
+        assertThat(commentUnderTest.getContent(), is(equalToIgnoringWhiteSpace(expectedContent)));
+    }
+
+    @Then("variable $variablePosition value of field $fieldPosition in class $classPosition is commented \"$expectedContent\"")
+    public void thenVariableValueOfFieldInClassIsCommented(int variablePosition, int fieldPosition, int classPosition, String expectedContent) {
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        FieldDeclaration fieldUnderTest = getMemberByTypeAndPosition(classUnderTest, fieldPosition - 1,
+                FieldDeclaration.class);
+        VariableDeclarator variableUnderTest = fieldUnderTest.getVariable(variablePosition - 1);
+        Expression valueUnderTest = variableUnderTest.getInitializer().orElse(null);
+        Comment commentUnderTest = valueUnderTest.getComment().get();
+        assertThat(commentUnderTest.getContent(), is(expectedContent));
+    }
+
+    @Then("comment $commentPosition in compilation unit parent is ClassOrInterfaceDeclaration")
+    public void thenCommentInCompilationUnitParentIsClassOrInterfaceDeclaration(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getParentNode().get(), instanceOf(ClassOrInterfaceDeclaration.class));
+    }
+
+    @Then("comment $commentPosition in compilation unit commented node is ClassOrInterfaceDeclaration")
+    public void thenCommentInCompilationUnitCommentedNodeIsClassOrInterfaceDeclaration(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getCommentedNode().get(), instanceOf(ClassOrInterfaceDeclaration.class));
+    }
+
+    @Then("comment $commentPosition in compilation unit commented node is FieldDeclaration")
+    public void thenCommentInCompilationUnitCommentedNodeIsFieldDeclaration(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getCommentedNode().get(), instanceOf(FieldDeclaration.class));
+    }
+
+    @Then("comment $commentPosition in compilation unit commented node is IntegerLiteralExpr")
+    public void thenCommentInCompilationUnitCommentedNodeIsIntegerLiteralExpr(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getCommentedNode().get(), instanceOf(IntegerLiteralExpr.class));
+    }
+
+    @Then("comment $commentPosition in compilation unit commented node is ExpressionStmt")
+    public void thenCommentInCompilationUnitCommentedNodeIsIntegerExpressionStmt(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getCommentedNode().get(), instanceOf(ExpressionStmt.class));
+    }
+
+    @Then("comment $commentPosition in compilation unit commented node is PrimitiveType")
+    public void thenCommentInCompilationUnitCommentedNodeIsIntegerPrimitiveType(int commentPosition) {
+        Comment commentUnderTest = compilationUnit.getAllContainedComments().get(commentPosition - 1);
+        assertThat(commentUnderTest.getCommentedNode().get(), instanceOf(PrimitiveType.class));
+    }
+
+    private Comment toComment(Parameters row, Comment comment) {
+        comment.setRange(range(Integer.parseInt(row.values().get("beginLine")),
+                Integer.parseInt(row.values().get("beginColumn")),
+                Integer.parseInt(row.values().get("endLine")),
+                Integer.parseInt(row.values().get("endColumn"))));
+        return comment;
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ComparingSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ComparingSteps.java
new file mode 100644
index 0000000..4b789a7
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ComparingSteps.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class ComparingSteps {
+
+    private CompilationUnit first;
+    private CompilationUnit second;
+
+    /*
+     * Given steps
+     */
+
+    @Given("the first class:$classSrc")
+    public void givenTheFirstClass(String classSrc) {
+        this.first = JavaParser.parse(classSrc.trim());
+    }
+
+    @Given("the second class:$classSrc")
+    public void givenTheSecondClass(String classSrc) {
+        this.second = JavaParser.parse(classSrc.trim());
+    }
+
+    /*
+     * Then steps
+     */
+
+    @Then("they are equals")
+    public void thenTheyAreEquals() {
+        assertThat(first, is(equalTo(second)));
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ExistenceOfParentNodeVerifier.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ExistenceOfParentNodeVerifier.java
new file mode 100644
index 0000000..27d81b5
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ExistenceOfParentNodeVerifier.java
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.HasParentNode;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * The <code>ExistenceOfParentNodeVerifier</code> verifies that each node of the compilation unit has a parent set.
+ */
+class ExistenceOfParentNodeVerifier {
+
+    public void verify(CompilationUnit compilationUnit) throws AssertionError {
+        new Verifier().visit(compilationUnit, null);
+    }
+
+    private static class Verifier extends VoidVisitorAdapter<Void> {
+        private static void assertParentIsSet(HasParentNode<?> n) {
+            assertThat(n + " has no parent set!", n.getParentNode().orElse(null), is(notNullValue()));
+        }
+
+        @Override
+        public void visit(AnnotationDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(AnnotationMemberDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ArrayAccessExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ArrayCreationExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ArrayInitializerExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(AssertStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(AssignExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(BinaryExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(BlockComment n, Void arg) {
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(BlockStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(BooleanLiteralExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(BreakStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(CastExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(CatchClause n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(CharLiteralExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ClassExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ClassOrInterfaceDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ClassOrInterfaceType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(CompilationUnit n, Void arg) {
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ConditionalExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ConstructorDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ContinueStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(DoStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(DoubleLiteralExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(EmptyStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(EnclosedExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(EnumConstantDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(EnumDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ExplicitConstructorInvocationStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ExpressionStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(FieldAccessExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(FieldDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ForeachStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ForStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(IfStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(InitializerDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(InstanceOfExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(IntegerLiteralExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(JavadocComment n, Void arg) {
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(LabeledStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(LineComment n, Void arg) {
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(LambdaExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(LongLiteralExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(MarkerAnnotationExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(MemberValuePair n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(MethodCallExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(MethodDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(MethodReferenceExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(NameExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(NormalAnnotationExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(NullLiteralExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ObjectCreationExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(PackageDeclaration n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(Parameter n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(PrimitiveType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(Name n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(SimpleName n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ArrayType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ArrayCreationLevel n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(IntersectionType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(UnionType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ReturnStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(SingleMemberAnnotationExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(StringLiteralExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(SuperExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(SwitchEntryStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(SwitchStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(SynchronizedStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ThisExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(ThrowStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(TryStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(LocalClassDeclarationStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(TypeExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(NodeList n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(TypeParameter n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(UnaryExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(UnknownType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(VariableDeclarationExpr n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(VariableDeclarator n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(VoidType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(WhileStmt n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+
+        @Override
+        public void visit(WildcardType n, Void arg) {
+            assertParentIsSet(n);
+            super.visit(n, arg);
+        }
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ManipulationSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ManipulationSteps.java
new file mode 100644
index 0000000..557bf0d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ManipulationSteps.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.stmt.TryStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.VoidType;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+import org.jbehave.core.annotations.Alias;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+import java.util.EnumSet;
+import java.util.Map;
+
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+import static com.github.javaparser.JavaParser.parseName;
+import static com.github.javaparser.ast.NodeList.nodeList;
+import static com.github.javaparser.ast.type.PrimitiveType.*;
+import static com.github.javaparser.bdd.steps.SharedSteps.getMethodByPositionAndClassPosition;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+
+public class ManipulationSteps {
+
+    /* Fields used to maintain step state within this step class */
+    private BlockStmt blockStmt;
+    private Statement statement;
+    private TryStmt tryStmt;
+    private NodeList<Expression> variableDeclarationExprList;
+    private ChangeMethodNameToUpperCaseVisitor changeMethodNameToUpperCaseVisitor;
+    private AddNewIntParameterCalledValueVisitor addNewIntParameterCalledValueVisitor;
+
+    /* Map that maintains shares state across step classes.  If manipulating the objects in the map you must update the state */
+    private Map<String, Object> state;
+
+    public ManipulationSteps(Map<String, Object> state) {
+        this.state = state;
+    }
+
+    @Given("a BlockStmt")
+    public void givenABlockStatement() {
+        blockStmt = new BlockStmt();
+    }
+
+    @Given("a Statement")
+    public void givenAStatement() {
+        statement = null;
+    }
+
+    @Given("a TryStmt")
+    public void givenATryStmt() {
+        tryStmt = new TryStmt();
+    }
+
+    @Given("a List of VariableDeclarations")
+    public void givenAListOfVariableDeclarations() {
+        variableDeclarationExprList = new NodeList<>();
+        variableDeclarationExprList.add(new VariableDeclarationExpr());
+        variableDeclarationExprList.add(new VariableDeclarationExpr());
+    }
+
+    @Given("a ChangeNameToUpperCaseVisitor")
+    public void givenAChangeNameToUpperCaseVisitor() {
+        changeMethodNameToUpperCaseVisitor = new ChangeMethodNameToUpperCaseVisitor();
+    }
+
+    @Given("a AddNewIntParameterCalledValueVisitor")
+    public void givenAAddNewParameterCalledValueVisitor() {
+        addNewIntParameterCalledValueVisitor = new AddNewIntParameterCalledValueVisitor();
+    }
+
+    @When("is the String \"$value\" is parsed by the JavaParser using parseBlock")
+    public void whenIsTheStringIsParsedByTheJavaParser(String value) {
+        blockStmt = JavaParser.parseBlock(value);
+    }
+
+    @When("is the String \"$value\" is parsed by the JavaParser using parseStatement")
+    public void whenIsTheStringIsParsedByTheJavaParserUsingParseStatement(String value) {
+        statement = JavaParser.parseStatement(value);
+    }
+
+    @When("the List of VariableDeclarations are set as the resources on TryStmt")
+    public void whenTheListOfVariableDeclarationsAreSetAsTheResourcesOnTryStmt() {
+        tryStmt.setResources(variableDeclarationExprList);
+    }
+
+    @When("empty list is set as the resources on TryStmt")
+    public void whenNullIsSetAsTheResourcesOnTryStmt() {
+        tryStmt.setResources(new NodeList<>());
+    }
+
+    @When("the package declaration is set to \"$packageName\"")
+    public void whenThePackageDeclarationIsSetTo(String packageName) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        compilationUnit.setPackageDeclaration(new PackageDeclaration(parseName(packageName)));
+        state.put("cu1", compilationUnit);
+    }
+
+    @When("a public class called \"$className\" is added to the CompilationUnit")
+    public void whenAClassCalledIsAddedToTheCompilationUnit(String className) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        TypeDeclaration<?> type = new ClassOrInterfaceDeclaration(EnumSet.of(Modifier.PUBLIC), false, "CreateClass");
+        compilationUnit.setTypes(nodeList(type));
+        state.put("cu1", compilationUnit);
+    }
+
+    @When("a public static method called \"$methodName\" returning void is added to class $position in the compilation unit")
+    public void whenAStaticMethodCalledReturningIsAddedToClassInTheCompilationUnit(String methodName, int position) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        TypeDeclaration<?> type = compilationUnit.getType(position - 1);
+        EnumSet<Modifier> modifiers = EnumSet.of(Modifier.PUBLIC);
+        MethodDeclaration method = new MethodDeclaration(modifiers, new VoidType(), methodName);
+        modifiers.add(Modifier.STATIC);
+        method.setModifiers(modifiers);
+        type.addMember(method);
+        state.put("cu1", compilationUnit);
+    }
+
+    @When("$typeName varargs called \"$parameterName\" are added to method $methodPosition in class $classPosition")
+    public void whenVarargsCalledAreAddedToMethodInClass(String typeName, String parameterName, int methodPosition, int classPosition) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition)
+                .addAndGetParameter(typeName, parameterName)
+                .setVarArgs(true);
+    }
+
+    @When("a BlockStmt is added to method $methodPosition in class $classPosition")
+    public void whenABlockStmtIsAddedToMethodInClass(int methodPosition, int classPosition) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+        method.setBody(new BlockStmt());
+    }
+
+    @When("$className.$fieldName.$methodName(\"$stringValue\"); is added to the body of method $methodPosition in class $classPosition")
+    public void whenHelloWorldIsAddedToTheBodyOfMethodInClass(String className, String fieldName, String methodName, String stringValue,
+                                                              int methodPosition, int classPosition) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+        NameExpr clazz = new NameExpr(className);
+        FieldAccessExpr field = new FieldAccessExpr(clazz, fieldName);
+        MethodCallExpr call = new MethodCallExpr(field, methodName);
+        call.addArgument(new StringLiteralExpr(stringValue));
+        method.getBody().get().addStatement(call);
+    }
+
+    @When("method $methodPosition in class $classPosition has it's name converted to uppercase")
+    public void whenMethodInClassHasItsNameConvertedToUppercase(int methodPosition, int classPosition) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+        method.setName(method.getNameAsString().toUpperCase());
+    }
+
+    @When("method $methodPosition in class $classPosition has an int parameter called \"$paramName\" added")
+    public void whenMethodInClassHasAnIntArgumentCalledAdded(int methodPosition, int classPosition, String paramName) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+        method.addParameter(intType(), paramName);
+    }
+
+    @When("the compilation unit is cloned")
+    public void whenTheCompilationUnitIsCloned() throws CloneNotSupportedException {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        state.put("cu1", compilationUnit.clone());
+    }
+
+    @When("the ChangeNameToUpperCaseVisitor visits to compilation unit")
+    public void whenTheVisitorVisitsToCompilationUnit() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        changeMethodNameToUpperCaseVisitor.visit(compilationUnit, null);
+        state.put("cu1", compilationUnit);
+    }
+
+    @When("the AddNewIntParameterCalledValueVisitor visits to compilation unit")
+    public void whenTheAddNewParameterCalledValueVisitorVisitsToCompilationUnit() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        addNewIntParameterCalledValueVisitor.visit(compilationUnit, null);
+        state.put("cu1", compilationUnit);
+    }
+
+    @Then("is not equal to null")
+    public void thenIsNotEqualToNull() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        assertNotEquals(compilationUnit, null);
+    }
+
+    @Then("is not equal to $value")
+    public void thenIsNotEqualTo(String value) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        assertNotEquals(compilationUnit, value);
+    }
+
+    @Then("Statement $position in BlockStmt toString is \"$expectedContent\"")
+    public void thenTheBlockStmtContentIs(int position, String expectedContent) {
+        Statement statementUnderTest = blockStmt.getStatement(position - 1);
+        assertThat(statementUnderTest.toString(), is(expectedContent));
+    }
+
+    @Then("Statement toString is \"$expectedContent\"")
+    public void thenStatementToStringIsxXy(String expectedContent) {
+        assertThat(statement.toString(), is(expectedContent));
+    }
+
+    @Then("all the VariableDeclarations parent is the TryStmt")
+    public void thenAllTheVariableDeclarationsParentIsTheTryStmt() {
+        variableDeclarationExprList.forEach(expr -> assertThat(expr.getParentNode().get(), is(tryStmt)));
+    }
+
+    @Then("the TryStmt has no child nodes")
+    public void thenTheTryStmtHasNotChildNodes() {
+        assertThat(tryStmt.getChildNodes().size(), is(0));
+    }
+
+    @Then("method $methodPosition in class $classPosition has the name \"$expectedName\"")
+    public void thenMethodInClassHasTheName(int methodPosition, int classPosition, String expectedName) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+        assertThat(method.getNameAsString(), is(expectedName));
+    }
+
+    @Then("method $methodPosition in class $classPosition has $expectedCount parameters")
+    @Alias("method $methodPosition in class $classPosition has $expectedCount parameter")
+    public void thenMethodInClassHasArguments(int methodPosition, int classPosition, int expectedCount) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+
+        assertThat(method.getParameters().size(), is(expectedCount));
+    }
+
+    @Then("method $methodPosition in class $classPosition parameter $parameterPosition is type int called \"$expectedName\"")
+    public void thenMethodInClassParameterIsTypeIntCalled(int methodPosition, int classPosition, int parameterPosition, String expectedName) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+        Parameter parameter = method.getParameter(parameterPosition - 1);
+        assertThat(parameter.getType(), is(intType()));
+        assertThat(parameter.getNameAsString(), is(expectedName));
+    }
+
+    private static class ChangeMethodNameToUpperCaseVisitor extends VoidVisitorAdapter<Void> {
+        @Override
+        public void visit(MethodDeclaration n, Void arg) {
+            n.setName(n.getNameAsString().toUpperCase());
+        }
+    }
+
+    private static class AddNewIntParameterCalledValueVisitor extends VoidVisitorAdapter<Void> {
+        @Override
+        public void visit(MethodDeclaration n, Void arg) {
+            n.addParameter(intType(), "value");
+        }
+    }
+}
+
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ParsingSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ParsingSteps.java
new file mode 100644
index 0000000..01631c6
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/ParsingSteps.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+import java.util.List;
+import java.util.Map;
+
+import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.bdd.steps.SharedSteps.getMemberByTypeAndPosition;
+import static com.github.javaparser.bdd.steps.SharedSteps.getMethodByPositionAndClassPosition;
+import static java.lang.String.format;
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.*;
+
+public class ParsingSteps {
+
+    private Map<String, Object> state;
+
+    public ParsingSteps(Map<String, Object> state) {
+        this.state = state;
+    }
+
+    private String sourceUnderTest;
+
+    /*
+     * Given steps
+     */
+
+    @Given("the class:$classSrc")
+    public void givenTheClass(String classSrc) {
+        this.sourceUnderTest = classSrc.trim();
+    }
+
+
+    /*
+     * When steps
+     */
+
+    @When("I take the ArrayCreationExpr")
+    public void iTakeTheArrayCreationExpr() {
+        setSelectedNodeFromCompilationUnit(ArrayCreationExpr.class);
+    }
+
+    @When("I take the PackageDeclaration")
+    public void iTakeThePackageDeclaration() {
+        setSelectedNodeFromCompilationUnit(PackageDeclaration.class);
+    }
+
+    @When("I take the ObjectCreationExpr")
+    public void iTakeTheObjectCreationExpr() throws ClassNotFoundException {
+        setSelectedNodeFromCompilationUnit(ObjectCreationExpr.class);
+    }
+
+    /*
+     * Then steps
+     */
+
+    @Then("constructor $constructorPosition in class $classPosition declaration as a String is \"$expectedString\"")
+    public void thenTheConstructorDeclarationAsAStringIs(int constructorPosition, int classPosition, String expectedString) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
+        ConstructorDeclaration constructor = (ConstructorDeclaration) clazz.getMember(constructorPosition - 1);
+        assertThat(constructor.getDeclarationAsString(), is(expectedString));
+    }
+
+    @Then("constructor $constructorPosition in class $classPosition declaration short form as a String is \"$expectedString\"")
+    public void thenConstructorInClassDeclarationShortFormAsAStringIs(int constructorPosition, int classPosition, String expectedString) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
+        ConstructorDeclaration constructor = (ConstructorDeclaration) clazz.getMember(constructorPosition - 1);
+        assertThat(constructor.getDeclarationAsString(false, false), is(expectedString));
+    }
+
+    @Then("method $methodPosition in class $classPosition declaration as a String is \"$expectedString\"")
+    public void thenMethod1InClass1DeclarationAsAStringIs(int methodPosition, int classPosition, String expectedString) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
+        MethodDeclaration method = (MethodDeclaration) clazz.getMember(methodPosition - 1);
+        assertThat(method.getDeclarationAsString(), is(expectedString));
+    }
+
+    @Then("method $methodPosition in class $classPosition declaration as a String short form is \"$expectedString\"")
+    public void thenMethodInClassDeclarationAsAStringShortFormIs(int methodPosition, int classPosition, String expectedString) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
+        MethodDeclaration method = (MethodDeclaration) clazz.getMember(methodPosition - 1);
+        assertThat(method.getDeclarationAsString(false, false), is(expectedString));
+    }
+
+    @Then("field $fieldPosition in class $classPosition contains annotation $annotationPosition value is \"$expectedValue\"")
+    public void thenFieldInClassContainsAnnotationValueIs(int fieldPosition, int classPosition, int annotationPosition, String expectedValue) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+
+        TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
+        FieldDeclaration fieldUnderTest = getMemberByTypeAndPosition(classUnderTest, fieldPosition - 1,
+                FieldDeclaration.class);
+        AnnotationExpr annotationUnderTest = fieldUnderTest.getAnnotation(annotationPosition - 1);
+        assertThat(annotationUnderTest.getChildNodes().get(1).toString(), is(expectedValue));
+    }
+
+    @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is called $expectedName")
+    public void thenLambdaInClassIsCalled(int statementPosition, int methodPosition, int classPosition, String expectedName) {
+        Statement statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        VariableDeclarationExpr expression = (VariableDeclarationExpr) ((ExpressionStmt) statement).getExpression();
+        VariableDeclarator variableDeclarator = expression.getVariable(0);
+        assertThat(variableDeclarator.getNameAsString(), is(expectedName));
+    }
+
+    @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition body is \"$expectedBody\"")
+    public void thenLambdaInStatementInMethodInClassBody(int statementPosition, int methodPosition, int classPosition,
+                                                         String expectedBody) {
+        LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        assertThat(lambdaExpr.getBody().toString(), is(expectedBody));
+    }
+
+    @Then("lambda in method call in statement $statementPosition in method $methodPosition in class $classPosition body is \"$expectedBody\"")
+    public void thenLambdaInMethodCallInStatementInMethodInClassBody(int statementPosition, int methodPosition, int classPosition,
+                                                                     String expectedBody) {
+        ExpressionStmt statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asExpressionStmt();
+        VariableDeclarationExpr variableDeclarationExpr = statement.getExpression().asVariableDeclarationExpr();
+        VariableDeclarator variableDeclarator = variableDeclarationExpr.getVariable(0);
+        MethodCallExpr methodCallExpr = (MethodCallExpr) variableDeclarator.getInitializer().orElse(null);
+        CastExpr castExpr = methodCallExpr.getArgument(0).asCastExpr();
+        LambdaExpr lambdaExpr = castExpr.getExpression().asLambdaExpr();
+        assertThat(lambdaExpr.getBody().toString(), is(expectedBody));
+    }
+
+    @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition block statement is null")
+    public void thenLambdaInStatementInMethodInClassBlockStatementIsNull(int statementPosition, int methodPosition, int classPosition) {
+        LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        BlockStmt blockStmt = lambdaExpr.getBody().asBlockStmt();
+        assertEquals(true, blockStmt.getStatements().isEmpty());
+    }
+
+    @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition has parameters with non-null type")
+    public void thenLambdaInStatementInMethodInClassHasParametersWithNonNullType(int statementPosition, int methodPosition, int classPosition) {
+        LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        for (Parameter parameter : lambdaExpr.getParameters()) {
+            assertThat(parameter.getType(), is(notNullValue()));
+        }
+    }
+
+    @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition block statement is \"$expectedBody\"")
+    public void thenLambdaInStatementInMethodInClassBlockStatement(int statementPosition, int methodPosition, int classPosition,
+                                                                   String expectedBody) {
+        LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        BlockStmt blockStmt = lambdaExpr.getBody().asBlockStmt();
+        Statement lambdaStmt = blockStmt.getStatement(0);
+        assertThat(lambdaStmt.toString(), is(expectedBody));
+    }
+
+    @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is parent of contained body")
+    public void thenLambdaInStatementInMethodInClassIsParentOfContainedBody(int statementPosition, int methodPosition, int classPosition) {
+        LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        Statement body = lambdaExpr.getBody();
+        assertThat(body.getParentNode().get(), is(lambdaExpr));
+    }
+
+    @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is parent of contained parameter")
+    public void thenLambdaInStatementInMethodInClassIsParentOfContainedParameter(int statementPosition, int methodPosition, int classPosition) {
+        LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        Parameter parameter = lambdaExpr.getParameter(0);
+        assertThat(parameter.getParentNode().get(), is(lambdaExpr));
+    }
+
+    @Then("method reference in statement $statementPosition in method $methodPosition in class $classPosition scope is $expectedName")
+    public void thenMethodReferenceInStatementInMethodInClassIsScope(int statementPosition, int methodPosition,
+                                                                     int classPosition, String expectedName) {
+        ExpressionStmt statementUnderTest = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asExpressionStmt();
+        assertEquals(1, statementUnderTest.findAll(MethodReferenceExpr.class).size());
+        MethodReferenceExpr methodReferenceUnderTest = statementUnderTest.findFirst(MethodReferenceExpr.class).get();
+        assertThat(methodReferenceUnderTest.getScope().toString(), is(expectedName));
+    }
+
+    @Then("method reference in statement $statementPosition in method $methodPosition in class $classPosition identifier is $expectedName")
+    public void thenMethodReferenceInStatementInMethodInClassIdentifierIsCompareByAge(int statementPosition, int methodPosition,
+                                                                                      int classPosition, String expectedName) {
+        Statement statementUnderTest = getStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        assertEquals(1, statementUnderTest.findAll(MethodReferenceExpr.class).size());
+        MethodReferenceExpr methodReferenceUnderTest = statementUnderTest.findFirst(MethodReferenceExpr.class).get();
+        assertThat(methodReferenceUnderTest.getIdentifier(), is(expectedName));
+    }
+
+    @Then("method $methodPosition class $classPosition is a default method")
+    public void thenMethodClassIsADefaultMethod(int methodPosition, int classPosition) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration methodUnderTest = getMethodByPositionAndClassPosition(compilationUnit,
+                methodPosition, classPosition);
+        assertThat(methodUnderTest.isDefault(), is(true));
+    }
+
+    @Then("method $methodPosition class $classPosition is not a default method")
+    public void thenMethodClassIsNotADefaultMethod(int methodPosition, int classPosition) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration methodUnderTest = getMethodByPositionAndClassPosition(compilationUnit,
+                methodPosition, classPosition);
+        assertThat(methodUnderTest.isDefault(), is(false));
+    }
+
+    private Statement getStatementInMethodInClass(int statementPosition, int methodPosition, int classPosition) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
+        return method.getBody().get().getStatement(statementPosition - 1);
+    }
+
+    private LambdaExpr getLambdaExprInStatementInMethodInClass(int statementPosition, int methodPosition, int classPosition) {
+        Statement statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition);
+        VariableDeclarationExpr expression = ((ExpressionStmt) statement).getExpression().asVariableDeclarationExpr();
+        VariableDeclarator variableDeclarator = expression.getVariable(0);
+        return (LambdaExpr) variableDeclarator.getInitializer().orElse(null);
+    }
+
+    @Then("all nodes refer to their parent")
+    public void allNodesReferToTheirParent() {
+        assertAllNodesOfTheCompilationUnitHaveTheirParentSet("cu1");
+    }
+
+    @Then("all nodes of the second compilation unit refer to their parent")
+    public void thenAllNodesOfTheSecondCompilationUnitReferToTheirParent() {
+        assertAllNodesOfTheCompilationUnitHaveTheirParentSet("cu2");
+    }
+
+    private void assertAllNodesOfTheCompilationUnitHaveTheirParentSet(String stateKey) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get(stateKey);
+        ExistenceOfParentNodeVerifier parentVerifier = new ExistenceOfParentNodeVerifier();
+        parentVerifier.verify(compilationUnit);
+    }
+
+    @Then("ThenExpr in the conditional expression of the statement $statementPosition in method $methodPosition in class $classPosition is LambdaExpr")
+    public void thenLambdaInConditionalExpressionInMethodInClassIsParentOfContainedParameter(int statementPosition, int methodPosition, int classPosition) {
+        ReturnStmt returnStmt = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asReturnStmt();
+        ConditionalExpr conditionalExpr = (ConditionalExpr) returnStmt.getExpression().orElse(null);
+        assertThat(conditionalExpr.getElseExpr().getClass().getName(), is(LambdaExpr.class.getName()));
+    }
+
+    @Then("the begin line is $line")
+    public void thenTheBeginLineIs(int line) {
+        Node node = (Node) state.get("selectedNode");
+        assertEquals(line, node.getBegin().get().line);
+    }
+
+    @Then("the begin column is $column")
+    public void thenTheBeginColumnIs(int column) {
+        Node node = (Node) state.get("selectedNode");
+        assertEquals(column, node.getBegin().get().column);
+    }
+
+    @Then("the end line is $line")
+    public void thenTheEndLineIs(int line) {
+        Node node = (Node) state.get("selectedNode");
+        assertEquals(line, node.getEnd().get().line);
+    }
+
+    @Then("the end column is $column")
+    public void thenTheEndColumnIs(int column) {
+        Node node = (Node) state.get("selectedNode");
+        assertEquals(column, node.getEnd().get().column);
+    }
+
+    @Then("no errors are reported")
+    public void thenNoErrorsAreReported() {
+        // this is present just for readability in the scenario specification
+        // if the code is not parsed then exceptions are thrown before reaching this step
+    }
+
+    @Then("the package name is $package")
+    public void thenThePackageNameIs(String expected) {
+        PackageDeclaration node = (PackageDeclaration) state.get("selectedNode");
+        assertEquals(expected, node.getNameAsString());
+        assertEquals(expected, node.getName().toString());
+    }
+
+    @Then("the type's diamond operator flag should be $expectedValue")
+    public void thenTheUsesDiamondOperatorShouldBeBooleanAsString(boolean expectedValue) {
+        ObjectCreationExpr expr = (ObjectCreationExpr) state.get("selectedNode");
+        assertEquals(expectedValue, expr.getType().isUsingDiamondOperator());
+    }
+
+    @Then("the Java parser cannot parse it because of an error")
+    public void javaParserCannotParseBecauseOfLexicalErrors() {
+        ParseResult<CompilationUnit> result = new JavaParser().parse(COMPILATION_UNIT, provider(sourceUnderTest));
+        if (result.isSuccessful()) {
+            fail("Lexical error expected");
+        }
+    }
+
+    @Then("the assignExpr produced doesn't have a null target")
+    public void thenTheAssignExprProducedDoesntHaveANullTarget() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        ClassOrInterfaceDeclaration classDeclaration = compilationUnit.getType(0).asClassOrInterfaceDeclaration();
+        ConstructorDeclaration ctor = classDeclaration.getMember(1).asConstructorDeclaration();
+        ExpressionStmt assignStmt = ctor.getBody().getStatement(0).asExpressionStmt();
+        AssignExpr assignExpr = assignStmt.getExpression().asAssignExpr();
+        assertNotNull(assignExpr.getTarget());
+        assertEquals(NameExpr.class, assignExpr.getTarget().getClass());
+        assertEquals(assignExpr.getTarget().asNameExpr().getNameAsString(), "mString");
+    }
+
+    private void setSelectedNodeFromCompilationUnit(Class<? extends Node> nodeType) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        List<? extends Node> nodes = compilationUnit.findAll(nodeType);
+        if (nodes.size() != 1) {
+            throw new RuntimeException(format("Exactly one %s expected", nodeType.getSimpleName()));
+        }
+        state.put("selectedNode", nodes.get(0));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/PositionRangeSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/PositionRangeSteps.java
new file mode 100644
index 0000000..0d7fd89
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/PositionRangeSteps.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.Position;
+import com.github.javaparser.Range;
+import org.jbehave.core.annotations.BeforeScenario;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+import static com.github.javaparser.Position.pos;
+import static com.github.javaparser.Range.range;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class PositionRangeSteps {
+
+    private Position position;
+    private Position secondPosition;
+    private Range range;
+    private Range secondRange;
+
+    @BeforeScenario
+    public void reset() {
+        position = null;
+        secondPosition = null;
+        range = null;
+        secondRange = null;
+    }
+    /*
+	 * Given steps
+     */
+
+    @Given("the position $line, $column")
+    public void givenThePosition(int line, int column) {
+        this.position = pos(line, column);
+    }
+
+    @Given("the range $line1, $column1 - $line2, $column2")
+    public void givenTheRange(int line1, int column1, int line2, int column2) {
+        this.range = range(line1, column1, line2, column2);
+    }
+
+    /*
+	 * When steps
+     */
+
+    @When("I compare to position $line, $column")
+    public void iCompareToPosition(int line, int column) {
+        secondPosition = pos(line, column);
+    }
+
+    @When("I compare to range $line1, $column1 - $line2, $column2")
+    public void whenICompareToRange(int line1, int column1, int line2, int column2) {
+        this.secondRange = range(line1, column1, line2, column2);
+    }
+
+    /*
+	 * Then steps
+     */
+
+    @Then("the positions are equal")
+    public void thenThePositionsAreEqual() {
+        assertTrue(position.equals(secondPosition));
+    }
+
+    @Then("it is after the {first|} position")
+    public void thenItIsAfterTheFirstPosition() {
+        if (secondPosition != null) {
+            assertTrue(secondPosition.isAfter(position));
+        } else {
+            assertTrue(secondRange.isAfter(position));
+        }
+    }
+
+    @Then("it is before the {first|} position")
+    public void thenItIsBeforeTheFirstPosition() {
+        if (secondPosition != null) {
+            assertTrue(secondPosition.isBefore(position));
+        } else {
+            assertTrue(secondRange.isBefore(position));
+        }
+    }
+
+    @Then("the positions are not equal")
+    public void thenThePositionsAreNotEqual() {
+        assertFalse(position.equals(secondPosition));
+    }
+
+    @Then("it is not after the {first|} position")
+    public void thenItIsNotAfterTheFirstPosition() {
+        assertFalse(secondPosition.isAfter(position));
+    }
+
+    @Then("it is not before the {first|} position")
+    public void thenItIsNotBeforeTheFirstPosition() {
+        assertFalse(secondPosition.isBefore(position));
+    }
+
+    @Then("the ranges are equal")
+    public void theRangesAreEqual() {
+        assertTrue(range.equals(secondRange));
+    }
+
+    @Then("it is contained in the first range")
+    public void itIsContainedInTheFirstRange() {
+        assertTrue(range.contains(secondRange));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/PrettyPrintingSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/PrettyPrintingSteps.java
new file mode 100644
index 0000000..1dcd802
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/PrettyPrintingSteps.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.visitor.ModifierVisitor;
+import com.github.javaparser.printer.PrettyPrinterConfiguration;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.Utils.readerToString;
+import static org.junit.Assert.assertEquals;
+
+public class PrettyPrintingSteps {
+
+    private Node resultNode;
+    private String sourceUnderTest;
+
+    @Given("the {class|compilation unit|expression|block|statement|import|annotation|body|class body|interface body}:$classSrc")
+    public void givenTheClass(String classSrc) {
+        this.sourceUnderTest = classSrc.trim();
+    }
+
+    @Given("the {class|compilation unit|expression|block|statement|import|annotation|body|class body|interface body} in the file \"$classFile\"")
+    public void givenTheClassInTheFile(String classFile) throws URISyntaxException, IOException, ParseException {
+        URL url = getClass().getResource("../samples/" + classFile);
+        sourceUnderTest = readerToString(new FileReader(new File(url.toURI()))).trim();
+    }
+
+    @When("the {class|compilation unit} is parsed by the Java parser")
+    public void whenTheClassIsParsedByTheJavaParser() {
+        resultNode = parse(sourceUnderTest);
+    }
+
+    @When("the expression is parsed by the Java parser")
+    public void whenTheExpressionIsParsedByTheJavaParser() {
+        resultNode = parseExpression(sourceUnderTest);
+    }
+
+    @When("the block is parsed by the Java parser")
+    public void whenTheBlockIsParsedByTheJavaParser() {
+        resultNode = parseBlock(sourceUnderTest);
+    }
+
+    @When("the statement is parsed by the Java parser")
+    public void whenTheStatementIsParsedByTheJavaParser() {
+        resultNode = parseStatement(sourceUnderTest);
+    }
+
+    @When("the import is parsed by the Java parser")
+    public void whenTheImportIsParsedByTheJavaParser() {
+        resultNode = parseImport(sourceUnderTest);
+    }
+
+    @When("the annotation is parsed by the Java parser")
+    public void whenTheAnnotationIsParsedByTheJavaParser() {
+        resultNode = parseAnnotation(sourceUnderTest);
+    }
+
+    @When("the annotation body declaration is parsed by the Java parser")
+    public void whenTheBodyDeclarationIsParsedByTheJavaParser() {
+        resultNode = parseAnnotationBodyDeclaration(sourceUnderTest);
+    }
+
+    @When("the class body declaration is parsed by the Java parser")
+    public void whenTheClassBodyDeclarationIsParsedByTheJavaParser() {
+        resultNode = parseBodyDeclaration(sourceUnderTest);
+    }
+
+    @When("the interface body declaration is parsed by the Java parser")
+    public void whenTheInterfaceBodyDeclarationIsParsedByTheJavaParser() {
+        resultNode = parseBodyDeclaration(sourceUnderTest);
+    }
+
+    @When("the class is visited by an empty ModifierVisitorAdapter")
+    public void whenTheClassIsVisitedByAnEmptyModifierVisitorAdapter() {
+        (new ModifierVisitor<Void>() {
+        }).visit((CompilationUnit) resultNode, null);
+    }
+
+    @Then("it is printed as:$src")
+    public void isPrintedAs(String src) {
+        assertEquals(src.trim(), resultNode.toString().trim());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/SharedSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/SharedSteps.java
new file mode 100644
index 0000000..53b7c44
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/SharedSteps.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+import org.hamcrest.CoreMatchers;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Map;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.text.IsEqualIgnoringWhiteSpace.equalToIgnoringWhiteSpace;
+import static org.junit.Assert.assertThat;
+
+public class SharedSteps {
+
+    /* Map that maintains shares state across step classes.  If manipulating the objects in the map you must update the state */
+    private Map<String, Object> state;
+
+    public SharedSteps(Map<String, Object> state) {
+        this.state = state;
+    }
+
+    /*
+     * Given steps
+     */
+
+    @Given("a CompilationUnit")
+    public void givenACompilationUnit() {
+        state.put("cu1", new CompilationUnit());
+    }
+
+    @Given("a second CompilationUnit")
+    public void givenASecondCompilationUnit() {
+        state.put("cu2", new CompilationUnit());
+    }
+
+    /*
+     * When steps
+     */
+
+    @When("the following source is parsed:$classSrc")
+    public void whenTheFollowingSourceIsParsed(String classSrc) {
+        state.put("cu1", JavaParser.parse(classSrc.trim()));
+    }
+
+    @When("the following source is parsed (trimming space):$classSrc")
+    public void whenTheFollowingSourceIsParsedTrimmingSpace(String classSrc) {
+        state.put("cu1", JavaParser.parse(classSrc.trim()));
+    }
+
+    @When("the following sources is parsed by the second CompilationUnit:$classSrc")
+    public void whenTheFollowingSourcesIsParsedBytTheSecondCompilationUnit(String classSrc) {
+        state.put("cu2", JavaParser.parse(classSrc.trim()));
+    }
+
+    @When("file \"$fileName\" is parsed")
+    public void whenTheJavaFileIsParsed(String fileName) throws IOException, URISyntaxException {
+        URL url = getClass().getResource("../samples/" + fileName);
+        CompilationUnit compilationUnit = JavaParser.parse(new File(url.toURI()));
+        state.put("cu1", compilationUnit);
+    }
+
+    @Then("the CompilationUnit is equal to the second CompilationUnit")
+    public void thenTheCompilationUnitIsEqualToTheSecondCompilationUnit() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        CompilationUnit compilationUnit2 = (CompilationUnit) state.get("cu2");
+
+        assertThat(compilationUnit, is(equalTo(compilationUnit2)));
+    }
+
+    @Then("the CompilationUnit has the same hashcode to the second CompilationUnit")
+    public void thenTheCompilationUnitHasTheSameHashcodeToTheSecondCompilationUnit() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        CompilationUnit compilationUnit2 = (CompilationUnit) state.get("cu2");
+
+        assertThat(compilationUnit.hashCode(), is(equalTo(compilationUnit2.hashCode())));
+    }
+
+    @Then("the CompilationUnit is not equal to the second CompilationUnit")
+    public void thenTheCompilationUnitIsNotEqualToTheSecondCompilationUnit() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        CompilationUnit compilationUnit2 = (CompilationUnit) state.get("cu2");
+
+        assertThat(compilationUnit, not(equalTo(compilationUnit2)));
+    }
+
+    @Then("the CompilationUnit has a different hashcode to the second CompilationUnit")
+    public void thenTheCompilationUnitHasADifferentHashcodeToTheSecondCompilationUnit() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        CompilationUnit compilationUnit2 = (CompilationUnit) state.get("cu2");
+
+        assertThat(compilationUnit.hashCode(), not(equalTo(compilationUnit2.hashCode())));
+    }
+
+    @Then("the expected source should be:$classSrc")
+    public void thenTheExpectedSourcesShouldBe(String classSrc) {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        assertThat(compilationUnit.toString(), CoreMatchers.is(equalToIgnoringWhiteSpace(classSrc)));
+    }
+
+    public static <T extends BodyDeclaration<?>> T getMemberByTypeAndPosition(TypeDeclaration<?> typeDeclaration, int position, Class<T> typeClass) {
+        int typeCount = 0;
+        for (BodyDeclaration<?> declaration : typeDeclaration.getMembers()) {
+            if (declaration.getClass().equals(typeClass)) {
+                if (typeCount == position) {
+                    return (T) declaration;
+                }
+                typeCount++;
+            }
+        }
+        throw new IllegalArgumentException("No member " + typeClass + " at position: " + position);
+    }
+
+    public static MethodDeclaration getMethodByPositionAndClassPosition(CompilationUnit compilationUnit,
+                                                                        int methodPosition, int classPosition) {
+        TypeDeclaration<?> type = compilationUnit.getType(classPosition - 1);
+
+        int memberCount = 0;
+        int methodCount = 0;
+        for (BodyDeclaration<?> bodyDeclaration : type.getMembers()) {
+            if (bodyDeclaration instanceof MethodDeclaration) {
+                if (methodCount == methodPosition - 1) {
+                    return (MethodDeclaration) type.getMember(memberCount);
+                }
+                methodCount++;
+            }
+            memberCount++;
+        }
+        throw new IllegalArgumentException("Method not found at position " + methodPosition + "in class " + classPosition);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/VisitorSteps.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/VisitorSteps.java
new file mode 100644
index 0000000..ba20eaf
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/steps/VisitorSteps.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.steps;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.visitor.CloneVisitor;
+import com.github.javaparser.ast.visitor.GenericListVisitorAdapter;
+import com.github.javaparser.ast.visitor.GenericVisitorAdapter;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+import com.github.javaparser.bdd.visitors.PositionTestVisitor;
+import org.jbehave.core.annotations.Given;
+import org.jbehave.core.annotations.Then;
+import org.jbehave.core.annotations.When;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public class VisitorSteps {
+
+    /* Fields used to maintain step state within this step class */
+    private VoidVisitorAdapter<AtomicReference<String>> toUpperCaseVariableNameVisitor;
+    private VoidVisitorAdapter<AtomicReference<String>> collectVariableNameVisitor;
+    private PositionTestVisitor positionTestVisitor;
+    private GenericVisitorAdapter<String, Void> nameReturningVisitor;
+    private GenericListVisitorAdapter<String, Void> allNameReturningVisitor;
+    private AtomicReference<String> collectedVariableName;
+    private String returnedVariableName;
+    private List<String> returnedVariableNames;
+
+    /* Map that maintains shares state across step classes.  If manipulating the objects in the map you must update the state */
+    private Map<String, Object> state;
+
+    public VisitorSteps(Map<String, Object> state) {
+        this.state = state;
+    }
+
+    @Given("a VoidVisitorAdapter with a visit method that changes variable names to uppercase")
+    public void givenAVoidVisitorAdapterWithAVisitMethodThatChangesVariableNamesToUppercase() {
+        toUpperCaseVariableNameVisitor = new VoidVisitorAdapter<AtomicReference<String>>() {
+            @Override
+            public void visit(VariableDeclarator n, AtomicReference<String> arg) {
+                n.setName(n.getNameAsString().toUpperCase());
+            }
+        };
+    }
+
+    @Given("a VoidVisitorAdapter with a visit method and collects the variable names")
+    public void givenAVoidVisitorAdapterWithAVisitMethodThatCollectsTheVariableName() {
+        collectVariableNameVisitor = new VoidVisitorAdapter<AtomicReference<String>>() {
+            @Override
+            public void visit(VariableDeclarator n, AtomicReference<String> arg) {
+                arg.set(arg.get() + n.getName() + ";");
+            }
+
+            @Override
+            public void visit(Parameter n, AtomicReference<String> arg) {
+                arg.set(arg.get() + n.getName() + ";");
+            }
+        };
+    }
+
+    @Given("a GenericVisitorAdapter with a visit method that returns variable names")
+    public void givenAGenericVisitorAdapterWithAVisitMethodThatReturnsVariableNames() {
+        nameReturningVisitor = new GenericVisitorAdapter<String, Void>() {
+            @Override
+            public String visit(VariableDeclarator n, Void arg) {
+                return n.getNameAsString();
+            }
+        };
+    }
+
+    @Given("a GenericListVisitorAdapter with a visit method that returns all variable names")
+    public void givenAGenericListVisitorAdapterWithAVisitMethodThatReturnsAllVariableNames() {
+        allNameReturningVisitor = new GenericListVisitorAdapter<String, Void>() {
+            @Override
+            public List<String> visit(VariableDeclarator n, Void arg) {
+                return Collections.singletonList(n.getNameAsString());
+            }
+        };
+    }
+
+    @Given("a VoidVisitorAdapter with a visit method that asserts sensible line positions")
+    public void givenAVoidVisitorAdapterWithAVisitMethodThatAssertsSensibleLinePositions() {
+        positionTestVisitor = new PositionTestVisitor();
+    }
+
+    @When("the CompilationUnit is cloned to the second CompilationUnit")
+    public void whenTheSecondCompilationUnitIsCloned() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        CompilationUnit compilationUnit2 = (CompilationUnit) compilationUnit.accept(new CloneVisitor(), null);
+        state.put("cu2", compilationUnit2);
+    }
+
+    @When("the CompilationUnit is visited by the to uppercase visitor")
+    public void whenTheCompilationUnitIsVisitedByTheVistor() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        toUpperCaseVariableNameVisitor.visit(compilationUnit, null);
+        state.put("cu1", compilationUnit);
+    }
+
+    @When("the CompilationUnit is visited by the variable name collector visitor")
+    public void whenTheCompilationUnitIsVisitedByTheVariableNameCollectorVisitor() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        collectedVariableName = new AtomicReference<>("");
+        collectVariableNameVisitor.visit(compilationUnit, collectedVariableName);
+    }
+
+    @When("the CompilationUnit is visited by the visitor that returns variable names")
+    public void whenTheCompilationUnitIsVisitedByTheVisitorThatReturnsVariableNames() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        returnedVariableName = nameReturningVisitor.visit(compilationUnit, null);
+    }
+
+    @When("the CompilationUnit is visited by the visitor that returns all variable names")
+    public void whenTheCompilationUnitIsVisitedByTheVisitorThatReturnsAllVariableNames() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        returnedVariableNames = allNameReturningVisitor.visit(compilationUnit, null);
+    }
+
+    @When("the CompilationUnit is visited by the PositionTestVisitor")
+    public void whenTheCompilationUnitIsVisitedByThePositionTestVisitor() {
+        CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
+        compilationUnit.accept(positionTestVisitor, null);
+    }
+
+    @Then("the collected variable name is \"$nameUnderTest\"")
+    public void thenTheCollectedVariableNameIs(String nameUnderTest) {
+        assertThat(collectedVariableName.get(), is(nameUnderTest));
+    }
+
+    @Then("the return variable name is \"$nameUnderTest\"")
+    public void thenTheReturnVariableNameIs(String nameUnderTest) {
+        assertThat(returnedVariableName, is(nameUnderTest));
+    }
+
+    @Then("the first return variable name is \"$nameUnderTest\"")
+    public void thenTheFirstReturnVariableNameIs(String nameUnderTest) {
+        assertThat(returnedVariableNames.get(0), is(nameUnderTest));
+    }
+
+    @Then("the total number of nodes visited is $expectedCount")
+    public void thenTheTotalNumberOfNodesVisitedIs(int expectedCount) {
+        assertThat(positionTestVisitor.getNumberOfNodesVisited(), is(expectedCount));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/bdd/visitors/PositionTestVisitor.java b/javaparser-testing/src/test/java/com/github/javaparser/bdd/visitors/PositionTestVisitor.java
new file mode 100644
index 0000000..bfa331f
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/bdd/visitors/PositionTestVisitor.java
@@ -0,0 +1,553 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.bdd.visitors;
+
+import com.github.javaparser.Position;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.lessThanOrEqualTo;
+import static org.hamcrest.core.Is.is;
+
+public class PositionTestVisitor extends VoidVisitorAdapter<Object> {
+
+    private int numberOfNodesVisited;
+
+    @Override
+    public void visit(final AnnotationDeclaration n, final Object arg) {
+        doTest(n);
+        doTest(n.getName());
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final AnnotationMemberDeclaration n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ArrayAccessExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ArrayCreationExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ArrayInitializerExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final AssertStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final AssignExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final BinaryExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final BlockComment n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final BlockStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final BooleanLiteralExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final BreakStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final CastExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final CatchClause n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(LambdaExpr n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(MethodReferenceExpr n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(TypeExpr n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final CharLiteralExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ClassExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceDeclaration n, final Object arg) {
+        doTest(n);
+        doTest(n.getName());
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceType n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final CompilationUnit n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ConditionalExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ConstructorDeclaration n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ContinueStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final DoStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final DoubleLiteralExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final EmptyStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final EnclosedExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final EnumConstantDeclaration n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final EnumDeclaration n, final Object arg) {
+        doTest(n);
+        doTest(n.getName());
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ExplicitConstructorInvocationStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ExpressionStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final FieldAccessExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final FieldDeclaration n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ForeachStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ForStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final IfStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final InitializerDeclaration n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final InstanceOfExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final IntegerLiteralExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final JavadocComment n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final LabeledStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final LineComment n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final LongLiteralExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final MarkerAnnotationExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final MemberValuePair n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final MethodCallExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final MethodDeclaration n, final Object arg) {
+        doTest(n);
+        doTest(n.getName());
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final NameExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final NormalAnnotationExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final NullLiteralExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ObjectCreationExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final PackageDeclaration n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final Parameter n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final PrimitiveType n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final Name n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(SimpleName n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(ArrayType n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(ArrayCreationLevel n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final IntersectionType n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(UnionType n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ReturnStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final SingleMemberAnnotationExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final StringLiteralExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final SuperExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final SwitchEntryStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final SwitchStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final SynchronizedStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ThisExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final ThrowStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final TryStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final LocalClassDeclarationStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final TypeParameter n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final UnaryExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final VariableDeclarationExpr n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final VariableDeclarator n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final VoidType n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final WhileStmt n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(final WildcardType n, final Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    @Override
+    public void visit(UnknownType n, Object arg) {
+        doTest(n);
+        super.visit(n, arg);
+    }
+
+    private void doTest(final Node node) {
+        Position begin = node.getRange().get().begin;
+        Position end = node.getRange().get().end;
+        assertThat(begin.line, is(greaterThanOrEqualTo(0)));
+        assertThat(begin.column, is(greaterThanOrEqualTo(0)));
+        assertThat(end.line, is(greaterThanOrEqualTo(0)));
+        assertThat(end.column, is(greaterThanOrEqualTo(0)));
+
+        if (begin.line == end.line) {
+            assertThat(begin.column, is(lessThanOrEqualTo(end.column)));
+        } else {
+            assertThat(begin.line, is(lessThanOrEqualTo(end.line)));
+        }
+        numberOfNodesVisited++;
+    }
+
+    public int getNumberOfNodesVisited() {
+        return numberOfNodesVisited;
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/ClassOrInterfaceDeclarationBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/ClassOrInterfaceDeclarationBuildersTest.java
new file mode 100644
index 0000000..aff5354
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/ClassOrInterfaceDeclarationBuildersTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.function.Function;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class ClassOrInterfaceDeclarationBuildersTest {
+    CompilationUnit cu;
+
+    @Before
+    public void setup() {
+        cu = new CompilationUnit();
+    }
+
+    @After
+    public void teardown() {
+        cu = null;
+    }
+
+    @Test
+    public void testAddExtends() {
+        ClassOrInterfaceDeclaration testClass = cu.addClass("test");
+        testClass.addExtendedType(List.class);
+        assertEquals(1, cu.getImports().size());
+        assertEquals("import " + List.class.getName() + ";" + EOL,
+                cu.getImport(0).toString());
+        assertEquals(1, testClass.getExtendedTypes().size());
+        assertEquals(List.class.getSimpleName(), testClass.getExtendedTypes(0).getNameAsString());
+    }
+
+    @Test
+    public void testAddImplements() {
+        ClassOrInterfaceDeclaration testClass = cu.addClass("test");
+        testClass.addImplementedType(Function.class);
+        assertEquals(1, cu.getImports().size());
+        assertEquals("import " + Function.class.getName() + ";" + EOL,
+                cu.getImport(0).toString());
+        assertEquals(1, testClass.getImplementedTypes().size());
+        assertEquals(Function.class.getSimpleName(), testClass.getImplementedTypes(0).getNameAsString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/CompilationUnitBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/CompilationUnitBuildersTest.java
new file mode 100644
index 0000000..11ac7e9
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/CompilationUnitBuildersTest.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+
+public class CompilationUnitBuildersTest {
+    private final CompilationUnit cu = new CompilationUnit();
+
+    @Test
+    public void testAddImport() {
+        cu.addImport(Map.class);
+        cu.addImport(Map.class);
+        cu.addImport(List.class);
+        assertEquals(2, cu.getImports().size());
+        cu.addImport("myImport");
+        assertEquals(3, cu.getImports().size());
+        assertEquals("import " + Map.class.getName() + ";" + EOL, cu.getImport(0).toString());
+        assertEquals("import " + List.class.getName() + ";" + EOL, cu.getImport(1).toString());
+        assertEquals("import myImport;" + EOL, cu.getImport(2).toString());
+    }
+
+    class testInnerClass {
+
+    }
+
+    @Test
+    public void testAddImportAnonymousClass() {
+        cu.addImport(testInnerClass.class);
+        assertEquals("import " + testInnerClass.class.getName().replace("$", ".") + ";" + EOL,
+                cu.getImport(0).toString());
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void testAddImportInnerClass() {
+        Object anonymous = new Object() {
+
+        };
+        cu.addImport(anonymous.getClass());
+    }
+
+    @Test
+    public void testAddClass() {
+        ClassOrInterfaceDeclaration myClassDeclaration = cu.addClass("testClass", Modifier.PRIVATE);
+        assertEquals(1, cu.getTypes().size());
+        assertEquals("testClass", cu.getType(0).getNameAsString());
+        assertEquals(ClassOrInterfaceDeclaration.class, cu.getType(0).getClass());
+        assertTrue(myClassDeclaration.isPrivate());
+        assertFalse(myClassDeclaration.isInterface());
+    }
+
+    @Test
+    public void testAddInterface() {
+        ClassOrInterfaceDeclaration myInterfaceDeclaration = cu.addInterface("testInterface");
+        assertEquals(1, cu.getTypes().size());
+        assertEquals("testInterface", cu.getType(0).getNameAsString());
+        assertTrue(myInterfaceDeclaration.isPublic());
+        assertEquals(ClassOrInterfaceDeclaration.class, cu.getType(0).getClass());
+        assertTrue(myInterfaceDeclaration.isInterface());
+    }
+
+    @Test
+    public void testAddEnum() {
+        EnumDeclaration myEnumDeclaration = cu.addEnum("test");
+        assertEquals(1, cu.getTypes().size());
+        assertEquals("test", cu.getType(0).getNameAsString());
+        assertTrue(myEnumDeclaration.isPublic());
+        assertEquals(EnumDeclaration.class, cu.getType(0).getClass());
+    }
+
+    @Test
+    public void testAddAnnotationDeclaration() {
+        AnnotationDeclaration myAnnotationDeclaration = cu.addAnnotationDeclaration("test");
+        assertEquals(1, cu.getTypes().size());
+        assertEquals("test", cu.getType(0).getNameAsString());
+        assertTrue(myAnnotationDeclaration.isPublic());
+        assertEquals(AnnotationDeclaration.class, cu.getType(0).getClass());
+    }
+
+    @Test
+    public void testGetClassByName() {
+        assertEquals(cu.addClass("test"), cu.getClassByName("test").get());
+    }
+
+    @Test
+    public void testGetInterfaceByName() {
+        assertEquals(cu.addInterface("test"), cu.getInterfaceByName("test").get());
+    }
+
+    @Test
+    public void testGetEnumByName() {
+        assertEquals(cu.addEnum("test"), cu.getEnumByName("test").get());
+    }
+
+    @Test
+    public void testGetAnnotationDeclarationByName() {
+        assertEquals(cu.addAnnotationDeclaration("test"), cu.getAnnotationDeclarationByName("test").get());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/EnumDeclarationBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/EnumDeclarationBuildersTest.java
new file mode 100644
index 0000000..048307d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/EnumDeclarationBuildersTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.function.Function;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class EnumDeclarationBuildersTest {
+    private final CompilationUnit cu = new CompilationUnit();
+
+    @Test
+    public void testAddImplements() {
+        EnumDeclaration testEnum = cu.addEnum("test");
+        testEnum.addImplementedType(Function.class);
+        assertEquals(1, cu.getImports().size());
+        assertEquals("import " + Function.class.getName() + ";" + EOL,
+                cu.getImport(0).toString());
+        assertEquals(1, testEnum.getImplementedTypes().size());
+        assertEquals(Function.class.getSimpleName(), testEnum.getImplementedTypes(0).getNameAsString());
+    }
+
+    @Test
+    public void testAddEnumConstant() {
+        EnumDeclaration testEnum = cu.addEnum("test");
+        testEnum.addEnumConstant("MY_ENUM_CONSTANT");
+        assertEquals(1, testEnum.getEntries().size());
+        assertEquals("MY_ENUM_CONSTANT", testEnum.getEntry(0).getNameAsString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/FieldDeclarationBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/FieldDeclarationBuildersTest.java
new file mode 100644
index 0000000..7824add
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/FieldDeclarationBuildersTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import static com.github.javaparser.ast.type.PrimitiveType.intType;
+import static org.junit.Assert.assertEquals;
+
+public class FieldDeclarationBuildersTest {
+    private final CompilationUnit cu = new CompilationUnit();
+    private ClassOrInterfaceDeclaration testClass = cu.addClass("testClass");
+    private EnumDeclaration testEnum = cu.addEnum("testEnum");
+
+    @Test(expected = IllegalStateException.class)
+    public void testOrphanFieldGetter() {
+        new FieldDeclaration().createGetter();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testOrphanFieldSetter() {
+        new FieldDeclaration().createSetter();
+    }
+
+    @Test
+    public void testCreateGetterInAClass() {
+        testClass.addPrivateField(int.class, "myField").createGetter();
+        assertEquals(2, testClass.getMembers().size());
+        assertEquals(MethodDeclaration.class, testClass.getMember(1).getClass());
+        List<MethodDeclaration> methodsWithName = testClass.getMethodsByName("getMyField");
+        assertEquals(1, methodsWithName.size());
+        MethodDeclaration getter = methodsWithName.get(0);
+        assertEquals("getMyField", getter.getNameAsString());
+        assertEquals("int", getter.getType().toString());
+        assertEquals(ReturnStmt.class, getter.getBody().get().getStatement(0).getClass());
+    }
+
+    @Test
+    public void testCreateSetterInAClass() {
+        testClass.addPrivateField(int.class, "myField").createSetter();
+        assertEquals(2, testClass.getMembers().size());
+        assertEquals(MethodDeclaration.class, testClass.getMember(1).getClass());
+        List<MethodDeclaration> methodsWithName = testClass.getMethodsByName("setMyField");
+        assertEquals(1, methodsWithName.size());
+        MethodDeclaration setter = methodsWithName.get(0);
+        assertEquals("setMyField", setter.getNameAsString());
+        assertEquals("int", setter.getParameter(0).getType().toString());
+        assertEquals(ExpressionStmt.class, setter.getBody().get().getStatement(0).getClass());
+        assertEquals("this.myField = myField;", setter.getBody().get().getStatement(0).toString());
+    }
+
+    @Test
+    public void testCreateGetterInEnum() {
+        testEnum.addPrivateField(int.class, "myField").createGetter();
+        assertEquals(2, testEnum.getMembers().size());
+        assertEquals(MethodDeclaration.class, testEnum.getMember(1).getClass());
+        List<MethodDeclaration> methodsWithName = testEnum.getMethodsByName("getMyField");
+        assertEquals(1, methodsWithName.size());
+        MethodDeclaration getter = methodsWithName.get(0);
+        assertEquals("getMyField", getter.getNameAsString());
+        assertEquals("int", getter.getType().toString());
+        assertEquals(ReturnStmt.class, getter.getBody().get().getStatement(0).getClass());
+    }
+
+    @Test
+    public void testCreateSetterInEnum() {
+        testEnum.addPrivateField(int.class, "myField").createSetter();
+        assertEquals(2, testEnum.getMembers().size());
+        assertEquals(MethodDeclaration.class, testEnum.getMember(1).getClass());
+        List<MethodDeclaration> methodsWithName = testEnum.getMethodsByName("setMyField");
+        assertEquals(1, methodsWithName.size());
+        MethodDeclaration setter = methodsWithName.get(0);
+        assertEquals("setMyField", setter.getNameAsString());
+        assertEquals("int", setter.getParameter(0).getType().toString());
+        assertEquals(ExpressionStmt.class, setter.getBody().get().getStatement(0).getClass());
+        assertEquals("this.myField = myField;", setter.getBody().get().getStatement(0).toString());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testCreateGetterWithANonValidField() {
+        FieldDeclaration myPrivateField = testClass.addPrivateField(int.class, "myField");
+        myPrivateField.getVariables().add(new VariableDeclarator(intType(), "secondField"));
+        myPrivateField.createGetter();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void testCreateSetterWithANonValidField() {
+        FieldDeclaration myPrivateField = testClass.addPrivateField(int.class, "myField");
+        myPrivateField.getVariables().add(new VariableDeclarator(intType(), "secondField"));
+        myPrivateField.createSetter();
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithAnnotationsBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithAnnotationsBuildersTest.java
new file mode 100644
index 0000000..b722016
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithAnnotationsBuildersTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class NodeWithAnnotationsBuildersTest {
+    private CompilationUnit cu = new CompilationUnit();
+    private ClassOrInterfaceDeclaration testClass = cu.addClass("testClass"); ;
+
+    @interface hey {
+
+    }
+
+    @Test
+    public void testAddAnnotation() {
+        NormalAnnotationExpr annotation = testClass.addAndGetAnnotation(hey.class);
+        assertEquals("import com.github.javaparser.builders.NodeWithAnnotationsBuildersTest.hey;", cu.getImport(0).toString().trim());
+        assertEquals(1, testClass.getAnnotations().size());
+        assertEquals(annotation, testClass.getAnnotation(0));
+        assertEquals(NormalAnnotationExpr.class, testClass.getAnnotation(0).getClass());
+    }
+
+    @Test
+    public void testAddMarkerAnnotation() {
+        testClass.addMarkerAnnotation("test");
+        assertEquals(1, testClass.getAnnotations().size());
+    }
+
+    @Test
+    public void testAddSingleMemberAnnotation() {
+        testClass.addSingleMemberAnnotation("test", "value");
+        assertEquals(1, testClass.getAnnotations().size());
+        assertEquals("value", testClass.getAnnotation(0).asSingleMemberAnnotationExpr().getMemberValue().toString());
+    }
+
+    @Test
+    public void testIsAnnotationPresent() {
+        testClass.addMarkerAnnotation(hey.class);
+        assertTrue(testClass.isAnnotationPresent(hey.class));
+    }
+
+    @Test
+    public void testGetAnnotationByName() {
+        NormalAnnotationExpr annotation = testClass.addAndGetAnnotation(hey.class);
+        assertEquals(annotation, testClass.getAnnotationByName("hey").get());
+    }
+
+    @Test
+    public void testGetAnnotationByClass() {
+        NormalAnnotationExpr annotation = testClass.addAndGetAnnotation(hey.class);
+        assertEquals(annotation, testClass.getAnnotationByClass(hey.class).get());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithMembersBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithMembersBuildersTest.java
new file mode 100644
index 0000000..4ac1f06
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithMembersBuildersTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import org.junit.Test;
+
+import java.util.List;
+
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class NodeWithMembersBuildersTest {
+    private final CompilationUnit cu = new CompilationUnit();
+    private final ClassOrInterfaceDeclaration classDeclaration = cu.addClass("test");
+
+    @Test
+    public void testAddField() {
+        FieldDeclaration addField = classDeclaration.addField(int.class, "fieldName", Modifier.PRIVATE);
+        assertEquals(1, classDeclaration.getMembers().size());
+        assertEquals(addField, classDeclaration.getMember(0));
+        assertEquals("fieldName", addField.getVariable(0).getNameAsString());
+    }
+
+    @Test
+    public void testAddMethod() {
+        MethodDeclaration addMethod = classDeclaration.addMethod("foo", Modifier.PUBLIC);
+        assertEquals(1, classDeclaration.getMembers().size());
+        assertEquals(addMethod, classDeclaration.getMember(0));
+        assertEquals("foo", addMethod.getNameAsString());
+    }
+
+    @Test
+    public void testAddCtor() {
+        ConstructorDeclaration addCtor = classDeclaration.addConstructor(Modifier.PUBLIC);
+        assertEquals(1, classDeclaration.getMembers().size());
+        assertEquals(addCtor, classDeclaration.getMember(0));
+        assertEquals(classDeclaration.getName(), addCtor.getName());
+    }
+
+    @Test
+    public void testAddInitializers() {
+        classDeclaration.addInitializer();
+        assertEquals(1, classDeclaration.getMembers().size());
+        assertEquals(InitializerDeclaration.class, classDeclaration.getMember(0).getClass());
+
+        classDeclaration.addStaticInitializer();
+        assertEquals(2, classDeclaration.getMembers().size());
+        assertEquals(InitializerDeclaration.class, classDeclaration.getMember(0).getClass());
+    }
+
+    @Test
+    public void testGetMethodsWithName() {
+        MethodDeclaration addMethod = classDeclaration.addMethod("foo", Modifier.PUBLIC);
+        MethodDeclaration addMethod2 = classDeclaration.addMethod("foo", Modifier.PUBLIC).addParameter(int.class, "overload");
+        List<MethodDeclaration> methodsByName = classDeclaration.getMethodsByName("foo");
+        assertEquals(2, methodsByName.size());
+        assertTrue(methodsByName.contains(addMethod));
+        assertTrue(methodsByName.contains(addMethod2));
+    }
+
+    @Test
+    public void testGetMethods() {
+        MethodDeclaration addMethod = classDeclaration.addMethod("foo", Modifier.PUBLIC);
+        MethodDeclaration addMethod2 = classDeclaration.addMethod("foo", Modifier.PUBLIC).addParameter(int.class, "overload");
+
+        List<MethodDeclaration> methods = classDeclaration.getMethods();
+
+        assertEquals(2, methods.size());
+        assertTrue(methods.contains(addMethod));
+        assertTrue(methods.contains(addMethod2));
+    }
+
+    @Test
+    public void testGetMethodsWithParameterTypes() {
+        classDeclaration.addMethod("foo", Modifier.PUBLIC);
+        MethodDeclaration addMethod2 = classDeclaration.addMethod("foo", Modifier.PUBLIC).addParameter(int.class, "overload");
+        ClassOrInterfaceType type = parseClassOrInterfaceType("List");
+        type.setTypeArguments(parseClassOrInterfaceType("String"));
+        MethodDeclaration methodWithListParam = classDeclaration.addMethod("fooList", Modifier.PUBLIC).addParameter(type, "overload");
+        MethodDeclaration addMethod3 = classDeclaration.addMethod("foo2", Modifier.PUBLIC).addParameter(int.class, "overload");
+
+        List<MethodDeclaration> methodsByParam = classDeclaration.getMethodsByParameterTypes(int.class);
+        assertEquals(2, methodsByParam.size());
+        assertTrue(methodsByParam.contains(addMethod2));
+        assertTrue(methodsByParam.contains(addMethod3));
+        List<MethodDeclaration> methodsByParam2 = classDeclaration.getMethodsByParameterTypes("List<String>");
+        assertEquals(1, methodsByParam2.size());
+        assertTrue(methodsByParam2.contains(methodWithListParam));
+    }
+
+    @Test
+    public void testGetFieldWithName() {
+        FieldDeclaration addField = classDeclaration.addField(int.class, "fieldName", Modifier.PRIVATE);
+        classDeclaration.addField(float.class, "secondField", Modifier.PRIVATE);
+        FieldDeclaration fieldByName = classDeclaration.getFieldByName("fieldName").get();
+        assertEquals(addField, fieldByName);
+    }
+
+    @Test
+    public void testGetFields() {
+        FieldDeclaration firstField = classDeclaration.addField(int.class, "fieldName", Modifier.PRIVATE);
+        FieldDeclaration secondField = classDeclaration.addField(float.class, "secondField", Modifier.PRIVATE);
+
+        List<FieldDeclaration> fields = classDeclaration.getFields();
+
+        assertTrue(fields.contains(firstField));
+        assertTrue(fields.contains(secondField));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithParametersBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithParametersBuildersTest.java
new file mode 100644
index 0000000..87d0a25
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithParametersBuildersTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class NodeWithParametersBuildersTest {
+    private final CompilationUnit cu = new CompilationUnit();
+
+    @Test
+    public void testAddParameter() {
+        MethodDeclaration addMethod = cu.addClass("test").addMethod("foo", Modifier.PUBLIC);
+        addMethod.addParameter(int.class, "yay");
+        Parameter myNewParam = addMethod.addAndGetParameter(List.class, "myList");
+        assertEquals(1, cu.getImports().size());
+        assertEquals("import " + List.class.getName() + ";" + EOL, cu.getImport(0).toString());
+        assertEquals(2, addMethod.getParameters().size());
+        assertEquals("yay", addMethod.getParameter(0).getNameAsString());
+        assertEquals("List", addMethod.getParameter(1).getType().toString());
+        assertEquals(myNewParam, addMethod.getParameter(1));
+    }
+
+    @Test
+    public void testGetParamByName() {
+        MethodDeclaration addMethod = cu.addClass("test").addMethod("foo", Modifier.PUBLIC);
+        Parameter addAndGetParameter = addMethod.addAndGetParameter(int.class, "yay");
+        assertEquals(addAndGetParameter, addMethod.getParameterByName("yay").get());
+    }
+
+    @Test
+    public void testGetParamByType() {
+        MethodDeclaration addMethod = cu.addClass("test").addMethod("foo", Modifier.PUBLIC);
+        Parameter addAndGetParameter = addMethod.addAndGetParameter(int.class, "yay");
+        assertEquals(addAndGetParameter, addMethod.getParameterByType("int").get());
+        assertEquals(addAndGetParameter, addMethod.getParameterByType(int.class).get());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithThrownExceptionsBuildersTest.java b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithThrownExceptionsBuildersTest.java
new file mode 100644
index 0000000..7975606
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/builders/NodeWithThrownExceptionsBuildersTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.builders;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+import static org.junit.Assert.assertEquals;
+
+public class NodeWithThrownExceptionsBuildersTest {
+    private final CompilationUnit cu = new CompilationUnit();
+
+    @Test
+    public void testThrows() {
+        MethodDeclaration addMethod = cu.addClass("test").addMethod("foo", Modifier.PUBLIC);
+        addMethod.addThrownException(IllegalStateException.class);
+        assertEquals(1, addMethod.getThrownExceptions().size());
+        assertEquals(true, addMethod.isThrown(IllegalStateException.class));
+        addMethod.addThrownException(parseClassOrInterfaceType("Test"));
+        assertEquals(2, addMethod.getThrownExceptions().size());
+        assertEquals("Test", addMethod.getThrownException(1).toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/javadoc/JavadocExtractorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/javadoc/JavadocExtractorTest.java
new file mode 100644
index 0000000..59740b3
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/javadoc/JavadocExtractorTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseProblemException;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+import org.apache.commons.io.Charsets;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.nio.charset.StandardCharsets;
+
+public class JavadocExtractorTest {
+
+    @Test
+    public void canParseAllJavadocsInJavaParser() throws FileNotFoundException {
+        processDir(new File(".."));
+    }
+
+    private void processFile(File file) throws FileNotFoundException {
+        try {
+            CompilationUnit cu = JavaParser.parse(file, StandardCharsets.UTF_8);
+            new VoidVisitorAdapter<Object>() {
+                @Override
+                public void visit(JavadocComment n, Object arg) {
+                    super.visit(n, arg);
+                    n.parse();
+                }
+            }.visit(cu, null);
+        } catch (ParseProblemException e) {
+            System.err.println("ERROR PROCESSING "+ file);
+        }
+    }
+
+    private void processDir(File dir) throws FileNotFoundException {
+        for (File child : dir.listFiles()) {
+            if (child.isFile() && child.getName().endsWith(".java")) {
+                processFile(child);
+            } else if (child.isDirectory()) {
+                processDir(child);
+            }
+        }
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/javadoc/JavadocTest.java b/javaparser-testing/src/test/java/com/github/javaparser/javadoc/JavadocTest.java
new file mode 100644
index 0000000..7377dfb
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/javadoc/JavadocTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.javadoc.description.JavadocDescription;
+import com.github.javaparser.javadoc.description.JavadocDescriptionElement;
+import com.github.javaparser.javadoc.description.JavadocInlineTag;
+import org.junit.Test;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class JavadocTest {
+
+    @Test
+    public void toTextForEmptyJavadoc() {
+        Javadoc javadoc = new Javadoc(new JavadocDescription());
+        assertEquals("", javadoc.toText());
+    }
+
+    @Test
+    public void toTextForJavadocWithTwoLinesOfJustDescription() {
+        Javadoc javadoc = new Javadoc(JavadocDescription.parseText("first line" + EOL + "second line"));
+        assertEquals("first line" + EOL + "second line" + EOL, javadoc.toText());
+    }
+
+    @Test
+    public void toTextForJavadocWithTwoLinesOfJustDescriptionAndOneBlockTag() {
+        Javadoc javadoc = new Javadoc(JavadocDescription.parseText("first line" + EOL + "second line"));
+        javadoc.addBlockTag("foo", "something useful");
+        assertEquals("first line" + EOL + "second line" + EOL + EOL + "@foo something useful" + EOL, javadoc.toText());
+    }
+
+    @Test
+    public void toCommentForEmptyJavadoc() {
+        Javadoc javadoc = new Javadoc(new JavadocDescription());
+        assertEquals(new JavadocComment("" + EOL + "\t\t "), javadoc.toComment("\t\t"));
+    }
+
+    @Test
+    public void toCommentorJavadocWithTwoLinesOfJustDescription() {
+        Javadoc javadoc = new Javadoc(JavadocDescription.parseText("first line" + EOL + "second line"));
+        assertEquals(new JavadocComment("" + EOL + "\t\t * first line" + EOL + "\t\t * second line" + EOL + "\t\t "), javadoc.toComment("\t\t"));
+    }
+
+    @Test
+    public void toCommentForJavadocWithTwoLinesOfJustDescriptionAndOneBlockTag() {
+        Javadoc javadoc = new Javadoc(JavadocDescription.parseText("first line" + EOL + "second line"));
+        javadoc.addBlockTag("foo", "something useful");
+        assertEquals(new JavadocComment("" + EOL + "\t\t * first line" + EOL + "\t\t * second line" + EOL + "\t\t * " + EOL + "\t\t * @foo something useful" + EOL + "\t\t "), javadoc.toComment("\t\t"));
+    }
+
+    @Test
+    public void descriptionAndBlockTagsAreRetrievable() {
+        Javadoc javadoc = JavaParser.parseJavadoc("first line" + EOL + "second line" + EOL + EOL + "@param node a node" + EOL + "@return result the result");
+        assertEquals("first line" + EOL + "second line", javadoc.getDescription().toText());
+        assertEquals(2, javadoc.getBlockTags().size());
+    }
+
+    @Test
+    public void inlineTagsAreParsable() {
+        String docText =
+                "Returns the {@link TOFilename}s of all files that existed during the requested" + EOL +
+                        "{@link TOVersion}." + EOL +
+                        "" + EOL +
+                        "@param versionID the id of the {@link TOVersion}." + EOL +
+                        "@return the filenames" + EOL +
+                        "@throws InvalidIDException if the {@link IPersistence} doesn't recognize the given versionID." + EOL;
+        String javadoc = JavaParser.parseJavadoc(docText).toText();
+        assertTrue(javadoc.contains("{@link TOVersion}"));
+    }
+
+    @Test
+    public void emptyLinesBetweenBlockTagsGetsFiltered() {
+        String comment = " * The type of the Object to be mapped." + EOL +
+                " * This interface maps the given Objects to existing ones in the database and" + EOL +
+                " * saves them." + EOL +
+                " * " + EOL +
+                " * @author censored" + EOL +
+                " * " + EOL +
+                " * @param <T>" + EOL;
+        Javadoc javadoc = JavaParser.parseJavadoc(comment);
+        assertEquals(2, javadoc.getBlockTags().size());
+    }
+
+    @Test
+    public void blockTagModificationWorks() {
+        Javadoc javadoc = new Javadoc(new JavadocDescription());
+
+        assertEquals(0, javadoc.getBlockTags().size());
+        JavadocBlockTag blockTag = new JavadocBlockTag(JavadocBlockTag.Type.RETURN, "a value");
+        javadoc.addBlockTag(blockTag);
+
+        assertEquals(1, javadoc.getBlockTags().size());
+        assertEquals(blockTag, javadoc.getBlockTags().get(0));
+
+        assertEquals(blockTag, javadoc.getBlockTags().remove(0));
+        assertEquals(0, javadoc.getBlockTags().size());
+    }
+
+    @Test
+    public void descriptionModificationWorks() {
+        JavadocDescription description = new JavadocDescription();
+
+        assertEquals(0, description.getElements().size());
+
+        JavadocDescriptionElement inlineTag = new JavadocInlineTag("inheritDoc", JavadocInlineTag.Type.INHERIT_DOC, "");
+        assertTrue(description.addElement(inlineTag));
+
+        assertEquals(1, description.getElements().size());
+        assertEquals(inlineTag, description.getElements().get(0));
+
+        assertEquals(inlineTag, description.getElements().remove(0));
+        assertEquals(0, description.getElements().size());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/javadoc/description/JavadocInlineTagTest.java b/javaparser-testing/src/test/java/com/github/javaparser/javadoc/description/JavadocInlineTagTest.java
new file mode 100644
index 0000000..128eb61
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/javadoc/description/JavadocInlineTagTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2017 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.javadoc.description;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class JavadocInlineTagTest {
+
+    @Test
+    public void javadocInlineTagShouldPersistCustomTagNames() {
+        String tag = JavadocInlineTag.fromText("{@foo something}").toText();
+
+        assertEquals(tag, "@foo something");
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/manual/BulkParseTest.java b/javaparser-testing/src/test/java/com/github/javaparser/manual/BulkParseTest.java
new file mode 100644
index 0000000..b09651f
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/manual/BulkParseTest.java
@@ -0,0 +1,120 @@
+package com.github.javaparser.manual;
+
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.Problem;
+import com.github.javaparser.utils.CodeGenerationUtils;
+import com.github.javaparser.utils.Log;
+import com.github.javaparser.utils.SourceRoot;
+import com.github.javaparser.utils.SourceZip;
+import org.junit.Test;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_10;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_9;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.SourceRoot.Callback.Result.DONT_SAVE;
+import static com.github.javaparser.utils.TestUtils.download;
+import static com.github.javaparser.utils.TestUtils.temporaryDirectory;
+import static java.util.Comparator.comparing;
+
+public class BulkParseTest {
+    /**
+     * Running this will download a version of the OpenJDK, unzip it, and parse it. If it throws a stack overflow
+     * exception, increase the JVM's stack size.
+     */
+    public static void main(String[] args) throws IOException {
+        Log.setAdapter(new Log.StandardOutStandardErrorAdapter());
+        // This contains all kinds of test cases so it will lead to a lot of errors:
+        new BulkParseTest().parseOpenJdkLangToolsRepository();
+        // This contains the JDK source code, so it should have zero errors:
+        new BulkParseTest().parseJdkSrcZip();
+    }
+
+    private void parseOpenJdkLangToolsRepository() throws IOException {
+        Path workdir = CodeGenerationUtils.mavenModuleRoot(BulkParseTest.class).resolve(Paths.get(temporaryDirectory(), "javaparser_bulkparsetest"));
+        workdir.toFile().mkdirs();
+        Path openJdkZipPath = workdir.resolve("langtools.zip");
+        if (Files.notExists(openJdkZipPath)) {
+            Log.info("Downloading JDK langtools");
+            /* Found by choosing a tag here: http://hg.openjdk.java.net/jdk9/jdk9/langtools/tags
+             then copying the "zip" link to the line below: */ 
+            download(new URL("http://hg.openjdk.java.net/jdk10/jdk10/langtools/archive/19293ea3999f.zip"), openJdkZipPath);
+        }
+        bulkTest(new SourceZip(openJdkZipPath), "openjdk_src_repo_test_results.txt", new ParserConfiguration().setLanguageLevel(JAVA_10));
+    }
+
+    private void parseJdkSrcZip() throws IOException {
+        // This is where Ubuntu stores the contents of package openjdk-8-src
+        Path path = Paths.get("/usr/lib/jvm/openjdk-9/src.zip");
+        bulkTest(new SourceZip(path), "openjdk_src_zip_test_results.txt", new ParserConfiguration().setLanguageLevel(JAVA_9));
+    }
+
+    @Test
+    public void parseOwnSourceCode() throws IOException {
+        bulkTest(
+                new SourceRoot(CodeGenerationUtils.mavenModuleRoot(BulkParseTest.class).resolve("..")), 
+                "javaparser_test_results.txt", 
+                new ParserConfiguration().setLanguageLevel(JAVA_9));
+    }
+
+    public void bulkTest(SourceRoot sourceRoot, String testResultsFileName, ParserConfiguration configuration) throws IOException {
+        sourceRoot.setParserConfiguration(configuration);
+        TreeMap<Path, List<Problem>> results = new TreeMap<>(comparing(o -> o.toString().toLowerCase()));
+        sourceRoot.parseParallelized((localPath, absolutePath, result) -> {
+            if (!localPath.toString().contains("target")) {
+                if (!result.isSuccessful()) {
+                    results.put(localPath, result.getProblems());
+                }
+            }
+            return DONT_SAVE;
+        });
+        writeResults(results, testResultsFileName);
+    }
+
+    public void bulkTest(SourceZip sourceRoot, String testResultsFileName, ParserConfiguration configuration) throws IOException {
+        sourceRoot.setParserConfiguration(configuration);
+        TreeMap<Path, List<Problem>> results = new TreeMap<>(comparing(o -> o.toString().toLowerCase()));
+        sourceRoot.parse((path, result) -> {
+            if (!path.toString().contains("target")) {
+                if (!result.isSuccessful()) {
+                    results.put(path, result.getProblems());
+                }
+            }
+        });
+        writeResults(results, testResultsFileName);
+    }
+
+    private void writeResults(TreeMap<Path, List<Problem>> results, String testResultsFileName) throws IOException {
+        Log.info("Writing results...");
+
+        Path testResults = CodeGenerationUtils.mavenModuleRoot(BulkParseTest.class).resolve(Paths.get("..", "javaparser-testing", "src", "test", "resources", "com", "github", "javaparser", "bulk_test_results")).normalize();
+        testResults.toFile().mkdirs();
+        testResults = testResults.resolve(testResultsFileName);
+
+        int problemTotal = 0;
+        try (BufferedWriter writer = Files.newBufferedWriter(testResults)) {
+            for (Map.Entry<Path, List<Problem>> file : results.entrySet()) {
+                writer.write(file.getKey().toString().replace("\\", "/"));
+                writer.newLine();
+                for (Problem problem : file.getValue()) {
+                    writer.write(problem.getVerboseMessage());
+                    writer.newLine();
+                    problemTotal++;
+                }
+                writer.newLine();
+            }
+            writer.write(f("%s problems in %s files", problemTotal, results.size()));
+        }
+
+        Log.info("Results are in %s", testResults);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/metamodel/BaseNodeMetaModelTest.java b/javaparser-testing/src/test/java/com/github/javaparser/metamodel/BaseNodeMetaModelTest.java
new file mode 100644
index 0000000..06a586c
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/metamodel/BaseNodeMetaModelTest.java
@@ -0,0 +1,25 @@
+package com.github.javaparser.metamodel;
+
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+
+class TestMetaModel extends BaseNodeMetaModel {
+
+    public TestMetaModel() {
+        super(Optional.empty(), StringLiteralExpr.class, "stri", "com.japa", true, true);
+    }
+}
+
+public class BaseNodeMetaModelTest {
+    @Test
+    public void testGetters() {
+        TestMetaModel test = new TestMetaModel();
+
+        assertEquals("testMetaModel", test.getMetaModelFieldName());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/metamodel/PropertyMetaModelTest.java b/javaparser-testing/src/test/java/com/github/javaparser/metamodel/PropertyMetaModelTest.java
new file mode 100644
index 0000000..2333d81
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/metamodel/PropertyMetaModelTest.java
@@ -0,0 +1,45 @@
+package com.github.javaparser.metamodel;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import org.junit.Test;
+
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+
+public class PropertyMetaModelTest {
+    @Test
+    public void whenPropertyIsVerySimpleThenTypeInfoIsCorrect() {
+        PropertyMetaModel bert = new PropertyMetaModel(null, "bert", int.class, Optional.empty(), false, false, false, false, false);
+        assertEquals("int", bert.getTypeName());
+        assertEquals("int", bert.getTypeNameGenerified());
+        assertEquals("int", bert.getTypeNameForGetter());
+        assertEquals("int", bert.getTypeNameForSetter());
+    }
+
+    @Test
+    public void whenPropertyIsVeryComplexThenTypeInfoIsCorrect() {
+        PropertyMetaModel bert = new PropertyMetaModel(null, "bert", BodyDeclaration.class, Optional.empty(), true, false, true, false, true);
+        assertEquals("BodyDeclaration", bert.getTypeName());
+        assertEquals("BodyDeclaration<?>", bert.getTypeNameGenerified());
+        assertEquals("Optional<NodeList<BodyDeclaration<?>>>", bert.getTypeNameForGetter());
+        assertEquals("NodeList<BodyDeclaration<?>>", bert.getTypeNameForSetter());
+    }
+
+    @Test
+    public void whenPropertyIsAnEnumThenTypeInfoIsCorrect() {
+        PropertyMetaModel bert = new PropertyMetaModel(null, "bert", Modifier.class, Optional.empty(), false, false, false, true, false);
+        assertEquals("Modifier", bert.getTypeName());
+        assertEquals("Modifier", bert.getTypeNameGenerified());
+        assertEquals("EnumSet<Modifier>", bert.getTypeNameForGetter());
+        assertEquals("EnumSet<Modifier>", bert.getTypeNameForSetter());
+    }
+
+    @Test
+    public void metaModelFieldName() {
+        PropertyMetaModel bert = new PropertyMetaModel(null, "bert", Modifier.class, Optional.empty(), false, false, false, true, false);
+        assertEquals("bertPropertyMetaModel", bert.getMetaModelFieldName());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/modules/ModuleDeclarationTest.java b/javaparser-testing/src/test/java/com/github/javaparser/modules/ModuleDeclarationTest.java
new file mode 100644
index 0000000..80ebe55
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/modules/ModuleDeclarationTest.java
@@ -0,0 +1,181 @@
+package com.github.javaparser.modules;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.JavaToken;
+import com.github.javaparser.ParseStart;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.MarkerAnnotationExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr;
+import com.github.javaparser.ast.modules.*;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import org.junit.Test;
+
+import static com.github.javaparser.GeneratedJavaParserConstants.IDENTIFIER;
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+import static com.github.javaparser.JavaParser.parseName;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_9;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+
+public class ModuleDeclarationTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_9));
+
+    private final CompilationUnit parse(String code) {
+        return javaParser.parse(ParseStart.COMPILATION_UNIT, provider(code)).getResult().get();
+    }
+
+    @Test
+    public void moduleInfoKeywordsAreSeenAsIdentifiers() {
+        CompilationUnit cu = parse("class module { }");
+        JavaToken moduleToken = cu.getClassByName("module").get().getName().getTokenRange().get().getBegin();
+        assertEquals(IDENTIFIER, moduleToken.getKind());
+    }
+
+    @Test
+    public void issue988RequireTransitiveShouldRequireAModuleCalledTransitive() {
+        CompilationUnit cu = parse("module X { requires transitive; }");
+        ModuleRequiresStmt requiresTransitive = (ModuleRequiresStmt) cu.getModule().get().getModuleStmts().get(0);
+        assertEquals("transitive", requiresTransitive.getNameAsString());
+        assertEquals(IDENTIFIER, requiresTransitive.getName().getTokenRange().get().getBegin().getKind());
+    }
+
+    @Test
+    public void jlsExample1() {
+        CompilationUnit cu = parse(
+                "@Foo(1) @Foo(2) @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;" +
+                        "}");
+
+        ModuleDeclaration module = cu.getModule().get();
+        assertEquals("M.N", module.getNameAsString());
+        assertEquals(false, module.isOpen());
+        assertThat(module.getAnnotations()).containsExactly(
+                new SingleMemberAnnotationExpr(new Name("Foo"), new IntegerLiteralExpr("1")),
+                new SingleMemberAnnotationExpr(new Name("Foo"), new IntegerLiteralExpr("2")),
+                new MarkerAnnotationExpr(new Name("Bar")));
+
+        ModuleRequiresStmt moduleRequiresStmt = module.getModuleStmts().get(0).asModuleRequiresStmt();
+        assertThat(moduleRequiresStmt.getNameAsString()).isEqualTo("A.B");
+        assertThat(moduleRequiresStmt.getModifiers()).isEmpty();
+
+        ModuleExportsStmt moduleExportsStmt = module.getModuleStmts().get(5).asModuleExportsStmt();
+        assertThat(moduleExportsStmt.getNameAsString()).isEqualTo("R.S");
+        assertThat(moduleExportsStmt.getModuleNames()).containsExactly(parseName("T1.U1"), parseName("T2.U2"));
+
+        ModuleOpensStmt moduleOpensStmt = module.getModuleStmts().get(7).asModuleOpensStmt();
+        assertThat(moduleOpensStmt.getNameAsString()).isEqualTo("R.S");
+        assertThat(moduleOpensStmt.getModuleNames()).containsExactly(parseName("T1.U1"), parseName("T2.U2"));
+
+        ModuleUsesStmt moduleUsesStmt = module.getModuleStmts().get(8).asModuleUsesStmt();
+        assertThat(moduleUsesStmt.getType().toString()).isEqualTo("V.W");
+
+        ModuleProvidesStmt moduleProvidesStmt = module.getModuleStmts().get(9).asModuleProvidesStmt();
+        assertThat(moduleProvidesStmt.getType().toString()).isEqualTo("X.Y");
+        assertThat(moduleProvidesStmt.getWithTypes()).containsExactly(
+                new ClassOrInterfaceType(parseClassOrInterfaceType("Z1"), "Z2"),
+                new ClassOrInterfaceType(parseClassOrInterfaceType("Z3"), "Z4"));
+
+    }
+
+    @Test
+    public void jlsExample2HasAnOpenModule() {
+        CompilationUnit cu = parse("open module M.N {}");
+
+        ModuleDeclaration module = cu.getModule().get();
+        assertEquals("M.N", module.getNameAsString());
+        assertEquals(true, module.isOpen());
+    }
+
+    @Test
+    public void testPrettyPrinting() {
+        CompilationUnit cu = parse(
+                "@Foo(1) @Foo(2) @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;" +
+                        "}");
+
+        assertEquals(
+                "@Foo(1) @Foo(2) @Bar " + EOL +
+                        "module M.N {" + EOL +
+                        "    requires A.B;" + EOL +
+                        "    requires transitive C.D;" + EOL +
+                        "    requires static E.F;" + EOL +
+                        "    requires static transitive G.H;" + EOL +
+                        "    exports P.Q;" + EOL +
+                        "    exports R.S to T1.U1, T2.U2;" + EOL +
+                        "    opens P.Q;" + EOL +
+                        "    opens R.S to T1.U1, T2.U2;" + EOL +
+                        "    uses V.W;" + EOL +
+                        "    provides X.Y with Z1.Z2, Z3.Z4;" + EOL +
+                        "}" + EOL, cu.toString());
+
+    }
+
+    @Test
+    public void testCsmPrinting() {
+        CompilationUnit cu = parse(
+                "@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;" +
+                        "" +
+                        "  opens P.Q;" +
+                        "  opens R.S to T1.U1, T2.U2;" +
+                        "" +
+                        "  uses V.W;" +
+                        "  provides X.Y with Z1.Z2, Z3.Z4;" +
+                        "}");
+
+        assertEquals(
+                "@Foo(1) @Foo(2) @Bar" + EOL +
+                        "open module M.N {" + EOL +
+                        "    requires A.B;" + EOL +
+                        "    requires transitive C.D;" + EOL +
+                        "    requires static E.F;" + EOL +
+                        "    requires static transitive G.H;" + EOL +
+                        "    exports P.Q;" + EOL +
+                        "    exports R.S to T1.U1, T2.U2;" + EOL +
+                        "    opens P.Q;" + EOL +
+                        "    opens R.S to T1.U1, T2.U2;" + EOL +
+                        "    uses V.W;" + EOL +
+                        "    provides X.Y with Z1.Z2, Z3.Z4;" + EOL +
+                        "}" + EOL, ConcreteSyntaxModel.genericPrettyPrint(cu));
+
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/ConcreteSyntaxModelAcceptanceTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/ConcreteSyntaxModelAcceptanceTest.java
new file mode 100644
index 0000000..af47a9d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/ConcreteSyntaxModelAcceptanceTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.utils.CodeGenerationUtils;
+import com.github.javaparser.utils.TestUtils;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Path;
+
+import static org.junit.Assert.assertEquals;
+
+public class ConcreteSyntaxModelAcceptanceTest {
+    private final Path rootDir = CodeGenerationUtils.mavenModuleRoot(ConcreteSyntaxModelAcceptanceTest.class).resolve("src/test/test_sourcecode");
+
+    private String prettyPrint(Node node) {
+        return ConcreteSyntaxModel.genericPrettyPrint(node);
+    }
+
+    private String prettyPrintedExpectation(String name) throws IOException {
+        return TestUtils.readResource("com/github/javaparser/printer/" + name + "_prettyprinted");
+    }
+
+    @Test
+    public void printingExamplePrettyPrintVisitor() throws IOException {
+        CompilationUnit cu = JavaParser.parse(rootDir.resolve("com/github/javaparser/printer/PrettyPrintVisitor.java"));
+        assertEquals(prettyPrintedExpectation("PrettyPrintVisitor"), prettyPrint(cu));
+    }
+
+    @Test
+    public void printingExampleJavaConcepts() throws IOException {
+        CompilationUnit cu = JavaParser.parse(rootDir.resolve("com/github/javaparser/printer/JavaConcepts.java"));
+        assertEquals(prettyPrintedExpectation("JavaConcepts"), prettyPrint(cu));
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/ConcreteSyntaxModelTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/ConcreteSyntaxModelTest.java
new file mode 100644
index 0000000..b08f90b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/ConcreteSyntaxModelTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.ClassExpr;
+import org.junit.Test;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class ConcreteSyntaxModelTest {
+
+    private String print(Node node) {
+        return ConcreteSyntaxModel.genericPrettyPrint(node);
+    }
+
+    @Test
+    public void printSimpleClassExpr() {
+        ClassExpr expr = JavaParser.parseExpression("Foo.class");
+        assertEquals("Foo.class", print(expr));
+    }
+
+    @Test
+    public void printArrayClassExpr() {
+        ClassExpr expr = JavaParser.parseExpression("Foo[].class");
+        assertEquals("Foo[].class", print(expr));
+    }
+
+    @Test
+    public void printGenericClassExpr() {
+        ClassExpr expr = JavaParser.parseExpression("Foo<String>.class");
+        assertEquals("Foo<String>.class", print(expr));
+    }
+
+    @Test
+    public void printSimplestClass() {
+        Node node = JavaParser.parse("class A {}");
+        assertEquals("class A {" + EOL +
+                "}" + EOL, print(node));
+    }
+
+    @Test
+    public void printAClassWithField() {
+        Node node = JavaParser.parse("class A { int a; }");
+        assertEquals("class A {" + EOL
+                + EOL +
+                "    int a;" + EOL +
+                "}" + EOL, print(node));
+    }
+
+    @Test
+    public void printParameters() {
+        Node node = JavaParser.parseBodyDeclaration("int x(int y, int z) {}");
+        assertEquals("int x(int y, int z) {" + EOL + "}", print(node));
+    }
+
+    @Test
+    public void printReceiverParameter() {
+        Node node = JavaParser.parseBodyDeclaration("int x(X A.B.this, int y, int z) {}");
+        assertEquals("int x(X A.B.this, int y, int z) {" + EOL + "}", print(node));
+    }
+
+    @Test
+    public void printAnEmptyInterface() {
+        Node node = JavaParser.parse("interface A {}");
+        assertEquals("interface A {" + EOL +
+                "}" + EOL, print(node));
+    }
+
+    @Test
+    public void printAnEmptyInterfaceWithModifier() {
+        Node node = JavaParser.parse("public interface A {}");
+        assertEquals("public interface A {" + EOL +
+                "}" + EOL, print(node));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/DotPrinterTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/DotPrinterTest.java
new file mode 100644
index 0000000..ca11465
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/DotPrinterTest.java
@@ -0,0 +1,79 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.printer;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.Test;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ast.expr.Expression;

+

+public class DotPrinterTest {

+    @Test

+    public void testWithType() {

+        String expectedOutput = "digraph {" + System.lineSeparator();

+        expectedOutput += "n0 [label=\"root (MethodCallExpr)\"];" + System.lineSeparator();

+        expectedOutput += "n1 [label=\"name (SimpleName)\"];" + System.lineSeparator();

+        expectedOutput += "n0 -> n1;" + System.lineSeparator();

+        expectedOutput += "n2 [label=\"identifier='x'\"];" + System.lineSeparator();

+        expectedOutput += "n1 -> n2;" + System.lineSeparator();

+        expectedOutput += "n3 [label=\"arguments\"];" + System.lineSeparator();

+        expectedOutput += "n0 -> n3;" + System.lineSeparator();

+        expectedOutput += "n4 [label=\"argument (IntegerLiteralExpr)\"];" + System.lineSeparator();

+        expectedOutput += "n3 -> n4;" + System.lineSeparator();

+        expectedOutput += "n5 [label=\"value='1'\"];" + System.lineSeparator();

+        expectedOutput += "n4 -> n5;" + System.lineSeparator();

+        expectedOutput += "n6 [label=\"argument (IntegerLiteralExpr)\"];" + System.lineSeparator();

+        expectedOutput += "n3 -> n6;" + System.lineSeparator();

+        expectedOutput += "n7 [label=\"value='1'\"];" + System.lineSeparator();

+        expectedOutput += "n6 -> n7;" + System.lineSeparator();

+        expectedOutput += "}";

+

+        DotPrinter dotPrinter = new DotPrinter(true);

+        Expression expression = JavaParser.parseExpression("x(1,1)");

+        String output = dotPrinter.output(expression);

+        assertEquals(expectedOutput, output);

+    }

+

+    @Test

+    public void testWithoutType() {

+        String expectedOutput = "digraph {" + System.lineSeparator();

+        expectedOutput += "n0 [label=\"root\"];" + System.lineSeparator();

+        expectedOutput += "n1 [label=\"operator='PLUS'\"];" + System.lineSeparator();

+        expectedOutput += "n0 -> n1;" + System.lineSeparator();

+        expectedOutput += "n2 [label=\"left\"];" + System.lineSeparator();

+        expectedOutput += "n0 -> n2;" + System.lineSeparator();

+        expectedOutput += "n3 [label=\"value='1'\"];" + System.lineSeparator();

+        expectedOutput += "n2 -> n3;" + System.lineSeparator();

+        expectedOutput += "n4 [label=\"right\"];" + System.lineSeparator();

+        expectedOutput += "n0 -> n4;" + System.lineSeparator();

+        expectedOutput += "n5 [label=\"value='1'\"];" + System.lineSeparator();

+        expectedOutput += "n4 -> n5;" + System.lineSeparator();

+        expectedOutput += "}";

+

+        DotPrinter dotPrinter = new DotPrinter(false);

+        Expression expression = JavaParser.parseExpression("1+1");

+        String output = dotPrinter.output(expression);

+        assertEquals(expectedOutput, output);

+    }

+}

diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/JsonPrinterTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/JsonPrinterTest.java
new file mode 100644
index 0000000..7e26254
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/JsonPrinterTest.java
@@ -0,0 +1,75 @@
+package com.github.javaparser.printer;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.expr.Expression;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.*;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.io.BufferedWriter;
+
+public class JsonPrinterTest {
+    @Test
+    public void testWithType() {
+        JsonPrinter jsonPrinter = new JsonPrinter(true);
+        Expression expression = parseExpression("x(1,1)");
+
+        String output = jsonPrinter.output(expression);
+
+        assertEquals("{\"type\":\"MethodCallExpr\",\"name\":{\"type\":\"SimpleName\",\"identifier\":\"x\"},\"arguments\":[{\"type\":\"IntegerLiteralExpr\",\"value\":\"1\"},{\"type\":\"IntegerLiteralExpr\",\"value\":\"1\"}]}", output);
+    }
+
+    @Test
+    public void testWithoutType() {
+        JsonPrinter jsonPrinter = new JsonPrinter(false);
+        Expression expression = parseExpression("1+1");
+
+        String output = jsonPrinter.output(expression);
+
+        assertEquals("{\"operator\":\"PLUS\",\"left\":{\"value\":\"1\"},\"right\":{\"value\":\"1\"}}", output);
+    }
+
+    @Test
+    public void testEscaping() {
+        JsonPrinter jsonPrinter = new JsonPrinter(false);
+        CompilationUnit expression = parse("class X {//hi\"" + EOL + "int x;}");
+
+        String output = jsonPrinter.output(expression);
+
+        assertEquals("{\"types\":[{\"isInterface\":\"false\",\"name\":{\"identifier\":\"X\",\"comment\":{\"content\":\"hi\\\"\"}},\"members\":[{\"variables\":[{\"name\":{\"identifier\":\"x\"},\"type\":{\"type\":\"INT\"}}]}]}]}", output);
+    }
+
+    @Test
+    public void issue1338() {
+        String code = "class Test {" +
+                "  public void method() {" +
+                "    String.format(\"I'm using %s\", \"JavaParser\");" +
+                "  }" +
+                "}";
+        CompilationUnit unit = parse(code);
+        JsonPrinter printer = new JsonPrinter(true);
+        printer.output(unit);
+    }
+
+    @Test
+    public void issue1421() {
+        // Handle multi-line strings in JSON output
+        String code = "/* \n" +
+                "* Some comment\n" +
+                "*/\n" +
+                "public class Test {}";
+        CompilationUnit unit = parse(code);
+        JsonPrinter printer = new JsonPrinter(true);
+
+        String output = printer.output(unit);
+
+        assertEquals("{\"type\":\"CompilationUnit\",\"types\":[{\"type\":\"ClassOrInterfaceDeclaration\",\"isInterface\":\"false\",\"name\":{\"type\":\"SimpleName\",\"identifier\":\"Test\"},\"comment\":{\"type\":\"BlockComment\",\"content\":\" \\n* Some comment\\n\"}}]}", output);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrintVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrintVisitorTest.java
new file mode 100644
index 0000000..df1168e
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrintVisitorTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.CastExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.type.Type;
+import org.junit.Test;
+
+import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+
+public class PrettyPrintVisitorTest {
+
+    @Test
+    public void getMaximumCommonTypeWithoutAnnotations() {
+        VariableDeclarationExpr vde1 = JavaParser.parseVariableDeclarationExpr("int a[], b[]");
+        assertEquals("int[]", vde1.getMaximumCommonType().get().toString());
+
+        VariableDeclarationExpr vde2 = JavaParser.parseVariableDeclarationExpr("int[][] a[], b[]");
+        assertEquals("int[][][]", vde2.getMaximumCommonType().get().toString());
+
+        VariableDeclarationExpr vde3 = JavaParser.parseVariableDeclarationExpr("int[][] a, b[]");
+        assertEquals("int[][]", vde3.getMaximumCommonType().get().toString());
+    }
+
+    @Test
+    public void getMaximumCommonTypeWithAnnotations() {
+        VariableDeclarationExpr vde1 = JavaParser.parseVariableDeclarationExpr("int a @Foo [], b[]");
+        assertEquals("int", vde1.getMaximumCommonType().get().toString());
+
+        VariableDeclarationExpr vde2 = JavaParser.parseVariableDeclarationExpr("int[]@Foo [] a[], b[]");
+        assertEquals("int[] @Foo [][]", vde2.getMaximumCommonType().get().toString());
+    }
+
+    private String print(Node node) {
+        return new PrettyPrinter().print(node);
+    }
+
+    @Test
+    public void printSimpleClassExpr() {
+        ClassExpr expr = JavaParser.parseExpression("Foo.class");
+        assertEquals("Foo.class", print(expr));
+    }
+
+    @Test
+    public void printArrayClassExpr() {
+        ClassExpr expr = JavaParser.parseExpression("Foo[].class");
+        assertEquals("Foo[].class", print(expr));
+    }
+
+    @Test
+    public void printGenericClassExpr() {
+        ClassExpr expr = JavaParser.parseExpression("Foo<String>.class");
+        assertEquals("Foo<String>.class", print(expr));
+    }
+
+    @Test
+    public void printSimplestClass() {
+        Node node = JavaParser.parse("class A {}");
+        assertEquals("class A {" + EOL +
+                "}" + EOL, print(node));
+    }
+
+    @Test
+    public void printAClassWithField() {
+        Node node = JavaParser.parse("class A { int a; }");
+        assertEquals("class A {" + EOL
+                + EOL +
+                "    int a;" + EOL +
+                "}" + EOL, print(node));
+    }
+
+    @Test
+    public void printAReceiverParameter() {
+        Node node = JavaParser.parseBodyDeclaration("int x(@O X A.B.this, int y) { }");
+        assertEquals("int x(@O X A.B.this, int y) {" + EOL + "}", print(node));
+    }
+
+    @Test
+    public void printLambdaIntersectionTypeAssignment() {
+        String code = "class A {" + EOL +
+                "  void f() {" + EOL +
+                "    Runnable r = (Runnable & Serializable) (() -> {});" + EOL +
+                "    r = (Runnable & Serializable)() -> {};" + EOL +
+                "    r = (Runnable & I)() -> {};" + EOL +
+                "  }}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodDeclaration methodDeclaration = (MethodDeclaration) cu.getType(0).getMember(0);
+
+        assertEquals("Runnable r = (Runnable & Serializable) (() -> {" + EOL + "});", print(methodDeclaration.getBody().get().getStatements().get(0)));
+    }
+
+    @Test
+    public void printIntersectionType() {
+        String code = "(Runnable & Serializable) (() -> {})";
+        Expression expression = JavaParser.parseExpression(code);
+        Type type = ((CastExpr) expression).getType();
+
+        assertEquals("Runnable & Serializable", print(type));
+    }
+
+    @Test
+    public void printLambdaIntersectionTypeReturn() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        CompilationUnit cu = JavaParser.parse(code);
+        MethodDeclaration methodDeclaration = (MethodDeclaration) cu.getType(0).getMember(0);
+
+        assertEquals("return (Comparator<Map.Entry<K, V>> & Serializable) (c1, c2) -> c1.getKey().compareTo(c2.getKey());", print(methodDeclaration.getBody().get().getStatements().get(0)));
+    }
+
+    @Test
+    public void printClassWithoutJavaDocButWithComment() {
+        String code = String.format("/** javadoc */ public class A { %s// stuff%s}", EOL, EOL);
+        CompilationUnit cu = JavaParser.parse(code);
+        PrettyPrinterConfiguration ignoreJavaDoc = new PrettyPrinterConfiguration().setPrintJavadoc(false);
+        String content = cu.toString(ignoreJavaDoc);
+        assertEquals(String.format("public class A {%s    // stuff%s}%s", EOL, EOL, EOL), content);
+    }
+
+    @Test
+    public void printImportsDefaultOrder() {
+        String code = "import x.y.z;import a.b.c;import static b.c.d;class c {}";
+        CompilationUnit cu = JavaParser.parse(code);
+        String content = cu.toString();
+        assertEqualsNoEol("import x.y.z;\n" +
+                "import a.b.c;\n" +
+                "import static b.c.d;\n" +
+                "\n" +
+                "class c {\n" +
+                "}\n", content);
+    }
+
+    @Test
+    public void printImportsOrdered() {
+        String code = "import x.y.z;import a.b.c;import static b.c.d;class c {}";
+        CompilationUnit cu = JavaParser.parse(code);
+        PrettyPrinterConfiguration orderImports = new PrettyPrinterConfiguration().setOrderImports(true);
+        String content = cu.toString(orderImports);
+        assertEqualsNoEol("import static b.c.d;\n" +
+                "import a.b.c;\n" +
+                "import x.y.z;\n" +
+                "\n" +
+                "class c {\n" +
+                "}\n", content);
+    }
+
+    @Test
+    public void multilineJavadocGetsFormatted() {
+        CompilationUnit cu = new CompilationUnit();
+        cu.addClass("X").addMethod("abc").setJavadocComment("line1\n   line2 *\n * line3");
+
+        assertEqualsNoEol("public class X {\n" +
+                "\n" +
+                "    /**\n" +
+                "     * line1\n" +
+                "     *   line2 *\n" +
+                "     * line3\n" +
+                "     */\n" +
+                "    void abc() {\n" +
+                "    }\n" +
+                "}\n", cu.toString());
+    }
+
+    @Test
+    public void emptyJavadocGetsFormatted() {
+        CompilationUnit cu = new CompilationUnit();
+        cu.addClass("X").addMethod("abc").setJavadocComment("");
+
+        assertEqualsNoEol("public class X {\n" +
+                "\n" +
+                "    /**\n" +
+                "     */\n" +
+                "    void abc() {\n" +
+                "    }\n" +
+                "}\n", cu.toString());
+    }
+
+    @Test
+    public void multilineJavadocWithLotsOfEmptyLinesGetsFormattedNeatly() {
+        CompilationUnit cu = new CompilationUnit();
+        cu.addClass("X").addMethod("abc").setJavadocComment("\n\n\n ab\n\n\n cd\n\n\n");
+
+        assertEqualsNoEol("public class X {\n" +
+                "\n" +
+                "    /**\n" +
+                "     * ab\n" +
+                "     *\n" +
+                "     * cd\n" +
+                "     */\n" +
+                "    void abc() {\n" +
+                "    }\n" +
+                "}\n", cu.toString());
+    }
+
+    @Test
+    public void singlelineJavadocGetsFormatted() {
+        CompilationUnit cu = new CompilationUnit();
+        cu.addClass("X").addMethod("abc").setJavadocComment("line1");
+
+        assertEqualsNoEol("public class X {\n" +
+                "\n" +
+                "    /**\n" +
+                "     * line1\n" +
+                "     */\n" +
+                "    void abc() {\n" +
+                "    }\n" +
+                "}\n", cu.toString());
+    }
+
+    @Test
+    public void singlelineCommentGetsFormatted() {
+        CompilationUnit cu = new CompilationUnit();
+        cu.addClass("X").addMethod("abc").setComment(new LineComment("   line1  \n "));
+
+        assertEqualsNoEol("public class X {\n" +
+                "\n" +
+                "    // line1\n" +
+                "    void abc() {\n" +
+                "    }\n" +
+                "}\n", cu.toString());
+    }
+
+    @Test
+    public void blockcommentGetsNoFormatting() {
+        CompilationUnit cu = JavaParser.parse("class A {\n" +
+                "    public void helloWorld(String greeting, String name) {\n" +
+                "        //sdfsdfsdf\n" +
+                "            //sdfds\n" +
+                "        /*\n" +
+                "                            dgfdgfdgfdgfdgfd\n" +
+                "         */\n" +
+                "    }\n" +
+                "}\n");
+
+        assertEqualsNoEol("class A {\n" +
+                "\n" +
+                "    public void helloWorld(String greeting, String name) {\n" +
+                "    // sdfsdfsdf\n" +
+                "    // sdfds\n" +
+                "    /*\n" +
+                "                            dgfdgfdgfdgfdgfd\n" +
+                "         */\n" +
+                "    }\n" +
+                "}\n", cu.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrinterTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrinterTest.java
new file mode 100644
index 0000000..fef3609
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/PrettyPrinterTest.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.type.PrimitiveType;
+import org.junit.Test;
+
+import static com.github.javaparser.JavaParser.*;
+import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
+import static org.junit.Assert.assertEquals;
+
+public class PrettyPrinterTest {
+
+    private String prettyPrintField(String code) {
+        CompilationUnit cu = parse(code);
+        return new PrettyPrinter().print(cu.findFirst(FieldDeclaration.class).get());
+    }
+
+    private String prettyPrintVar(String code) {
+        CompilationUnit cu = parse(code);
+        return new PrettyPrinter().print(cu.findAll(VariableDeclarationExpr.class).get(0));
+    }
+
+    @Test
+    public void printingArrayFields() {
+        String code;
+        code = "class A { int a, b[]; }";
+        assertEquals("int a, b[];", prettyPrintField(code));
+
+        code = "class A { int[] a[], b[]; }";
+        assertEquals("int[][] a, b;", prettyPrintField(code));
+
+        code = "class A { int[] a[][], b; }";
+        assertEquals("int[] a[][], b;", prettyPrintField(code));
+
+        code = "class A { int[] a, b; }";
+        assertEquals("int[] a, b;", prettyPrintField(code));
+
+        code = "class A { int a[], b[]; }";
+        assertEquals("int[] a, b;", prettyPrintField(code));
+    }
+
+    @Test
+    public void printingArrayVariables() {
+        String code;
+        code = "class A { void foo(){ int a, b[]; }}";
+        assertEquals("int a, b[]", prettyPrintVar(code));
+
+        code = "class A { void foo(){ int[] a[], b[]; }}";
+        assertEquals("int[][] a, b", prettyPrintVar(code));
+
+        code = "class A { void foo(){ int[] a[][], b; }}";
+        assertEquals("int[] a[][], b", prettyPrintVar(code));
+
+        code = "class A { void foo(){ int[] a, b; }}";
+        assertEquals("int[] a, b", prettyPrintVar(code));
+
+        code = "class A { void foo(){ int a[], b[]; }}";
+        assertEquals("int[] a, b", prettyPrintVar(code));
+    }
+
+    private String prettyPrintConfigurable(String code) {
+        CompilationUnit cu = parse(code);
+        PrettyPrinter printer = new PrettyPrinter(new PrettyPrinterConfiguration().setVisitorFactory(TestVisitor::new));
+        return printer.print(cu.findFirst(ClassOrInterfaceDeclaration.class).get());
+    }
+
+    @Test
+    public void printUseTestVisitor() {
+        String code;
+        code = "class A { void foo(){ int a, b[]; }}";
+        assertEquals("test", prettyPrintConfigurable(code));
+    }
+
+    @Test
+    public void prettyColumnAlignParameters_enabled() {
+        PrettyPrinterConfiguration config = new PrettyPrinterConfiguration()
+                .setIndent("\t")
+                .setColumnAlignParameters(true);
+
+        final String EOL = config.getEndOfLineCharacter();
+
+        String code = "class Example { void foo(Object arg0,Object arg1){ myMethod(1, 2, 3, 5, Object.class); } }";
+        String expected = "class Example {" + EOL +
+                "" + EOL +
+                "\tvoid foo(Object arg0, Object arg1) {" + EOL +
+                "\t\tmyMethod(1," + EOL +
+                "\t\t         2," + EOL +
+                "\t\t         3," + EOL +
+                "\t\t         5," + EOL +
+                "\t\t         Object.class);" + EOL +
+                "\t}" + EOL +
+                "}" + EOL +
+                "";
+
+        assertEquals(expected, new PrettyPrinter(config).print(parse(code)));
+    }
+
+    @Test
+    public void prettyColumnAlignParameters_disabled() {
+        PrettyPrinterConfiguration config = new PrettyPrinterConfiguration();
+        final String EOL = config.getEndOfLineCharacter();
+
+        String code = "class Example { void foo(Object arg0,Object arg1){ myMethod(1, 2, 3, 5, Object.class); } }";
+        String expected = "class Example {" + EOL +
+                "" + EOL +
+                "    void foo(Object arg0, Object arg1) {" + EOL +
+                "        myMethod(1, 2, 3, 5, Object.class);" + EOL +
+                "    }" + EOL +
+                "}" + EOL +
+                "";
+
+        assertEquals(expected, new PrettyPrinter(config).print(parse(code)));
+    }
+
+    @Test
+    public void prettyAlignMethodCallChains_enabled() {
+        PrettyPrinterConfiguration config = new PrettyPrinterConfiguration()
+                .setIndent("\t")
+                .setColumnAlignFirstMethodChain(true);
+
+        final String EOL = config.getEndOfLineCharacter();
+
+        String code = "class Example { void foo() { IntStream.range(0, 10).filter(x -> x % 2 == 0).map(x -> x * IntStream.of(1,3,5,1).sum()).forEach(System.out::println); } }";
+        String expected = "class Example {" + EOL +
+                "" + EOL +
+                "\tvoid foo() {" + EOL +
+                "\t\tIntStream.range(0, 10)" + EOL +
+                "\t\t         .filter(x -> x % 2 == 0)" + EOL +
+                "\t\t         .map(x -> x * IntStream.of(1, 3, 5, 1)" + EOL +
+                "\t\t                                .sum())" + EOL +
+                "\t\t         .forEach(System.out::println);" + EOL +
+                "\t}" + EOL +
+                "}" + EOL +
+                "";
+
+        assertEquals(expected, new PrettyPrinter(config).print(parse(code)));
+    }
+
+    @Test
+    public void prettyAlignMethodCallChains_disabled() {
+        PrettyPrinterConfiguration config = new PrettyPrinterConfiguration();
+        final String EOL = config.getEndOfLineCharacter();
+
+        String code = "class Example { void foo() { IntStream.range(0, 10).filter(x -> x % 2 == 0).map(x -> x * IntStream.of(1,3,5,1).sum()).forEach(System.out::println); } }";
+        String expected = "class Example {" + EOL +
+                "" + EOL +
+                "    void foo() {" + EOL +
+                "        IntStream.range(0, 10).filter(x -> x % 2 == 0).map(x -> x * IntStream.of(1, 3, 5, 1).sum()).forEach(System.out::println);" + EOL +
+                "    }" + EOL +
+                "}" + EOL +
+                "";
+
+        assertEquals(expected, new PrettyPrinter(config).print(parse(code)));
+    }
+
+    @Test
+    public void enumConstantsHorizontally() {
+        CompilationUnit cu = parse("enum X{A, B, C, D, E}");
+        assertEqualsNoEol("enum X {\n\n    A, B, C, D, E\n}\n", new PrettyPrinter().print(cu));
+    }
+
+    @Test
+    public void enumConstantsVertically() {
+        CompilationUnit cu = parse("enum X{A, B, C, D, E, F}");
+        assertEqualsNoEol("enum X {\n\n    A,\n    B,\n    C,\n    D,\n    E,\n    F\n}\n", new PrettyPrinter().print(cu));
+    }
+
+    @Test
+    public void printingInconsistentVariables() {
+        FieldDeclaration fieldDeclaration = parseBodyDeclaration("int a, b;").asFieldDeclaration();
+
+        assertEquals("int a, b;", fieldDeclaration.toString());
+
+        fieldDeclaration.getVariable(0).setType(PrimitiveType.doubleType());
+
+        assertEquals("??? a, b;", fieldDeclaration.toString());
+
+        fieldDeclaration.getVariable(1).setType(PrimitiveType.doubleType());
+
+        assertEquals("double a, b;", fieldDeclaration.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/TestVisitor.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/TestVisitor.java
new file mode 100644
index 0000000..6cbe328
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/TestVisitor.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.printer;
+
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+
+public class TestVisitor extends PrettyPrintVisitor {
+
+    public TestVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) {
+        super(prettyPrinterConfiguration);
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceDeclaration n, final Void arg) {
+        printer.print("test");
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/XmlPrinterTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/XmlPrinterTest.java
new file mode 100644
index 0000000..b649891
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/XmlPrinterTest.java
@@ -0,0 +1,41 @@
+package com.github.javaparser.printer;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.expr.Expression;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class XmlPrinterTest {
+    @Test
+    public void testWithType() {
+        Expression expression = JavaParser.parseExpression("1+1");
+        XmlPrinter xmlOutput = new XmlPrinter(true);
+
+        String output = xmlOutput.output(expression);
+
+        assertEquals("<root type='BinaryExpr' operator='PLUS'><left type='IntegerLiteralExpr' value='1'></left><right type='IntegerLiteralExpr' value='1'></right></root>", output);
+    }
+
+    @Test
+    public void testWithoutType() {
+        Expression expression = JavaParser.parseExpression("1+1");
+
+        XmlPrinter xmlOutput = new XmlPrinter(false);
+
+        String output = xmlOutput.output(expression);
+
+        assertEquals("<root operator='PLUS'><left value='1'></left><right value='1'></right></root>", output);
+    }
+
+    @Test
+    public void testList() {
+        Expression expression = JavaParser.parseExpression("a(1,2)");
+
+        XmlPrinter xmlOutput = new XmlPrinter(true);
+
+        String output = xmlOutput.output(expression);
+
+        assertEquals("<root type='MethodCallExpr'><name type='SimpleName' identifier='a'></name><arguments><argument type='IntegerLiteralExpr' value='1'></argument><argument type='IntegerLiteralExpr' value='2'></argument></arguments></root>", output);
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/YamlPrinterTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/YamlPrinterTest.java
new file mode 100644
index 0000000..435cd81
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/YamlPrinterTest.java
@@ -0,0 +1,94 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.printer;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.Test;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ast.expr.Expression;

+

+public class YamlPrinterTest {

+

+    @Test

+    public void testWithType() {

+        String expectedOutput = "---" + System.lineSeparator();

+        expectedOutput += "root(Type=MethodCallExpr): " + System.lineSeparator();

+        expectedOutput += "    name(Type=SimpleName): " + System.lineSeparator();

+        expectedOutput += "        identifier: \"x\"" + System.lineSeparator();

+        expectedOutput += "    arguments: " + System.lineSeparator();

+        expectedOutput += "        - argument(Type=IntegerLiteralExpr): " + System.lineSeparator();

+        expectedOutput += "            value: \"1\"" + System.lineSeparator();

+        expectedOutput += "        - argument(Type=IntegerLiteralExpr): " + System.lineSeparator();

+        expectedOutput += "            value: \"1\"" + System.lineSeparator();

+        expectedOutput += "...";

+

+        YamlPrinter yamlPrinter = new YamlPrinter(true);

+        Expression expression = JavaParser.parseExpression("x(1,1)");

+        String output = yamlPrinter.output(expression);

+        assertEquals(expectedOutput, output);

+    }

+

+    @Test

+    public void testWithoutType() {

+        String expectedOutput = "---" + System.lineSeparator();

+        expectedOutput += "root: " + System.lineSeparator();

+        expectedOutput += "    operator: \"PLUS\"" + System.lineSeparator();

+        expectedOutput += "    left: " + System.lineSeparator();

+        expectedOutput += "        value: \"1\"" + System.lineSeparator();

+        expectedOutput += "    right: " + System.lineSeparator();

+        expectedOutput += "        value: \"1\"" + System.lineSeparator();

+        expectedOutput += "...";

+

+        YamlPrinter yamlPrinter = new YamlPrinter(false);

+        Expression expression = JavaParser.parseExpression("1+1");

+        String output = yamlPrinter.output(expression);

+        assertEquals(expectedOutput, output);

+    }

+

+    @Test

+    public void testWithColonFollowedBySpaceInValue() {

+        String expectedOutput = "---" + System.lineSeparator();

+        expectedOutput += "root(Type=StringLiteralExpr): " + System.lineSeparator();

+        expectedOutput += "    value: \"a\\\\: b\"" + System.lineSeparator();

+        expectedOutput += "...";

+

+        YamlPrinter yamlPrinter = new YamlPrinter(true);

+        Expression expression = JavaParser.parseExpression("\"a\\\\: b\"");

+        String output = yamlPrinter.output(expression);

+        assertEquals(expectedOutput, output);

+    }

+

+    @Test

+    public void testWithColonFollowedByLineSeparatorInValue() {

+        String expectedOutput = "---" + System.lineSeparator();

+        expectedOutput += "root(Type=StringLiteralExpr): " + System.lineSeparator();

+        expectedOutput += "    value: \"a\\\\:\\\\nb\"" + System.lineSeparator();

+        expectedOutput += "...";

+

+        YamlPrinter yamlPrinter = new YamlPrinter(true);

+        Expression expression = JavaParser.parseExpression("\"a\\\\:\\\\nb\"");

+        String output = yamlPrinter.output(expression);

+        assertEquals(expectedOutput, output);

+    }

+}

diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/AbstractLexicalPreservingTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/AbstractLexicalPreservingTest.java
new file mode 100644
index 0000000..1088457
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/AbstractLexicalPreservingTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.expr.Expression;
+import org.junit.Before;
+
+import java.io.IOException;
+
+import static com.github.javaparser.utils.TestUtils.readResource;
+import static org.junit.Assert.assertEquals;
+
+public abstract class AbstractLexicalPreservingTest {
+
+    protected CompilationUnit cu;
+    protected Expression expression;
+
+    protected void considerCode(String code) {
+        cu = LexicalPreservingPrinter.setup(JavaParser.parse(code));
+    }
+
+    protected void considerExpression(String code) {
+        expression = LexicalPreservingPrinter.setup(JavaParser.parseExpression(code));
+    }
+
+    protected String considerExample(String resourceName) throws IOException {
+        String code = readExample(resourceName);
+        considerCode(code);
+        return code;
+    }
+
+    protected String readExample(String resourceName) throws IOException {
+        return readResource("com/github/javaparser/lexical_preservation_samples/" + resourceName + ".java.txt");
+    }
+
+    protected void assertTransformed(String exampleName, Node node) throws IOException {
+        String expectedCode = readExample(exampleName + "_expected");
+        String actualCode = LexicalPreservingPrinter.print(node);
+        assertEquals(expectedCode, actualCode);
+    }
+
+    protected void assertUnchanged(String exampleName) throws IOException {
+        String code = considerExample(exampleName + "_original");
+        assertEquals(code, LexicalPreservingPrinter.print(cu != null ? cu : expression));
+    }
+
+    protected void assertTransformedToString(String expectedPartialCode, Node node) {
+        String actualCode = LexicalPreservingPrinter.print(node);
+        assertEquals(expectedPartialCode, actualCode);
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/DifferenceTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/DifferenceTest.java
new file mode 100644
index 0000000..2fb98c1
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/DifferenceTest.java
@@ -0,0 +1,428 @@
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmElement;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmIndent;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmToken;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmUnindent;
+import com.github.javaparser.printer.lexicalpreservation.LexicalDifferenceCalculator.CsmChild;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+
+import static com.github.javaparser.TokenTypes.eolTokenKind;
+import static com.github.javaparser.TokenTypes.spaceTokenKind;
+import static com.github.javaparser.printer.lexicalpreservation.Difference.DifferenceElement.*;
+import static org.junit.Assert.assertEquals;
+
+public class DifferenceTest extends AbstractLexicalPreservingTest {
+
+    @Test
+    public void calculateDifferenceEmpty() {
+        LexicalDifferenceCalculator.CalculatedSyntaxModel a = new LexicalDifferenceCalculator.CalculatedSyntaxModel(Collections.emptyList());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel b = new LexicalDifferenceCalculator.CalculatedSyntaxModel(Collections.emptyList());
+        Difference diff = Difference.calculate(a, b);
+        assertEquals(0, diff.getElements().size());
+    }
+
+    @Test
+    public void calculateDifferenceAIsEmpty() {
+        Node n1 = new FieldDeclaration();
+        Node n2 = new MethodDeclaration();
+
+        LexicalDifferenceCalculator.CalculatedSyntaxModel a = new LexicalDifferenceCalculator.CalculatedSyntaxModel(Collections.emptyList());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel b = new LexicalDifferenceCalculator.CalculatedSyntaxModel(Arrays.asList(
+                new CsmToken(GeneratedJavaParserConstants.LPAREN),
+                new CsmChild(n1),
+                new CsmToken(GeneratedJavaParserConstants.RPAREN),
+                new CsmChild(n2)));
+        Difference diff = Difference.calculate(a, b);
+        assertEquals(4, diff.getElements().size());
+        assertEquals(added(new CsmToken(GeneratedJavaParserConstants.LPAREN)), diff.getElements().get(0));
+        assertEquals(added(new CsmChild(n1)), diff.getElements().get(1));
+        assertEquals(added(new CsmToken(GeneratedJavaParserConstants.RPAREN)), diff.getElements().get(2));
+        assertEquals(added(new CsmChild(n2)), diff.getElements().get(3));
+    }
+
+    @Test
+    public void calculateDifferenceBIsEmpty() {
+        Node n1 = new FieldDeclaration();
+        Node n2 = new MethodDeclaration();
+
+        LexicalDifferenceCalculator.CalculatedSyntaxModel a = new LexicalDifferenceCalculator.CalculatedSyntaxModel(Arrays.asList(
+                new CsmToken(GeneratedJavaParserConstants.LPAREN),
+                new CsmChild(n1),
+                new CsmToken(GeneratedJavaParserConstants.RPAREN),
+                new CsmChild(n2)));
+        LexicalDifferenceCalculator.CalculatedSyntaxModel b = new LexicalDifferenceCalculator.CalculatedSyntaxModel(Collections.emptyList());
+        Difference diff = Difference.calculate(a, b);
+        assertEquals(4, diff.getElements().size());
+        assertEquals(removed(new CsmToken(GeneratedJavaParserConstants.LPAREN)), diff.getElements().get(0));
+        assertEquals(removed(new CsmChild(n1)), diff.getElements().get(1));
+        assertEquals(removed(new CsmToken(GeneratedJavaParserConstants.RPAREN)), diff.getElements().get(2));
+        assertEquals(removed(new CsmChild(n2)), diff.getElements().get(3));
+    }
+
+    @Test
+    public void compilationUnitExampleWithPackageSetDiff() {
+        considerCode("class A {}");
+        CsmElement element = ConcreteSyntaxModel.forClass(cu.getClass());
+        PackageDeclaration packageDeclaration = new PackageDeclaration(new Name(new Name("foo"), "bar"));
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, cu);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, cu, ObservableProperty.PACKAGE_DECLARATION, null, packageDeclaration);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        assertEquals(3, diff.getElements().size());
+        assertEquals(added(new CsmChild(packageDeclaration)), diff.getElements().get(0));
+        assertEquals(kept(new CsmChild(cu.getType(0))), diff.getElements().get(1));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(2));
+    }
+
+    @Test
+    public void annotationDeclarationExampleWithModifierAdded() throws IOException {
+        considerExample("AnnotationDeclaration_Example1_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, annotationDeclaration);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.MODIFIERS, EnumSet.noneOf(Modifier.class), EnumSet.of(Modifier.PUBLIC));
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        diff.removeIndentationElements();
+        int i = 0;
+        assertEquals(added(new CsmToken(GeneratedJavaParserConstants.PUBLIC)), diff.getElements().get(i++));
+        assertEquals(added(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.AT)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.INTERFACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getName())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LBRACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(0))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(1))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(2))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(3))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(4))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(5))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RBRACE)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void annotationDeclarationExampleWithNameChanged() throws IOException {
+        considerExample("AnnotationDeclaration_Example1_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, annotationDeclaration);
+        SimpleName newName = new SimpleName("NewName");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.NAME,
+                annotationDeclaration.getName(), newName);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        diff.removeIndentationElements();
+        int i = 0;
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.AT)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.INTERFACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(removed(new CsmChild(annotationDeclaration.getName())), diff.getElements().get(i++));
+        assertEquals(added(new CsmChild(newName)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LBRACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(0))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(1))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(2))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(3))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(4))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(5))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RBRACE)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void annotationDeclarationExampleWithJavadocAdded() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        JavadocComment comment = new JavadocComment("Cool this annotation!");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, annotationDeclaration);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.COMMENT, null, comment);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        diff.removeIndentationElements();
+        int i = 0;
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.PUBLIC)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.AT)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.INTERFACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getName())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LBRACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(0))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(1))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(2))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(3))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(4))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(5))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RBRACE)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void annotationDeclarationExampleWithJavadocRemoved() throws IOException {
+        considerExample("AnnotationDeclaration_Example9_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, annotationDeclaration);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.COMMENT, annotationDeclaration.getComment().get(), null);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        diff.removeIndentationElements();
+        int i = 0;
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.PUBLIC)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.AT)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.INTERFACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getName())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LBRACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(0))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(1))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(2))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(3))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(4))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(5))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RBRACE)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void annotationDeclarationExampleWithModifierRemoved() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, annotationDeclaration);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.MODIFIERS, EnumSet.of(Modifier.PUBLIC), EnumSet.noneOf(Modifier.class));
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        diff.removeIndentationElements();
+        int i = 0;
+        assertEquals(removed(new CsmToken(GeneratedJavaParserConstants.PUBLIC)), diff.getElements().get(i++));
+        assertEquals(removed(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.AT)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.INTERFACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getName())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LBRACE)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(0))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(1))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(2))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(3))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(4))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(annotationDeclaration.getMember(5))), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RBRACE)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void removeDefaultValueInAnnotationMemberDeclaration() {
+        AnnotationMemberDeclaration md = considerAmd("int foo() default 10;");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(md);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(md, ObservableProperty.DEFAULT_VALUE, md.getDefaultValue(), null);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        int i = 0;
+        assertEquals(kept(new CsmChild(md.getType())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(md.getName())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LPAREN)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RPAREN)), diff.getElements().get(i++));
+        assertEquals(removed(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(removed(new CsmToken(GeneratedJavaParserConstants._DEFAULT)), diff.getElements().get(i++));
+        assertEquals(removed(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(removed(new CsmChild(md.getDefaultValue().get())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.SEMICOLON)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void addedDefaultValueInAnnotationMemberDeclaration() {
+        AnnotationMemberDeclaration md = considerAmd("int foo();");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(md);
+        Expression defaultValue = new IntegerLiteralExpr(("10"));
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(md, ObservableProperty.DEFAULT_VALUE, null, defaultValue);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        int i = 0;
+        assertEquals(kept(new CsmChild(md.getType())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(md.getName())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LPAREN)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RPAREN)), diff.getElements().get(i++));
+        assertEquals(added(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(added(new CsmToken(GeneratedJavaParserConstants._DEFAULT)), diff.getElements().get(i++));
+        assertEquals(added(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(added(new CsmChild(defaultValue)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.SEMICOLON)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void addedModifierToConstructorDeclaration() {
+        ConstructorDeclaration cd = considerCd("A(){}");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(cd);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(cd, ObservableProperty.MODIFIERS,
+                EnumSet.noneOf(Modifier.class), EnumSet.of(Modifier.PUBLIC));
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        int i = 0;
+        assertEquals(added(new CsmToken(GeneratedJavaParserConstants.PUBLIC)), diff.getElements().get(i++));
+        assertEquals(added(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(cd.getName())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.LPAREN)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(GeneratedJavaParserConstants.RPAREN)), diff.getElements().get(i++));
+        assertEquals(kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(kept(new CsmChild(cd.getBody())), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void replacingNameForEnumConstantDeclaration() throws IOException {
+        EnumConstantDeclaration ecd = considerEcd("A");
+        SimpleName newName = new SimpleName("B");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(ecd);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(ecd, ObservableProperty.NAME,
+                ecd.getName(), newName);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        int i = 0;
+        assertEquals(Difference.DifferenceElement.removed(new CsmChild(ecd.getName())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.added(new CsmChild(newName)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void addingStatementToEmptyMethodBody() {
+        String code = "class A { void foo(char p1, int p2) {} }";
+        considerCode(code);
+
+        Statement s = new ExpressionStmt(new BinaryExpr(
+                new IntegerLiteralExpr("10"), new IntegerLiteralExpr("2"), BinaryExpr.Operator.PLUS
+        ));
+        MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(m.getBody().get());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterListAddition(m.getBody().get(), ObservableProperty.STATEMENTS, 0, s);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        int i = 0;
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.LBRACE)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.added(new CsmIndent()), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.added(new CsmChild(s)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.added(new CsmToken(eolTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.added(new CsmUnindent()), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.RBRACE)), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void methodDeclarationRemovingParameter() {
+        MethodDeclaration md = considerMd("public void foo(float f){}");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(md);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterListRemoval(md, ObservableProperty.PARAMETERS, 0);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        int i = 0;
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.PUBLIC)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmChild(md.getType())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmChild(md.getName())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.LPAREN)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.removed(new CsmChild(md.getParameter(0))), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.RPAREN)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmChild(md.getBody().get())), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    @Test
+    public void methodDeclarationAddingParameter() {
+        MethodDeclaration md = considerMd("public void foo(){}");
+        Parameter newParameter = new Parameter(new ArrayType(PrimitiveType.intType()), new SimpleName("foo"));
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(md);
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterListAddition(md, ObservableProperty.PARAMETERS, 0, newParameter);
+        Difference diff = Difference.calculate(csmOriginal, csmChanged);
+        int i = 0;
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.PUBLIC)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmChild(md.getType())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmChild(md.getName())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.LPAREN)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.added(new CsmChild(newParameter)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(GeneratedJavaParserConstants.RPAREN)), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmToken(spaceTokenKind())), diff.getElements().get(i++));
+        assertEquals(Difference.DifferenceElement.kept(new CsmChild(md.getBody().get())), diff.getElements().get(i++));
+        assertEquals(i, diff.getElements().size());
+    }
+
+    private AnnotationMemberDeclaration considerAmd(String code) {
+        considerCode("@interface AD { " + code + " }");
+        return (AnnotationMemberDeclaration)cu.getAnnotationDeclarationByName("AD").get().getMember(0);
+    }
+
+    private ConstructorDeclaration considerCd(String code) {
+        considerCode("class A { " + code + " }");
+        return (ConstructorDeclaration) cu.getType(0).getMembers().get(0);
+    }
+
+    private EnumConstantDeclaration considerEcd(String code) {
+        considerCode("enum A { " + code + " }");
+        return ((EnumDeclaration)cu.getType(0)).getEntries().get(0);
+    }
+
+    private MethodDeclaration considerMd(String code) {
+        considerCode("class A { " + code + " }");
+        return (MethodDeclaration) cu.getType(0).getMembers().get(0);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/LexicalDifferenceCalculatorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/LexicalDifferenceCalculatorTest.java
new file mode 100644
index 0000000..d3e5490
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/LexicalDifferenceCalculatorTest.java
@@ -0,0 +1,300 @@
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.GeneratedJavaParserConstants;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.AnnotationDeclaration;
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.observer.ObservableProperty;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.ExpressionStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.printer.ConcreteSyntaxModel;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmElement;
+import com.github.javaparser.printer.concretesyntaxmodel.CsmToken;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+import static com.github.javaparser.TokenTypes.eolTokenKind;
+import static com.github.javaparser.TokenTypes.spaceTokenKind;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class LexicalDifferenceCalculatorTest extends AbstractLexicalPreservingTest {
+
+    @Test
+    public void compilationUnitExampleOriginal() {
+        considerCode("class A {}");
+        CsmElement element = ConcreteSyntaxModel.forClass(cu.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmOriginal = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, cu);
+        assertEquals(2, csmOriginal.elements.size());
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(cu.getType(0)), csmOriginal.elements.get(0));
+        assertEquals(new CsmToken(eolTokenKind()), csmOriginal.elements.get(1));
+    }
+
+    @Test
+    public void compilationUnitExampleWithPackageSet() {
+        considerCode("class A {}");
+        CsmElement element = ConcreteSyntaxModel.forClass(cu.getClass());
+        PackageDeclaration packageDeclaration = new PackageDeclaration(new Name(new Name("foo"), "bar"));
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csmChanged = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, cu, ObservableProperty.PACKAGE_DECLARATION, null, packageDeclaration);
+        assertEquals(3, csmChanged.elements.size());
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(packageDeclaration), csmChanged.elements.get(0));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(cu.getType(0)), csmChanged.elements.get(1));
+        assertEquals(new CsmToken(eolTokenKind()), csmChanged.elements.get(2));
+    }
+
+    @Test
+    public void annotationDeclarationModifiersExampleOriginal() throws IOException {
+        considerExample("AnnotationDeclaration_Example1_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csm = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, annotationDeclaration);
+        csm.removeIndentationElements();
+        int i = 0;
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.AT), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.INTERFACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getName()), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.LBRACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(0)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(1)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(2)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(3)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(4)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(5)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.RBRACE), csm.elements.get(i++));
+        assertEquals(i, csm.elements.size());
+    }
+
+    @Test
+    public void annotationDeclarationModifiersExampleModified() throws IOException {
+        considerExample("AnnotationDeclaration_Example1_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csm = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.MODIFIERS, EnumSet.noneOf(Modifier.class), EnumSet.of(Modifier.PUBLIC));
+        csm.removeIndentationElements();
+        int i = 0;
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.PUBLIC), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.AT), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.INTERFACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getName()), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.LBRACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(0)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(1)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(2)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(3)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(4)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(5)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.RBRACE), csm.elements.get(i++));
+        assertEquals(i, csm.elements.size());
+    }
+
+    @Test
+    public void annotationDeclarationNameExampleModified() throws IOException {
+        considerExample("AnnotationDeclaration_Example1_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        SimpleName newName = new SimpleName("NewName");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csm = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.NAME,
+                annotationDeclaration.getName(), newName);
+        csm.removeIndentationElements();
+        int i = 0;
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.AT), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.INTERFACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(newName), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.LBRACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(0)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(1)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(2)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(3)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(4)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(5)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.RBRACE), csm.elements.get(i++));
+        assertEquals(i, csm.elements.size());
+    }
+
+    @Test
+    public void annotationDeclaratioJavadocExampleOriginal() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csm = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(element, annotationDeclaration);
+        csm.removeIndentationElements();
+        int i = 0;
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.PUBLIC), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.AT), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.INTERFACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getName()), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.LBRACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(0)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(1)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(2)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(3)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(4)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(5)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.RBRACE), csm.elements.get(i++));
+        assertEquals(i, csm.elements.size());
+    }
+
+    @Test
+    public void annotationDeclaratioJavadocExampleAddingJavadoc() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        AnnotationDeclaration annotationDeclaration = (AnnotationDeclaration)cu.getType(0);
+        CsmElement element = ConcreteSyntaxModel.forClass(annotationDeclaration.getClass());
+        JavadocComment comment = new JavadocComment("Cool this annotation!");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csm = new LexicalDifferenceCalculator().calculatedSyntaxModelAfterPropertyChange(element, annotationDeclaration, ObservableProperty.COMMENT, null, comment);
+        csm.removeIndentationElements();
+        int i = 0;
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.PUBLIC), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.AT), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.INTERFACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getName()), csm.elements.get(i++));
+        assertEquals(new CsmToken(spaceTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.LBRACE), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(0)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(1)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(2)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(3)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(4)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(annotationDeclaration.getMember(5)), csm.elements.get(i++));
+        assertEquals(new CsmToken(eolTokenKind()), csm.elements.get(i++));
+        assertEquals(new CsmToken(GeneratedJavaParserConstants.RBRACE), csm.elements.get(i++));
+        assertEquals(i, csm.elements.size());
+    }
+
+    @Test
+    public void simpleEnumConstantDeclaration() throws IOException {
+        EnumConstantDeclaration ecd = considerEcd("A");
+        LexicalDifferenceCalculator.CalculatedSyntaxModel csm = new LexicalDifferenceCalculator().calculatedSyntaxModelForNode(ecd);
+
+        int i = 0;
+        assertEquals(new LexicalDifferenceCalculator.CsmChild(ecd.getName()), csm.elements.get(i++));
+        assertEquals(i, csm.elements.size());
+    }
+
+    @Test
+    public void csmModelAfterAddingStatementToEmptyBlock() throws IOException {
+        LexicalDifferenceCalculator ldc = new LexicalDifferenceCalculator();
+        considerExample("ASimpleClassWithMoreFormatting_step3");
+
+        MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
+                .getMethodsByName("setAField").get(0);
+        Statement assignStatement = new ExpressionStmt(
+                new AssignExpr(
+                        new FieldAccessExpr(new ThisExpr(),"aField"),
+                        new NameExpr("aField"),
+                        AssignExpr.Operator.ASSIGN
+                ));
+        LexicalDifferenceCalculator.CalculatedSyntaxModel calculatedSyntaxModel =
+                ldc.calculatedSyntaxModelAfterListAddition(
+                        ConcreteSyntaxModel.forClass(BlockStmt.class),
+                        ObservableProperty.STATEMENTS,
+                        setter.getBody().get().getStatements(),
+                        0,
+                        assignStatement);
+        int index = 0;
+        assertEquals(CsmElement.token(GeneratedJavaParserConstants.LBRACE), calculatedSyntaxModel.elements.get(index++));
+        assertEquals(CsmElement.newline(), calculatedSyntaxModel.elements.get(index++));
+        assertEquals(CsmElement.indent(), calculatedSyntaxModel.elements.get(index++));
+        assertTrue(isChild(calculatedSyntaxModel.elements.get(index++), ExpressionStmt.class));
+        assertEquals(CsmElement.newline(), calculatedSyntaxModel.elements.get(index++));
+        assertEquals(CsmElement.unindent(), calculatedSyntaxModel.elements.get(index++));
+        assertEquals(CsmElement.token(GeneratedJavaParserConstants.RBRACE), calculatedSyntaxModel.elements.get(index++));
+        assertEquals(index, calculatedSyntaxModel.elements.size());
+    }
+
+    @Test
+    public void differenceAfterddingStatementToEmptyBlock() throws IOException {
+        LexicalDifferenceCalculator ldc = new LexicalDifferenceCalculator();
+        considerExample("ASimpleClassWithMoreFormatting_step3");
+
+        MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
+                .getMethodsByName("setAField").get(0);
+        Statement assignStatement = new ExpressionStmt(
+                new AssignExpr(
+                        new FieldAccessExpr(new ThisExpr(),"aField"),
+                        new NameExpr("aField"),
+                        AssignExpr.Operator.ASSIGN
+                ));
+        Difference diff = ldc.calculateListAdditionDifference(
+                ObservableProperty.STATEMENTS,
+                setter.getBody().get().getStatements(),
+                0,
+                assignStatement);
+        int index = 0;
+        assertEquals(Difference.DifferenceElement.kept(CsmElement.token(GeneratedJavaParserConstants.LBRACE)), diff.getElements().get(index++));
+        assertEquals(Difference.DifferenceElement.kept(CsmElement.newline()), diff.getElements().get(index++));
+        assertEquals(Difference.DifferenceElement.added(CsmElement.indent()), diff.getElements().get(index++));
+        assertTrue(isAddedChild(diff.getElements().get(index++), ExpressionStmt.class));
+        assertEquals(Difference.DifferenceElement.added(CsmElement.newline()), diff.getElements().get(index++));
+        assertEquals(Difference.DifferenceElement.added(CsmElement.unindent()), diff.getElements().get(index++));
+        assertEquals(Difference.DifferenceElement.kept(CsmElement.token(GeneratedJavaParserConstants.RBRACE)), diff.getElements().get(index++));
+        assertEquals(index, diff.getElements().size());
+    }
+
+    private boolean isAddedChild(Difference.DifferenceElement element, Class<? extends Node> childClass) {
+        return element.isAdded() && isChild(element.getElement(), childClass);
+    }
+
+    private boolean isChild(CsmElement element, Class<? extends Node> childClass) {
+        return element instanceof LexicalDifferenceCalculator.CsmChild && childClass.isInstance(((LexicalDifferenceCalculator.CsmChild)element).getChild());
+    }
+
+    protected EnumConstantDeclaration considerEcd(String code) {
+        considerCode("enum A { " + code + " }");
+        return ((EnumDeclaration)cu.getType(0)).getEntries().get(0);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinterTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinterTest.java
new file mode 100644
index 0000000..796da14
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/LexicalPreservingPrinterTest.java
@@ -0,0 +1,1051 @@
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.*;
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.Type;
+import com.github.javaparser.ast.type.UnionType;
+import com.github.javaparser.ast.type.VoidType;
+import com.github.javaparser.ast.visitor.ModifierVisitor;
+import com.github.javaparser.ast.visitor.Visitable;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.NODE_TEXT_DATA;
+import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class LexicalPreservingPrinterTest extends AbstractLexicalPreservingTest {
+    private NodeText getTextForNode(Node node) {
+        return node.getData(NODE_TEXT_DATA);
+    }
+
+
+    //
+    // Tests on TextNode definition
+    //
+
+    @Test
+    public void checkNodeTextCreatedForSimplestClass() {
+        considerCode("class A {}");
+
+        // CU
+        assertEquals(1, getTextForNode(cu).numberOfElements());
+        assertEquals(true, getTextForNode(cu).getTextElement(0) instanceof ChildTextElement);
+        assertEquals(cu.getClassByName("A").get(), ((ChildTextElement)getTextForNode(cu).getTextElement(0)).getChild());
+
+        // Class
+        ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
+        assertEquals(7, getTextForNode(classA).numberOfElements());
+        assertEquals("class", getTextForNode(classA).getTextElement(0).expand());
+        assertEquals(" ", getTextForNode(classA).getTextElement(1).expand());
+        assertEquals("A", getTextForNode(classA).getTextElement(2).expand());
+        assertEquals(" ", getTextForNode(classA).getTextElement(3).expand());
+        assertEquals("{", getTextForNode(classA).getTextElement(4).expand());
+        assertEquals("}", getTextForNode(classA).getTextElement(5).expand());
+        assertEquals("", getTextForNode(classA).getTextElement(6).expand());
+        assertEquals(true, getTextForNode(classA).getTextElement(6) instanceof TokenTextElement);
+        assertEquals(GeneratedJavaParserConstants.EOF, ((TokenTextElement)getTextForNode(classA).getTextElement(6)).getTokenKind());
+    }
+
+    @Test
+    public void checkNodeTextCreatedForField() {
+        String code = "class A {int i;}";
+        considerCode(code);
+
+        ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
+        FieldDeclaration fd = classA.getFieldByName("i").get();
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(fd);
+        assertEquals(Arrays.asList("int", " ", "i", ";"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedForVariableDeclarator() {
+        String code = "class A {int i;}";
+        considerCode(code);
+
+        ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
+        FieldDeclaration fd = classA.getFieldByName("i").get();
+        VariableDeclarator vd = fd.getVariables().get(0);
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(vd);
+        assertEquals(Arrays.asList("i"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedForMethod() {
+        String code = "class A {void foo(int p1, float p2) { }}";
+        considerCode(code);
+
+        ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
+        MethodDeclaration md = classA.getMethodsByName("foo").get(0);
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
+        assertEquals(Arrays.asList("void", " ", "foo", "(", "int p1", ",", " ", "float p2", ")", " ", "{ }"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedForMethodParameter() {
+        String code = "class A {void foo(int p1, float p2) { }}";
+        considerCode(code);
+
+        ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
+        MethodDeclaration md = classA.getMethodsByName("foo").get(0);
+        Parameter p1 = md.getParameterByName("p1").get();
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(p1);
+        assertEquals(Arrays.asList("int", " ", "p1"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedForPrimitiveType() {
+        String code = "class A {void foo(int p1, float p2) { }}";
+        considerCode(code);
+
+        ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
+        MethodDeclaration md = classA.getMethodsByName("foo").get(0);
+        Parameter p1 = md.getParameterByName("p1").get();
+        Type t = p1.getType();
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(t);
+        assertEquals(Arrays.asList("int"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedForSimpleImport() {
+        String code = "import a.b.c.D;";
+        considerCode(code);
+
+        ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(imp);
+        assertEquals(Arrays.asList("import", " ", "a.b.c.D", ";", ""),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedGenericType() {
+        String code = "class A {ParseResult<T> result;}";
+        considerCode(code);
+
+        FieldDeclaration field = cu.getClassByName("A").get().getFieldByName("result").get();
+        Node t = field.getCommonType();
+        Node t2 = field.getVariable(0).getType();
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(field);
+        assertEquals(Arrays.asList("ParseResult", "<", "T", ">", " ", "result", ";"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedAnnotationDeclaration() {
+        String code = "public @interface ClassPreamble { String author(); }";
+        considerCode(code);
+
+        AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(ad);
+        assertEquals(Arrays.asList("public", " ", "@", "interface", " ", "ClassPreamble", " ", "{", " ", "String author();", " ", "}", ""),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedAnnotationMemberDeclaration() {
+        String code = "public @interface ClassPreamble { String author(); }";
+        considerCode(code);
+
+        AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
+        AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)ad.getMember(0);
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
+        assertEquals(Arrays.asList("String", " ", "author", "(", ")", ";"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedAnnotationMemberDeclarationWithArrayType() {
+        String code = "public @interface ClassPreamble { String[] author(); }";
+        considerCode(code);
+
+        AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
+        AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)ad.getMember(0);
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
+        assertEquals(Arrays.asList("String[]", " ", "author", "(", ")", ";"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedAnnotationMemberDeclarationArrayType() {
+        String code = "public @interface ClassPreamble { String[] author(); }";
+        considerCode(code);
+
+        AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
+        AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)ad.getMember(0).asAnnotationMemberDeclaration();
+        Type type = md.getType();
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(type);
+        assertEquals(Arrays.asList("String", "[", "]"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedAnnotationMemberDeclarationWithComment() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+
+        AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)cu.getAnnotationDeclarationByName("ClassPreamble").get().getMember(5).asAnnotationMemberDeclaration();
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
+        assertEquals(Arrays.asList("String[]", " ", "reviewers", "(", ")", ";"),
+                nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedArrayCreationLevelWithoutExpression() throws IOException {
+        considerExpression("new int[]");
+
+        ArrayCreationExpr arrayCreationExpr = (ArrayCreationExpr)expression.asArrayCreationExpr();
+        ArrayCreationLevel arrayCreationLevel = arrayCreationExpr.getLevels().get(0);
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(arrayCreationLevel);
+        assertEquals(Arrays.asList("[", "]"),
+                nodeText.getElements().stream().map(TextElement::expand).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void checkNodeTextCreatedArrayCreationLevelWith() throws IOException {
+        considerExpression("new int[123]");
+
+        ArrayCreationExpr arrayCreationExpr = (ArrayCreationExpr)expression.asArrayCreationExpr();
+        ArrayCreationLevel arrayCreationLevel = arrayCreationExpr.getLevels().get(0);
+        NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(arrayCreationLevel);
+        assertEquals(Arrays.asList("[", "123", "]"),
+                nodeText.getElements().stream().map(TextElement::expand).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
+    }
+
+    //
+    // Tests on findIndentation
+    //
+
+    @Test
+    public void findIndentationForAnnotationMemberDeclarationWithoutComment() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        Node node = cu.getAnnotationDeclarationByName("ClassPreamble").get().getMember(4);
+        List<TokenTextElement> indentation = LexicalPreservingPrinter.findIndentation(node);
+        assertEquals(Arrays.asList(" ", " ", " "), indentation.stream().map(TokenTextElement::expand).collect(Collectors.toList()));
+    }
+
+    @Test
+    public void findIndentationForAnnotationMemberDeclarationWithComment() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        Node node = cu.getAnnotationDeclarationByName("ClassPreamble").get().getMember(5);
+        List<TokenTextElement> indentation = LexicalPreservingPrinter.findIndentation(node);
+        assertEquals(Arrays.asList(" ", " ", " "), indentation.stream().map(TokenTextElement::expand).collect(Collectors.toList()));
+    }
+
+    //
+    // Tests on printing
+    //
+
+    @Test
+    public void printASuperSimpleCUWithoutChanges() {
+        String code = "class A {}";
+        considerCode(code);
+
+        assertEquals(code, LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void printASuperSimpleClassWithAFieldAdded() {
+        String code = "class A {}";
+        considerCode(code);
+
+        ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
+        classA.addField("int", "myField");
+        assertEquals("class A {" + EOL + "    int myField;"+EOL+"}", LexicalPreservingPrinter.print(classA));
+    }
+
+    @Test
+    public void printASuperSimpleClassWithoutChanges() {
+        String code = "class A {}";
+        considerCode(code);
+
+        assertEquals(code, LexicalPreservingPrinter.print(cu.getClassByName("A").get()));
+    }
+
+    @Test
+    public void printASimpleCUWithoutChanges() {
+        String code = "class /*a comment*/ A {\t\t"+EOL+" int f;"+EOL+EOL+EOL+"         void foo(int p  ) { return  'z'  \t; }}";
+        considerCode(code);
+
+        assertEquals(code, LexicalPreservingPrinter.print(cu));
+        assertEquals(code, LexicalPreservingPrinter.print(cu.getClassByName("A").get()));
+        assertEquals("void foo(int p  ) { return  'z'  \t; }", LexicalPreservingPrinter.print(cu.getClassByName("A").get().getMethodsByName("foo").get(0)));
+    }
+
+    @Test
+    public void printASimpleClassRemovingAField() {
+        String code = "class /*a comment*/ A {\t\t"+EOL+" int f;"+EOL+EOL+EOL+"         void foo(int p  ) { return  'z'  \t; }}";
+        considerCode(code);
+
+        ClassOrInterfaceDeclaration c = cu.getClassByName("A").get();
+        c.getMembers().remove(0);
+        assertEquals("class /*a comment*/ A {\t\t"+ EOL +
+                EOL +
+                "         void foo(int p  ) { return  'z'  \t; }}", LexicalPreservingPrinter.print(c));
+    }
+
+    @Test
+    public void printASimpleMethodAddingAParameterToAMethodWithZeroParameters() {
+        String code = "class A { void foo() {} }";
+        considerCode(code);
+
+        MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
+        m.addParameter("float", "p1");
+        assertEquals("void foo(float p1) {}", LexicalPreservingPrinter.print(m));
+    }
+
+    @Test
+    public void printASimpleMethodAddingAParameterToAMethodWithOneParameter() {
+        String code = "class A { void foo(char p1) {} }";
+        considerCode(code);
+
+        MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
+        m.addParameter("float", "p2");
+        assertEquals("void foo(char p1, float p2) {}", LexicalPreservingPrinter.print(m));
+    }
+
+    @Test
+    public void printASimpleMethodRemovingAParameterToAMethodWithOneParameter() {
+        String code = "class A { void foo(float p1) {} }";
+        considerCode(code);
+
+        MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
+        m.getParameters().remove(0);
+        assertEquals("void foo() {}", LexicalPreservingPrinter.print(m));
+    }
+
+    @Test
+    public void printASimpleMethodRemovingParameterOneFromMethodWithTwoParameters() {
+        String code = "class A { void foo(char p1, int p2) {} }";
+        considerCode(code);
+
+        MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
+        m.getParameters().remove(0);
+        assertEquals("void foo(int p2) {}", LexicalPreservingPrinter.print(m));
+    }
+
+    @Test
+    public void printASimpleMethodRemovingParameterTwoFromMethodWithTwoParameters() {
+        String code = "class A { void foo(char p1, int p2) {} }";
+        considerCode(code);
+
+        MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
+        m.getParameters().remove(1);
+        assertEquals("void foo(char p1) {}", LexicalPreservingPrinter.print(m));
+    }
+
+    @Test
+    public void printASimpleMethodAddingAStatement() {
+        String code = "class A { void foo(char p1, int p2) {} }";
+        considerCode(code);
+
+        Statement s = new ExpressionStmt(new BinaryExpr(
+                new IntegerLiteralExpr("10"), new IntegerLiteralExpr("2"), BinaryExpr.Operator.PLUS
+        ));
+        NodeList<Statement> stmts = cu.getClassByName("A").get().getMethodsByName("foo").get(0).getBody().get().getStatements();
+        stmts.add(s);
+        MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
+        assertEquals("void foo(char p1, int p2) {"+EOL +
+                "    10 + 2;"+ EOL +
+                "}", LexicalPreservingPrinter.print(m));
+    }
+
+    @Test
+    public void printASimpleImport() {
+        String code = "import a.b.c.D;";
+        considerCode(code);
+
+        ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
+        assertEquals("import a.b.c.D;", LexicalPreservingPrinter.print(imp));
+    }
+
+    @Test
+    public void printAnotherImport() {
+        String code = "import com.github.javaparser.ast.CompilationUnit;";
+        considerCode(code);
+
+        ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
+        assertEquals("import com.github.javaparser.ast.CompilationUnit;", LexicalPreservingPrinter.print(imp));
+    }
+
+    @Test
+    public void printAStaticImport() {
+        String code = "import static com.github.javaparser.ParseStart.*;";
+        considerCode(code);
+
+        ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
+        assertEquals("import static com.github.javaparser.ParseStart.*;", LexicalPreservingPrinter.print(imp));
+    }
+
+    @Test
+    public void checkAnnidatedTypeParametersPrinting() {
+        String code = "class A { private final Stack<Iterator<Triple>> its = new Stack<Iterator<Triple>>(); }";
+        considerCode(code);
+        assertEquals("class A { private final Stack<Iterator<Triple>> its = new Stack<Iterator<Triple>>(); }", LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void printASingleCatch() {
+        String code = "class A {{try { doit(); } catch (Exception e) {}}}";
+        considerCode(code);
+
+        assertEquals("class A {{try { doit(); } catch (Exception e) {}}}", LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void printAMultiCatch() {
+        String code = "class A {{try { doit(); } catch (Exception | AssertionError e) {}}}";
+        considerCode(code);
+
+        assertEquals("class A {{try { doit(); } catch (Exception | AssertionError e) {}}}", LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void printASingleCatchType() {
+        String code = "class A {{try { doit(); } catch (Exception e) {}}}";
+        considerCode(code);
+        InitializerDeclaration initializerDeclaration = (InitializerDeclaration)cu.getType(0).getMembers().get(0);
+        TryStmt tryStmt = (TryStmt)initializerDeclaration.getBody().getStatements().get(0);
+        CatchClause catchClause = tryStmt.getCatchClauses().get(0);
+        Type catchType = catchClause.getParameter().getType();
+
+        assertEquals("Exception", LexicalPreservingPrinter.print(catchType));
+    }
+
+    @Test
+    public void printUnionType() {
+        String code = "class A {{try { doit(); } catch (Exception | AssertionError e) {}}}";
+        considerCode(code);
+        InitializerDeclaration initializerDeclaration = (InitializerDeclaration)cu.getType(0).getMembers().get(0);
+        TryStmt tryStmt = (TryStmt)initializerDeclaration.getBody().getStatements().get(0);
+        CatchClause catchClause = tryStmt.getCatchClauses().get(0);
+        UnionType unionType = (UnionType)catchClause.getParameter().getType();
+
+        assertEquals("Exception | AssertionError", LexicalPreservingPrinter.print(unionType));
+    }
+
+    @Test
+    public void printParameterHavingUnionType() {
+        String code = "class A {{try { doit(); } catch (Exception | AssertionError e) {}}}";
+        considerCode(code);
+        InitializerDeclaration initializerDeclaration = (InitializerDeclaration)cu.getType(0).getMembers().get(0);
+        TryStmt tryStmt = (TryStmt)initializerDeclaration.getBody().getStatements().get(0);
+        CatchClause catchClause = tryStmt.getCatchClauses().get(0);
+        Parameter parameter = catchClause.getParameter();
+
+        assertEquals("Exception | AssertionError e", LexicalPreservingPrinter.print(parameter));
+    }
+
+    @Test
+    public void printLambaWithUntypedParams() {
+        String code = "class A {Function<String,String> f = a -> a;}";
+        considerCode(code);
+
+        assertEquals("class A {Function<String,String> f = a -> a;}", LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void printAModuleInfoSpecificKeywordUsedAsIdentifier1() {
+        considerCode("class module { }");
+
+        cu.getClassByName("module").get().setName("xyz");
+
+        assertEquals("class xyz { }", LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void printAModuleInfoSpecificKeywordUsedAsIdentifier2() {
+        considerCode("class xyz { }");
+
+        cu.getClassByName("xyz").get().setName("module");
+
+        assertEquals("class module { }", LexicalPreservingPrinter.print(cu));
+    }
+
+    // Issue 823: setPackageDeclaration on CU starting with a comment
+    @Test
+    public void reactToSetPackageDeclarationOnCuStartingWithComment() {
+        considerCode("// Hey, this is a comment\n" +
+                "\n" +
+                "\n" +
+                "// Another one\n" +
+                "\n" +
+                "class A {}");
+        cu.setPackageDeclaration("org.javaparser.lexicalpreservation.examples");
+    }
+
+    @Test
+    public void printLambdaIntersectionTypeAssignment() {
+        String code = "class A {" + EOL +
+                "  void f() {" + EOL +
+                "    Runnable r = (Runnable & Serializable) (() -> {});" + EOL +
+                "    r = (Runnable & Serializable)() -> {};" + EOL +
+                "    r = (Runnable & I)() -> {};" + EOL +
+                "  }}";
+        considerCode(code);
+
+        assertEquals(code, LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void printLambdaIntersectionTypeReturn() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        considerCode(code);
+
+        assertEquals(code, LexicalPreservingPrinter.print(cu));
+    }
+
+    // See issue #855
+    @Test
+    public void handleOverrideAnnotation() {
+        String code = "public class TestPage extends Page {" + EOL +
+                EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes()
+                .forEach(type -> type.getMembers()
+                        .forEach(member -> {
+                            if (member instanceof MethodDeclaration) {
+                                MethodDeclaration methodDeclaration = (MethodDeclaration) member;
+                                if (!methodDeclaration.getAnnotationByName("Override").isPresent()) {
+                                    methodDeclaration.addAnnotation("Override");
+                                }
+                            }
+                        }));
+        assertEquals("public class TestPage extends Page {" + EOL +
+                EOL +
+                "   @Override()" + EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}", LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void preserveSpaceAsIsForASimpleClassWithMoreFormatting() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting");
+        assertEquals(readExample("ASimpleClassWithMoreFormatting"), LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void renameASimpleClassWithMoreFormatting() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting");
+
+        cu.getClassByName("ASimpleClass").get()
+                .setName("MyRenamedClass");
+        assertEquals(readExample("ASimpleClassWithMoreFormatting_step1"), LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void theLexicalPreservationStringForAnAddedMethodShouldBeIndented() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting");
+
+        cu.getClassByName("ASimpleClass").get()
+                .setName("MyRenamedClass");
+        MethodDeclaration setter = cu
+                .getClassByName("MyRenamedClass").get()
+                .addMethod("setAField", Modifier.PUBLIC);
+        assertEquals("public void setAField() {" + EOL +
+                "    }", LexicalPreservingPrinter.print(setter));
+    }
+
+    @Test
+    public void addMethodToASimpleClassWithMoreFormatting() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting");
+
+        cu.getClassByName("ASimpleClass").get()
+                .setName("MyRenamedClass");
+        MethodDeclaration setter = cu
+                .getClassByName("MyRenamedClass").get()
+                .addMethod("setAField", Modifier.PUBLIC);
+        assertEquals(readExample("ASimpleClassWithMoreFormatting_step2"), LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void addingParameterToAnAddedMethodInASimpleClassWithMoreFormatting() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting");
+
+        cu.getClassByName("ASimpleClass").get()
+                .setName("MyRenamedClass");
+        MethodDeclaration setter = cu
+                .getClassByName("MyRenamedClass").get()
+                .addMethod("setAField", Modifier.PUBLIC);
+        setter.addParameter("boolean", "aField");
+        assertEquals(readExample("ASimpleClassWithMoreFormatting_step3"), LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void findIndentationOfEmptyMethod() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting_step3");
+
+        MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
+                .getMethodsByName("setAField").get(0);
+        assertEquals(4, LexicalPreservingPrinter.findIndentation(setter).size());
+        assertEquals(4, LexicalPreservingPrinter.findIndentation(setter.getBody().get()).size());
+    }
+
+    @Test
+    public void findIndentationOfMethodWithStatements() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting_step4");
+
+        MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
+                .getMethodsByName("setAField").get(0);
+        assertEquals(4, LexicalPreservingPrinter.findIndentation(setter).size());
+        assertEquals(4, LexicalPreservingPrinter.findIndentation(setter.getBody().get()).size());
+        assertEquals(8, LexicalPreservingPrinter.findIndentation(setter.getBody().get().getStatement(0)).size());
+    }
+
+    @Test
+    public void addingStatementToAnAddedMethodInASimpleClassWithMoreFormatting() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting");
+
+        cu.getClassByName("ASimpleClass").get()
+                .setName("MyRenamedClass");
+        MethodDeclaration setter = cu
+                .getClassByName("MyRenamedClass").get()
+                .addMethod("setAField", Modifier.PUBLIC);
+        setter.addParameter("boolean", "aField");
+        setter.getBody().get().getStatements().add(new ExpressionStmt(
+                new AssignExpr(
+                        new FieldAccessExpr(new ThisExpr(),"aField"),
+                        new NameExpr("aField"),
+                        AssignExpr.Operator.ASSIGN
+                )));
+        assertEquals(readExample("ASimpleClassWithMoreFormatting_step4"), LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void addingStatementToAnAddedMethodInASimpleClassWithMoreFormattingFromStep3() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting_step3");
+
+        MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
+                .getMethodsByName("setAField").get(0);
+        setter.getBody().get().getStatements().add(new ExpressionStmt(
+                new AssignExpr(
+                        new FieldAccessExpr(new ThisExpr(),"aField"),
+                        new NameExpr("aField"),
+                        AssignExpr.Operator.ASSIGN
+                )));
+        assertEquals(readExample("ASimpleClassWithMoreFormatting_step4"), LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void nodeTextForMethod() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting_step4");
+
+        MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
+                .getMethodsByName("setAField").get(0);
+        NodeText nodeText;
+
+        nodeText = getTextForNode(setter);
+        int index = 0;
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.PUBLIC));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(VoidType.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(SimpleName.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LPAREN));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(Parameter.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RPAREN));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(BlockStmt.class));
+        assertEquals(index, nodeText.getElements().size());
+
+        nodeText = getTextForNode(setter.getBody().get());
+        index = 0;
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LBRACE));
+        assertTrue(nodeText.getElements().get(index++).isNewline());
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(ExpressionStmt.class));
+        assertTrue(nodeText.getElements().get(index++).isNewline());
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RBRACE));
+        assertEquals(index, nodeText.getElements().size());
+
+        nodeText = getTextForNode(setter.getBody().get().getStatement(0));
+        index = 0;
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(AssignExpr.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SEMICOLON));
+        assertEquals(index, nodeText.getElements().size());
+    }
+
+    @Test
+    public void nodeTextForModifiedMethod() throws IOException {
+        considerExample("ASimpleClassWithMoreFormatting_step3");
+
+        MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
+                .getMethodsByName("setAField").get(0);
+        setter.getBody().get().getStatements().add(new ExpressionStmt(
+                new AssignExpr(
+                        new FieldAccessExpr(new ThisExpr(),"aField"),
+                        new NameExpr("aField"),
+                        AssignExpr.Operator.ASSIGN
+                )));
+        NodeText nodeText;
+
+        nodeText = getTextForNode(setter);
+        int index = 0;
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.PUBLIC));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(VoidType.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(SimpleName.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LPAREN));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(Parameter.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RPAREN));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(BlockStmt.class));
+        assertEquals(index, nodeText.getElements().size());
+
+        nodeText = getTextForNode(setter.getBody().get());
+        index = 0;
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LBRACE));
+        assertTrue(nodeText.getElements().get(index++).isNewline());
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(ExpressionStmt.class));
+        assertTrue(nodeText.getElements().get(index++).isNewline());
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RBRACE));
+        assertEquals(index, nodeText.getElements().size());
+
+        nodeText = LexicalPreservingPrinter.getOrCreateNodeText(setter.getBody().get().getStatement(0));
+        index = 0;
+        assertTrue(nodeText.getElements().get(index++).isChildOfClass(AssignExpr.class));
+        assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SEMICOLON));
+        assertEquals(index, nodeText.getElements().size());
+    }
+
+    // See issue #926
+    @Test
+    public void addASecondStatementToExistingMethod() throws IOException {
+        considerExample("MethodWithOneStatement");
+
+        MethodDeclaration methodDeclaration = cu.getType(0).getMethodsByName("someMethod").get(0);
+        methodDeclaration.getBody().get().getStatements().add(new ExpressionStmt(
+                new VariableDeclarationExpr(
+                        new VariableDeclarator(
+                                JavaParser.parseClassOrInterfaceType("String"),
+                                "test2",
+                                new StringLiteralExpr("")))
+        ));
+        assertEquals("public void someMethod() {" + EOL
+                + "        String test = \"\";" + EOL
+                + "        String test2 = \"\";" + EOL
+                + "    }", LexicalPreservingPrinter.print(methodDeclaration));
+    }
+
+    // See issue #866
+    @Test
+    public void moveOverrideAnnotations() {
+        String code = "public class TestPage extends Page {" + EOL +
+                EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   protected @Override void initializePage() {}" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes()
+                .forEach(type -> {
+                    type.getMembers()
+                            .forEach(member -> {
+                                member.ifMethodDeclaration(methodDeclaration -> {
+                                    if (methodDeclaration.getAnnotationByName("Override").isPresent()) {
+
+                                        while (methodDeclaration.getAnnotations().isNonEmpty()) {
+                                            AnnotationExpr annotationExpr = methodDeclaration.getAnnotations().get(0);
+                                            annotationExpr.remove();
+                                        }
+
+                                        methodDeclaration.addMarkerAnnotation("Override");
+                                    }
+                                });
+                            });
+                });
+        assertEquals("public class TestPage extends Page {" + EOL +
+                EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}", LexicalPreservingPrinter.print(cu));
+    }
+
+    // See issue #866
+    @Test
+    public void moveOrAddOverrideAnnotations() {
+        String code = "public class TestPage extends Page {" + EOL +
+                EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   protected @Override void initializePage() {}" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes()
+                .forEach(type -> {
+                    type.getMembers()
+                            .forEach(member -> {
+                                if (member instanceof MethodDeclaration) {
+                                    MethodDeclaration methodDeclaration = (MethodDeclaration) member;
+                                    if (methodDeclaration.getAnnotationByName("Override").isPresent()) {
+
+                                        while (methodDeclaration.getAnnotations().isNonEmpty()) {
+                                            AnnotationExpr annotationExpr = methodDeclaration.getAnnotations().get(0);
+                                            annotationExpr.remove();
+                                        }
+                                    }
+                                    methodDeclaration.addMarkerAnnotation("Override");
+                                }
+                            });
+                });
+        assertEquals("public class TestPage extends Page {" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}", LexicalPreservingPrinter.print(cu));
+    }
+
+    // See issue #865
+    @Test
+    public void handleAddingMarkerAnnotation() {
+        String code = "public class TestPage extends Page {" + EOL +
+                EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes()
+                .forEach(type -> {
+                    type.getMembers()
+                            .forEach(member -> {
+                                if (member instanceof MethodDeclaration) {
+                                    MethodDeclaration methodDeclaration = (MethodDeclaration) member;
+                                    if (!methodDeclaration.getAnnotationByName("Override").isPresent()) {
+                                        methodDeclaration.addMarkerAnnotation("Override");
+                                    }
+                                }
+                            });
+                });
+        assertEquals("public class TestPage extends Page {" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}", LexicalPreservingPrinter.print(cu));
+    }
+
+    // See issue #865
+    @Test
+    public void handleOverrideMarkerAnnotation() {
+        String code = "public class TestPage extends Page {" + EOL +
+                EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes()
+                .forEach(type -> type.getMembers()
+                        .forEach(member ->
+                            member.ifMethodDeclaration(methodDeclaration -> methodDeclaration.addMarkerAnnotation("Override")
+                        )));
+        assertEquals("public class TestPage extends Page {" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}", LexicalPreservingPrinter.print(cu));
+    }
+
+    // See issue #865
+    @Test
+    public void handleOverrideAnnotationAlternative() {
+        String code = "public class TestPage extends Page {" + EOL +
+                EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes()
+                .forEach(type -> type.getMembers()
+                        .forEach(member ->  member.ifMethodDeclaration(methodDeclaration -> methodDeclaration.addAnnotation("Override"))));
+        assertEquals("public class TestPage extends Page {" + EOL +
+                EOL +
+                "   @Override()" + EOL +
+                "   protected void test() {}" + EOL +
+                EOL +
+                "   @Override()" + EOL +
+                "   protected void initializePage() {}" + EOL +
+                "}", LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void invokeModifierVisitor() {
+        String code = "class A {" + EOL
+                + "  Object f() {" + EOL
+                + "    return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+                + "}}";
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+        cu.accept(new ModifierVisitor<>(), null);
+    }
+
+    @Test
+    public void handleDeprecatedAnnotationFinalClass() {
+        String code = "public final class A {}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes().forEach(type -> type.addAndGetAnnotation(Deprecated.class));
+
+        assertEquals("@Deprecated()" + EOL +
+                "public final class A {}" , LexicalPreservingPrinter.print(cu));
+
+    }
+
+    @Test
+    public void handleDeprecatedAnnotationAbstractClass() {
+        String code = "public abstract class A {}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+
+        cu.getTypes().forEach(type -> type.addAndGetAnnotation(Deprecated.class));
+
+        assertEquals("@Deprecated()" + EOL +
+                "public abstract class A {}" , LexicalPreservingPrinter.print(cu));
+    }
+
+    @Test
+    public void issue1244() {
+        String code = "public class Foo {" + EOL + EOL
+                + "// Some comment" + EOL + EOL // does work with only one \n
+                + "public void writeExternal() {}" + EOL + "}";
+        CompilationUnit originalCu = JavaParser.parse(code);
+        CompilationUnit cu = LexicalPreservingPrinter.setup(originalCu);
+
+        cu.findAll(ClassOrInterfaceDeclaration.class).stream().forEach(c -> {
+            List<MethodDeclaration> methods = c.getMethodsByName("writeExternal");
+            for (MethodDeclaration method : methods) {
+                c.remove(method);
+            }
+        });
+        assertEqualsNoEol("public class Foo {\n" +
+                "// Some comment\n\n" +
+                "}", LexicalPreservingPrinter.print(cu));
+    }
+
+    static class AddFooCallModifierVisitor extends ModifierVisitor<Void> {
+        @Override
+        public Visitable visit(MethodCallExpr n, Void arg) {
+            // Add a call to foo() on every found method call
+            return new MethodCallExpr(n, "foo");
+        }
+    }
+
+    // See issue 1277
+    @Test
+    public void testInvokeModifierVisitor() throws IOException {
+        String code = "class A {" + EOL +
+                "  public String message = \"hello\";" + EOL +
+                "   void bar() {" + EOL +
+                "     System.out.println(\"hello\");" + EOL +
+                "   }" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+        cu.accept(new AddFooCallModifierVisitor(), null);
+    }
+
+    static class CallModifierVisitor extends ModifierVisitor<Void> {
+        @Override
+        public Visitable visit(MethodCallExpr n, Void arg) {
+            // Add a call to foo() on every found method call
+            return new MethodCallExpr(n.clone(), "foo");
+        }
+    }
+
+    @Test
+    public void invokeModifierVisitorIssue1297() {
+        String code = "class A {" + EOL +
+                "   public void bar() {" + EOL +
+                "     System.out.println(\"hello\");" + EOL +
+                "     System.out.println(\"hello\");" + EOL +
+                "     // comment" + EOL +
+                "   }" + EOL +
+                "}";
+
+        CompilationUnit cu = JavaParser.parse(code);
+        LexicalPreservingPrinter.setup(cu);
+        cu.accept(new CallModifierVisitor(), null);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/TransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/TransformationsTest.java
new file mode 100644
index 0000000..ec89dd1
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/TransformationsTest.java
@@ -0,0 +1,143 @@
+package com.github.javaparser.printer.lexicalpreservation;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.NameExpr;
+import com.github.javaparser.ast.expr.NullLiteralExpr;
+import com.github.javaparser.ast.stmt.ReturnStmt;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.PrimitiveType;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+/**
+ * These tests are more "high level" than the ones in LexicalPreservingPrinterTest.
+ * The idea is to perform some transformations on the code, print it back and see if the generated code
+ * is the expected one. We do not care about the internal state of LexicalPreservingPrinter, just the visible result.
+ */
+public class TransformationsTest extends  AbstractLexicalPreservingTest {
+
+    @Test
+    public void unchangedSimpleClasses() throws IOException {
+        assertUnchanged("Example1");
+        assertUnchanged("Example2");
+    }
+
+    @Test
+    public void unchangedComplexFile() throws IOException {
+        assertUnchanged("Example4");
+    }
+
+    @Test
+    public void example1() throws IOException {
+        considerExample("Example1_original");
+        cu.getClassByName("A").get().getFieldByName("a").get().setModifiers(EnumSet.of(Modifier.STATIC));
+        assertTransformed("Example1", cu);
+    }
+
+    @Test
+    public void example2() throws IOException {
+        considerExample("Example2_original");
+        cu.getClassByName("A").get().getFieldByName("a").get().getVariable(0).setInitializer("10");
+        assertTransformed("Example2", cu);
+    }
+
+    @Test
+    public void example3() throws IOException {
+        considerExample("Example3_original");
+        cu.getClassByName("A").get().getFieldByName("a").get().getVariable(0).setInitializer((Expression) null);
+        assertTransformed("Example3", cu);
+    }
+
+    @Test
+    public void example5() throws IOException {
+        considerExample("Example5_original");
+        cu.getClassByName("A").get().getFieldByName("a").get().getVariable(0).setInitializer(new NullLiteralExpr());
+        assertTransformed("Example5", cu);
+    }
+
+    @Test
+    public void example6() throws IOException {
+        considerExample("Example6_original");
+        cu.getClassByName("A").get().getFieldByName("a").get().getVariable(0).setName("someOtherName");
+        assertTransformed("Example6", cu);
+    }
+
+    @Test
+    public void example7() throws IOException {
+        considerExample("Example7_original");
+        cu.getClassByName("A").get().getFieldByName("a").get().getVariable(0).setType(new ArrayType(PrimitiveType.intType()));
+        assertTransformed("Example7", cu);
+    }
+
+    @Test
+    public void example8() throws IOException {
+        considerExample("Example8_original");
+        FieldDeclaration fd = (FieldDeclaration) cu.getClassByName("A").get().getMember(0).asFieldDeclaration();
+        fd.addVariable(new VariableDeclarator(PrimitiveType.intType(), "b"));
+        assertTransformed("Example8", cu);
+    }
+
+    @Test
+    public void example9() throws IOException {
+        considerExample("Example9_original");
+        FieldDeclaration fd = (FieldDeclaration) cu.getClassByName("A").get().getMember(0).asFieldDeclaration();
+        fd.addVariable(new VariableDeclarator(new ArrayType(PrimitiveType.intType()), "b"));
+        assertTransformed("Example9", cu);
+    }
+
+    @Test
+    public void example10() throws IOException {
+        considerExample("Example10_original");
+        cu.getClassByName("A").get().getMembers().remove(0);
+        assertTransformed("Example10", cu);
+    }
+
+    @Test
+    public void exampleParam1() throws IOException {
+        considerExample("Example_param1_original");
+        MethodDeclaration md = (MethodDeclaration) cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        md.addParameter("int", "p1");
+        assertTransformed("Example_param1", cu);
+    }
+
+    @Test
+    public void exampleParam2() throws IOException {
+        considerExample("Example_param1_original");
+        MethodDeclaration md = (MethodDeclaration) cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        md.addParameter(new ArrayType(PrimitiveType.intType()), "p1");
+        md.addParameter("char", "p2");
+        assertTransformed("Example_param2", cu);
+    }
+
+    @Test
+    public void exampleParam3() throws IOException {
+        considerExample("Example_param3_original");
+        MethodDeclaration md = (MethodDeclaration) cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        md.getParameters().remove(0);
+        assertTransformed("Example_param3", cu);
+    }
+
+    @Test
+    public void exampleParam4() throws IOException {
+        considerExample("Example_param3_original");
+        MethodDeclaration md = (MethodDeclaration) cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        md.getParameters().remove(1);
+        assertTransformed("Example_param4", cu);
+    }
+
+    @Test
+    public void exampleParam5() throws IOException {
+        considerExample("Example_param3_original");
+        MethodDeclaration md = (MethodDeclaration) cu.getClassByName("A").get().getMember(0).asMethodDeclaration();
+        md.setType(PrimitiveType.intType());
+        assertTransformed("Example_param5b", cu);
+        md.getBody().get().getStatements().add(new ReturnStmt(new NameExpr("p1")));
+        assertTransformed("Example_param5", cu);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/ArrayCreationLevelTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/ArrayCreationLevelTransformationsTest.java
new file mode 100644
index 0000000..93cff34
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/ArrayCreationLevelTransformationsTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast;
+
+import com.github.javaparser.ast.ArrayCreationLevel;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.expr.ArrayCreationExpr;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import com.github.javaparser.utils.Utils;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * Transforming ArrayCreationLevel and verifying the LexicalPreservation works as expected.
+ */
+public class ArrayCreationLevelTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected ArrayCreationLevel consider(String code) {
+        considerExpression("new int" + code);
+        ArrayCreationExpr arrayCreationExpr = expression.asArrayCreationExpr();
+        return arrayCreationExpr.getLevels().get(0);
+    }
+
+    // Dimension
+
+    @Test
+    public void addingDimension() throws IOException {
+        ArrayCreationLevel it = consider("[]");
+        it.setDimension(new IntegerLiteralExpr("10"));
+        assertTransformedToString("[10]", it);
+    }
+
+    @Test
+    public void removingDimension() throws IOException {
+        ArrayCreationLevel it = consider("[10]");
+        it.removeDimension();
+        assertTransformedToString("[]", it);
+    }
+
+    @Test
+    public void replacingDimension() throws IOException {
+        ArrayCreationLevel it = consider("[10]");
+        it.setDimension(new IntegerLiteralExpr("12"));
+        assertTransformedToString("[12]", it);
+    }
+
+    // Annotations
+
+    @Test
+    public void addingAnnotation() throws IOException {
+        ArrayCreationLevel it = consider("[]");
+        it.addAnnotation("myAnno");
+        assertTransformedToString("@myAnno()"+ Utils.EOL+"[]", it);
+    }
+
+    @Test
+    public void removingAnnotation() throws IOException {
+        ArrayCreationLevel it = consider("@myAnno []");
+        it.getAnnotations().remove(0);
+        assertTransformedToString("[]", it);
+    }
+
+    @Test
+    public void replacingAnnotation() throws IOException {
+        ArrayCreationLevel it = consider("@myAnno []");
+        it.getAnnotations().set(0, new NormalAnnotationExpr(new Name("myOtherAnno"), new NodeList<>()));
+        assertTransformedToString("@myOtherAnno() []", it);
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/CompilationUnitTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/CompilationUnitTransformationsTest.java
new file mode 100644
index 0000000..3040378
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/CompilationUnitTransformationsTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast;
+
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static com.github.javaparser.utils.Utils.EOL;
+
+/**
+ * Transforming CompilationUnit and verifying the LexicalPreservation works as expected.
+ */
+public class CompilationUnitTransformationsTest extends AbstractLexicalPreservingTest {
+
+    // packageDeclaration
+
+    @Test
+    public void addingPackageDeclaration() throws IOException {
+        considerCode("class A {}");
+        cu.setPackageDeclaration(new PackageDeclaration(new Name(new Name("foo"), "bar")));
+        assertTransformedToString("package foo.bar;"+ EOL + EOL + "class A {}", cu);
+    }
+
+    @Test
+    public void removingPackageDeclaration() throws IOException {
+        considerCode("package foo.bar; class A {}");
+        cu.removePackageDeclaration();
+        assertTransformedToString("class A {}", cu);
+    }
+
+    @Test
+    public void replacingPackageDeclaration() throws IOException {
+        considerCode("package foo.bar; class A {}");
+        cu.setPackageDeclaration(new PackageDeclaration(new Name(new Name("foo2"), "baz")));
+        assertTransformedToString("package foo2.baz;" +
+                EOL + EOL +
+                " class A {}", cu);
+    }
+
+    // imports
+
+    // types
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/AnnotationDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/AnnotationDeclarationTransformationsTest.java
new file mode 100644
index 0000000..a2ffd40
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/AnnotationDeclarationTransformationsTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Transforming AnnotationDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class AnnotationDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    @Test
+    public void unchangedExamples() throws IOException {
+        assertUnchanged("AnnotationDeclaration_Example1");
+        assertUnchanged("AnnotationDeclaration_Example3");
+        assertUnchanged("AnnotationDeclaration_Example9");
+    }
+
+    // name
+
+    @Test
+    public void changingName() throws IOException {
+        considerExample("AnnotationDeclaration_Example1_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().setName("NewName");
+        assertTransformed("AnnotationDeclaration_Example1", cu);
+    }
+
+    // modifiers
+
+    @Test
+    public void addingModifiers() throws IOException {
+        considerExample("AnnotationDeclaration_Example1_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().setModifiers(EnumSet.of(Modifier.PUBLIC));
+        assertTransformed("AnnotationDeclaration_Example2", cu);
+    }
+
+    @Test
+    public void removingModifiers() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().setModifiers(EnumSet.noneOf(Modifier.class));
+        assertTransformed("AnnotationDeclaration_Example3", cu);
+    }
+
+    @Test
+    public void replacingModifiers() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().setModifiers(EnumSet.of(Modifier.PROTECTED));
+        assertTransformed("AnnotationDeclaration_Example4", cu);
+    }
+
+    // members
+
+    @Test
+    public void addingMember() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().addMember(new AnnotationMemberDeclaration(EnumSet.noneOf(Modifier.class), PrimitiveType.intType(), "foo", null));
+        assertTransformed("AnnotationDeclaration_Example5", cu);
+    }
+
+    @Test
+    public void removingMember() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().getMember(2).remove();
+        assertTransformed("AnnotationDeclaration_Example6", cu);
+    }
+
+    @Test
+    public void replacingMember() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().setMember(2, new AnnotationMemberDeclaration(EnumSet.noneOf(Modifier.class), PrimitiveType.intType(), "foo", null));
+        assertTransformed("AnnotationDeclaration_Example7", cu);
+    }
+
+    // javadoc
+
+    @Test
+    public void addingJavadoc() throws IOException {
+        considerExample("AnnotationDeclaration_Example3_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().setJavadocComment("Cool this annotation!");
+        assertTransformed("AnnotationDeclaration_Example8", cu);
+    }
+
+    @Test
+    public void removingJavadoc() throws IOException {
+        considerExample("AnnotationDeclaration_Example9_original");
+        boolean removed = cu.getAnnotationDeclarationByName("ClassPreamble").get().getJavadocComment().get().remove();
+        assertEquals(true, removed);
+        assertTransformed("AnnotationDeclaration_Example9", cu);
+    }
+
+    @Test
+    public void replacingJavadoc() throws IOException {
+        considerExample("AnnotationDeclaration_Example9_original");
+        cu.getAnnotationDeclarationByName("ClassPreamble").get().setJavadocComment("Super extra cool this annotation!!!");
+        assertTransformed("AnnotationDeclaration_Example10", cu);
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/AnnotationMemberDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/AnnotationMemberDeclarationTransformationsTest.java
new file mode 100644
index 0000000..6b55528
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/AnnotationMemberDeclarationTransformationsTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.AnnotationMemberDeclaration;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.expr.NormalAnnotationExpr;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.util.EnumSet;
+
+import static com.github.javaparser.utils.Utils.EOL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Transforming AnnotationMemberDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class AnnotationMemberDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected AnnotationMemberDeclaration consider(String code) {
+        considerCode("@interface AD { " + code + " }");
+        return cu.getAnnotationDeclarationByName("AD").get().getMember(0).asAnnotationMemberDeclaration();
+    }
+
+    // Name
+
+    @Test
+    public void changingName() {
+        AnnotationMemberDeclaration md = consider("int foo();");
+        md.setName("bar");
+        assertTransformedToString("int bar();", md);
+    }
+
+    // Type
+
+    @Test
+    public void changingType() {
+        AnnotationMemberDeclaration md = consider("int foo();");
+        md.setType("String");
+        assertTransformedToString("String foo();", md);
+    }
+
+    // Modifiers
+
+    @Test
+    public void addingModifiers() {
+        AnnotationMemberDeclaration md = consider("int foo();");
+        md.setModifiers(EnumSet.of(Modifier.PUBLIC));
+        assertTransformedToString("public int foo();", md);
+    }
+
+    @Test
+    public void removingModifiers() {
+        AnnotationMemberDeclaration md = consider("public int foo();");
+        md.setModifiers(EnumSet.noneOf(Modifier.class));
+        assertTransformedToString("int foo();", md);
+    }
+
+    @Test
+    public void replacingModifiers() {
+        AnnotationMemberDeclaration md = consider("public int foo();");
+        md.setModifiers(EnumSet.of(Modifier.PROTECTED));
+        assertTransformedToString("protected int foo();", md);
+    }
+
+    // Default value
+
+    @Test
+    public void addingDefaultValue() {
+        AnnotationMemberDeclaration md = consider("int foo();");
+        md.setDefaultValue(new IntegerLiteralExpr("10"));
+        assertTransformedToString("int foo() default 10;", md);
+    }
+
+    @Test
+    public void removingDefaultValue() {
+        AnnotationMemberDeclaration md = consider("int foo() default 10;");
+        assertEquals(true, md.getDefaultValue().get().remove());
+        assertTransformedToString("int foo();", md);
+    }
+
+    @Test
+    public void replacingDefaultValue() {
+        AnnotationMemberDeclaration md = consider("int foo() default 10;");
+        md.setDefaultValue(new IntegerLiteralExpr("11"));
+        assertTransformedToString("int foo() default 11;", md);
+    }
+
+    // Annotations
+
+    @Test
+    public void addingAnnotation() {
+        AnnotationMemberDeclaration it = consider("int foo();");
+        it.addAnnotation("myAnno");
+        assertTransformedToString("@myAnno()" + EOL + "int foo();", it);
+    }
+
+    @Test
+    public void addingTwoAnnotations() {
+        AnnotationMemberDeclaration it = consider("int foo();");
+        it.addAnnotation("myAnno");
+        it.addAnnotation("myAnno2");
+        assertTransformedToString("@myAnno()" + EOL + "@myAnno2()" + EOL + "int foo();", it);
+    }
+
+    @Test
+    public void removingAnnotationOnSomeLine() {
+        AnnotationMemberDeclaration it = consider("@myAnno int foo();");
+        it.getAnnotations().remove(0);
+        assertTransformedToString("int foo();", it);
+    }
+
+    @Test
+    public void removingAnnotationOnPrevLine() {
+        AnnotationMemberDeclaration it = consider("@myAnno" + EOL + "int foo();");
+        it.getAnnotations().remove(0);
+        assertTransformedToString("int foo();", it);
+    }
+
+    @Test
+    public void replacingAnnotation() {
+        AnnotationMemberDeclaration it = consider("@myAnno int foo();");
+        it.getAnnotations().set(0, new NormalAnnotationExpr(new Name("myOtherAnno"), new NodeList<>()));
+        assertTransformedToString("@myOtherAnno() int foo();", it);
+    }
+
+    // Javadoc
+
+    @Test
+    public void addingJavadoc() {
+        AnnotationMemberDeclaration it = consider("int foo();");
+        it.setJavadocComment("Cool this annotation!");
+        assertTransformedToString("@interface AD { /** Cool this annotation!*/" + EOL +
+                "int foo(); }", it.getParentNode().get());
+    }
+
+    @Test
+    public void removingJavadoc() {
+        AnnotationMemberDeclaration it = consider("/** Cool this annotation!*/ int foo();");
+        assertTrue(it.getJavadocComment().get().remove());
+        assertTransformedToString("@interface AD {  int foo(); }", it.getParentNode().get());
+    }
+
+    @Test
+    public void replacingJavadoc() {
+        AnnotationMemberDeclaration it = consider("/** Cool this annotation!*/ int foo();");
+        it.setJavadocComment("Super extra cool this annotation!!!");
+        assertTransformedToString("@interface AD { /** Super extra cool this annotation!!!*/ int foo(); }", it.getParentNode().get());
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/ClassOrInterfaceDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/ClassOrInterfaceDeclarationTransformationsTest.java
new file mode 100644
index 0000000..1be8037
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/ClassOrInterfaceDeclarationTransformationsTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.ast.type.TypeParameter;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+import static com.github.javaparser.utils.Utils.EOL;
+
+/**
+ * Transforming ClassOrInterfaceDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class ClassOrInterfaceDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected ClassOrInterfaceDeclaration consider(String code) {
+        considerCode(code);
+        return cu.getType(0).asClassOrInterfaceDeclaration();
+    }
+
+    // Name
+
+    @Test
+    public void settingName() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A {}");
+        cid.setName("B");
+        assertTransformedToString("class B {}", cid);
+    }
+
+    // isInterface
+
+    @Test
+    public void classToInterface() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A {}");
+        cid.setInterface(true);
+        assertTransformedToString("interface A {}", cid);
+    }
+
+    @Test
+    public void interfaceToClass() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("interface A {}");
+        cid.setInterface(false);
+        assertTransformedToString("class A {}", cid);
+    }
+
+    // typeParameters
+
+    @Test
+    public void addingTypeParameterWhenThereAreNone() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A {}");
+        cid.addTypeParameter(new TypeParameter("T", new NodeList<>()));
+        assertTransformedToString("class A<T> {}", cid);
+    }
+
+    @Test
+    public void addingTypeParameterAsFirstWhenThereAreSome() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A<U> {}");
+        cid.getTypeParameters().addFirst(new TypeParameter("T", new NodeList<>()));
+        assertTransformedToString("class A<T, U> {}", cid);
+    }
+
+    @Test
+    public void addingTypeParameterAsLastWhenThereAreSome() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A<U> {}");
+        cid.addTypeParameter(new TypeParameter("T", new NodeList<>()));
+        assertTransformedToString("class A<U, T> {}", cid);
+    }
+
+    // extendedTypes
+
+    @Test
+    public void addingExtendedTypes() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A {}");
+        cid.addExtendedType("Foo");
+        assertTransformedToString("class A extends Foo {}", cid);
+    }
+
+    @Test
+    public void removingExtendedTypes() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A extends Foo {}");
+        cid.getExtendedTypes().remove(0);
+        assertTransformedToString("public class A {}", cid);
+    }
+
+    @Test
+    public void replacingExtendedTypes() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A extends Foo {}");
+        cid.getExtendedTypes().set(0, parseClassOrInterfaceType("Bar"));
+        assertTransformedToString("public class A extends Bar {}", cid);
+    }
+
+    // implementedTypes
+
+    @Test
+    public void addingImplementedTypes() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A {}");
+        cid.addImplementedType("Foo");
+        assertTransformedToString("class A implements Foo {}", cid);
+    }
+
+    @Test
+    public void removingImplementedTypes() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A implements Foo {}");
+        cid.getImplementedTypes().remove(0);
+        assertTransformedToString("public class A {}", cid);
+    }
+
+    @Test
+    public void replacingImplementedTypes() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A implements Foo {}");
+        cid.getImplementedTypes().set(0, parseClassOrInterfaceType("Bar"));
+        assertTransformedToString("public class A implements Bar {}", cid);
+    }
+
+    // Modifiers
+
+    @Test
+    public void addingModifiers() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A {}");
+        cid.setModifiers(EnumSet.of(Modifier.PUBLIC));
+        assertTransformedToString("public class A {}", cid);
+    }
+
+    @Test
+    public void removingModifiers() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A {}");
+        cid.setModifiers(EnumSet.noneOf(Modifier.class));
+        assertTransformedToString("class A {}", cid);
+    }
+
+    @Test
+    public void replacingModifiers() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A {}");
+        cid.setModifiers(EnumSet.of(Modifier.PROTECTED));
+        assertTransformedToString("protected class A {}", cid);
+    }
+
+    // members
+
+    @Test
+    public void addingField() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("class A {}");
+        cid.addField("int", "foo");
+        assertTransformedToString("class A {" + EOL + "    int foo;" + EOL + "}", cid);
+    }
+
+    @Test
+    public void removingField() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A { int foo; }");
+        cid.getMembers().remove(0);
+        assertTransformedToString("public class A {}", cid);
+    }
+
+    @Test
+    public void replacingFieldWithAnotherField() throws IOException {
+        ClassOrInterfaceDeclaration cid = consider("public class A {float f;}");
+        cid.getMembers().set(0, new FieldDeclaration(EnumSet.noneOf(Modifier.class), new VariableDeclarator(PrimitiveType.intType(), "bar")));
+        assertTransformedToString("public class A {int bar;}", cid);
+    }
+
+    // Annotations
+
+    // Javadoc
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/ConstructorDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/ConstructorDeclarationTransformationsTest.java
new file mode 100644
index 0000000..6889a70
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/ConstructorDeclarationTransformationsTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.ConstructorDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+/**
+ * Transforming ConstructorDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class ConstructorDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected ConstructorDeclaration consider(String code) {
+        considerCode("class A { " + code + " }");
+        return cu.getType(0).getMembers().get(0).asConstructorDeclaration();
+    }
+
+    // Name
+
+    @Test
+    public void settingName() throws IOException {
+        ConstructorDeclaration cd = consider("A(){}");
+        cd.setName("B");
+        assertTransformedToString("B(){}", cd);
+    }
+
+    // JavaDoc
+
+    // Modifiers
+
+    @Test
+    public void addingModifiers() throws IOException {
+        ConstructorDeclaration cd = consider("A(){}");
+        cd.setModifiers(EnumSet.of(Modifier.PUBLIC));
+        assertTransformedToString("public A(){}", cd);
+    }
+
+    @Test
+    public void removingModifiers() throws IOException {
+        ConstructorDeclaration cd = consider("public A(){}");
+        cd.setModifiers(EnumSet.noneOf(Modifier.class));
+        assertTransformedToString("A(){}", cd);
+    }
+
+    @Test
+    public void replacingModifiers() throws IOException {
+        ConstructorDeclaration cd = consider("public A(){}");
+        cd.setModifiers(EnumSet.of(Modifier.PROTECTED));
+        assertTransformedToString("protected A(){}", cd);
+    }
+
+    // Parameters
+
+    @Test
+    public void addingParameters() throws IOException {
+        ConstructorDeclaration cd = consider("A(){}");
+        cd.addParameter(PrimitiveType.doubleType(), "d");
+        assertTransformedToString("A(double d){}", cd);
+    }
+
+    @Test
+    public void removingOnlyParameter() throws IOException {
+        ConstructorDeclaration cd = consider("public A(double d){}");
+        cd.getParameters().remove(0);
+        assertTransformedToString("public A(){}", cd);
+    }
+
+    @Test
+    public void removingFirstParameterOfMany() throws IOException {
+        ConstructorDeclaration cd = consider("public A(double d, float f){}");
+        cd.getParameters().remove(0);
+        assertTransformedToString("public A(float f){}", cd);
+    }
+
+    @Test
+    public void removingLastParameterOfMany() throws IOException {
+        ConstructorDeclaration cd = consider("public A(double d, float f){}");
+        cd.getParameters().remove(1);
+        assertTransformedToString("public A(double d){}", cd);
+    }
+
+    @Test
+    public void replacingOnlyParameter() throws IOException {
+        ConstructorDeclaration cd = consider("public A(float f){}");
+        cd.getParameters().set(0, new Parameter(new ArrayType(PrimitiveType.intType()), new SimpleName("foo")));
+        assertTransformedToString("public A(int[] foo){}", cd);
+    }
+
+    // ThrownExceptions
+
+    // Body
+
+    // Annotations
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/EnumConstantDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/EnumConstantDeclarationTransformationsTest.java
new file mode 100644
index 0000000..dff71cc
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/EnumConstantDeclarationTransformationsTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.body.EnumConstantDeclaration;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * Transforming EnumConstantDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class EnumConstantDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected EnumConstantDeclaration consider(String code) {
+        considerCode("enum A { " + code + " }");
+        return cu.getType(0).asEnumDeclaration().getEntries().get(0);
+    }
+
+    // Name
+
+    @Test
+    public void settingName() throws IOException {
+        EnumConstantDeclaration ecd = consider("A");
+        ecd.setName("B");
+        assertTransformedToString("B", ecd);
+    }
+
+    // Annotations
+
+    // Javadoc
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/EnumDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/EnumDeclarationTransformationsTest.java
new file mode 100644
index 0000000..e2a8fa3
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/EnumDeclarationTransformationsTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.EnumDeclaration;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+/**
+ * Transforming EnumDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class EnumDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected EnumDeclaration consider(String code) {
+        considerCode(code);
+        return cu.getType(0).asEnumDeclaration();
+    }
+
+    // Name
+
+    @Test
+    public void settingName() throws IOException {
+        EnumDeclaration cid = consider("enum A { E1, E2 }");
+        cid.setName("B");
+        assertTransformedToString("enum B { E1, E2 }", cid);
+    }
+
+    // implementedTypes
+
+    // Modifiers
+
+    @Test
+    public void addingModifiers() throws IOException {
+        EnumDeclaration ed = consider("enum A { E1, E2 }");
+        ed.setModifiers(EnumSet.of(Modifier.PUBLIC));
+        assertTransformedToString("public enum A { E1, E2 }", ed);
+    }
+
+    @Test
+    public void removingModifiers() throws IOException {
+        EnumDeclaration ed = consider("public enum A { E1, E2 }");
+        ed.setModifiers(EnumSet.noneOf(Modifier.class));
+        assertTransformedToString("enum A { E1, E2 }", ed);
+    }
+
+    @Test
+    public void replacingModifiers() throws IOException {
+        EnumDeclaration ed = consider("public enum A { E1, E2 }");
+        ed.setModifiers(EnumSet.of(Modifier.PROTECTED));
+        assertTransformedToString("protected enum A { E1, E2 }", ed);
+    }
+
+    // members
+
+    // Annotations
+
+    // Javadoc
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/FieldDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/FieldDeclarationTransformationsTest.java
new file mode 100644
index 0000000..994f5d8
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/FieldDeclarationTransformationsTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+/**
+ * Transforming FieldDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class FieldDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected FieldDeclaration consider(String code) {
+        considerCode("class A { " + code + " }");
+        return cu.getType(0).getMembers().get(0).asFieldDeclaration();
+    }
+
+    // JavaDoc
+
+    // Modifiers
+
+    @Test
+    public void addingModifiers() {
+        FieldDeclaration it = consider("int A;");
+        it.setModifiers(EnumSet.of(Modifier.PUBLIC));
+        assertTransformedToString("public int A;", it);
+    }
+
+    @Test
+    public void removingModifiers() {
+        FieldDeclaration it = consider("public int A;");
+        it.setModifiers(EnumSet.noneOf(Modifier.class));
+        assertTransformedToString("int A;", it);
+    }
+
+    @Test
+    public void replacingModifiers() {
+        FieldDeclaration it = consider("int A;");
+        it.setModifiers(EnumSet.of(Modifier.PROTECTED));
+        assertTransformedToString("protected int A;", it);
+    }
+
+    @Test
+    public void changingTypes() {
+        FieldDeclaration it = consider("int a, b;");
+        assertTransformedToString("int a, b;", it);
+        it.getVariable(0).setType("Xyz");
+        assertTransformedToString(" a, b;", it);
+        it.getVariable(1).setType("Xyz");
+        assertTransformedToString("Xyz a, b;", it);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/InitializerDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/InitializerDeclarationTransformationsTest.java
new file mode 100644
index 0000000..738acb3
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/InitializerDeclarationTransformationsTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.body.InitializerDeclaration;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+
+/**
+ * Transforming InitializerDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class InitializerDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected InitializerDeclaration consider(String code) {
+        considerCode("class A { " + code + " }");
+        return cu.getType(0).getMembers().get(0).asInitializerDeclaration();
+    }
+
+    // JavaDoc
+
+    // Body
+
+    // IsStatic
+
+    @Test
+    public void instanceToStatic() throws IOException {
+        InitializerDeclaration it = consider("{ /*some comment*/ }");
+        it.setStatic(true);
+        assertTransformedToString("static { /*some comment*/ }", it);
+    }
+
+    @Test
+    public void staticToInstance() throws IOException {
+        InitializerDeclaration it = consider("static { /*some comment*/ }");
+        it.setStatic(false);
+        assertTransformedToString("{ /*some comment*/ }", it);
+    }
+
+    // Annotations
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/MethodDeclarationTransformationsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/MethodDeclarationTransformationsTest.java
new file mode 100644
index 0000000..1f94f38
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/printer/lexicalpreservation/transformations/ast/body/MethodDeclarationTransformationsTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer.lexicalpreservation.transformations.ast.body;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.SimpleName;
+import com.github.javaparser.ast.type.ArrayType;
+import com.github.javaparser.ast.type.PrimitiveType;
+import com.github.javaparser.printer.lexicalpreservation.AbstractLexicalPreservingTest;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.EnumSet;
+
+/**
+ * Transforming MethodDeclaration and verifying the LexicalPreservation works as expected.
+ */
+public class MethodDeclarationTransformationsTest extends AbstractLexicalPreservingTest {
+
+    protected MethodDeclaration consider(String code) {
+        considerCode("class A { " + code + " }");
+        return cu.getType(0).getMembers().get(0).asMethodDeclaration();
+    }
+
+    // Name
+
+    @Test
+    public void settingName() throws IOException {
+        MethodDeclaration it = consider("void A(){}");
+        it.setName("B");
+        assertTransformedToString("void B(){}", it);
+    }
+
+    // JavaDoc
+
+    // Modifiers
+
+    @Test
+    public void addingModifiers() throws IOException {
+        MethodDeclaration it = consider("void A(){}");
+        it.setModifiers(EnumSet.of(Modifier.PUBLIC));
+        assertTransformedToString("public void A(){}", it);
+    }
+
+    @Test
+    public void removingModifiers() throws IOException {
+        MethodDeclaration it = consider("public void A(){}");
+        it.setModifiers(EnumSet.noneOf(Modifier.class));
+        assertTransformedToString("void A(){}", it);
+    }
+
+    @Test
+    public void replacingModifiers() throws IOException {
+        MethodDeclaration it = consider("public void A(){}");
+        it.setModifiers(EnumSet.of(Modifier.PROTECTED));
+        assertTransformedToString("protected void A(){}", it);
+    }
+
+    // Parameters
+
+    @Test
+    public void addingParameters() throws IOException {
+        MethodDeclaration it = consider("void foo(){}");
+        it.addParameter(PrimitiveType.doubleType(), "d");
+        assertTransformedToString("void foo(double d){}", it);
+    }
+
+    @Test
+    public void removingOnlyParameter() throws IOException {
+        MethodDeclaration it = consider("public void foo(double d){}");
+        it.getParameters().remove(0);
+        assertTransformedToString("public void foo(){}", it);
+    }
+
+    @Test
+    public void removingFirstParameterOfMany() throws IOException {
+        MethodDeclaration it = consider("public void foo(double d, float f){}");
+        it.getParameters().remove(0);
+        assertTransformedToString("public void foo(float f){}", it);
+    }
+
+    @Test
+    public void removingLastParameterOfMany() throws IOException {
+        MethodDeclaration it = consider("public void foo(double d, float f){}");
+        it.getParameters().remove(1);
+        assertTransformedToString("public void foo(double d){}", it);
+    }
+
+    @Test
+    public void replacingOnlyParameter() throws IOException {
+        MethodDeclaration it = consider("public void foo(float f){}");
+        it.getParameters().set(0, new Parameter(new ArrayType(PrimitiveType.intType()), new SimpleName("foo")));
+        assertTransformedToString("public void foo(int[] foo){}", it);
+    }
+
+    // ThrownExceptions
+
+    // Body
+
+    // Annotations
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/remove/NodeRemovalTest.java b/javaparser-testing/src/test/java/com/github/javaparser/remove/NodeRemovalTest.java
new file mode 100644
index 0000000..6620bb1
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/remove/NodeRemovalTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.remove;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.FieldDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class NodeRemovalTest {
+    private final CompilationUnit cu = new CompilationUnit();
+
+    @Test
+    public void testRemoveClassFromCompilationUnit() {
+        ClassOrInterfaceDeclaration testClass = cu.addClass("test");
+        assertEquals(1, cu.getTypes().size());
+        boolean remove = testClass.remove();
+        assertEquals(true, remove);
+        assertEquals(0, cu.getTypes().size());
+    }
+
+    @Test
+    public void testRemoveFieldFromClass() {
+        ClassOrInterfaceDeclaration testClass = cu.addClass("test");
+
+        FieldDeclaration addField = testClass.addField(String.class, "test");
+        assertEquals(1, testClass.getMembers().size());
+        boolean remove = addField.remove();
+        assertEquals(true, remove);
+        assertEquals(0, testClass.getMembers().size());
+    }
+
+    @Test
+    public void testRemoveStatementFromMethodBody() {
+        ClassOrInterfaceDeclaration testClass = cu.addClass("testC");
+
+        MethodDeclaration addMethod = testClass.addMethod("testM");
+        BlockStmt methodBody = addMethod.createBody();
+        Statement addStatement = methodBody.addAndGetStatement("test");
+        assertEquals(1, methodBody.getStatements().size());
+        boolean remove = addStatement.remove();
+        assertEquals(true, remove);
+        assertEquals(0, methodBody.getStatements().size());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/CodeGenerationUtilsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/CodeGenerationUtilsTest.java
new file mode 100644
index 0000000..dafe7ad
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/CodeGenerationUtilsTest.java
@@ -0,0 +1,22 @@
+package com.github.javaparser.utils;
+
+import org.junit.Test;
+
+import static com.github.javaparser.utils.CodeGenerationUtils.*;
+import static org.junit.Assert.*;
+
+public class CodeGenerationUtilsTest {
+    @Test
+    public void setters() {
+        assertEquals("setValue", setterName("value"));
+        assertEquals("setBlue", setterName("isBlue"));
+    }
+
+    @Test
+    public void getters() {
+        assertEquals("getValue", getterName(Object.class, "value"));
+        assertEquals("isBlue", getterName(Boolean.class, "isBlue"));
+        assertEquals("isBlue", getterName(Boolean.class, "blue"));
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/PairTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/PairTest.java
new file mode 100644
index 0000000..2a5b84a
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/PairTest.java
@@ -0,0 +1,21 @@
+package com.github.javaparser.utils;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class PairTest {
+    @Test
+    public void testToString() {
+        Pair<String, String> pair = new Pair<>("abc", "def");
+
+        assertEquals("<abc, def>", pair.toString());
+    }
+
+    @Test
+    public void testToStringNulls() {
+        Pair<String, String> pair = new Pair<>(null, null);
+
+        assertEquals("<null, null>", pair.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/SourceRootTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/SourceRootTest.java
new file mode 100644
index 0000000..a0bb50e
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/SourceRootTest.java
@@ -0,0 +1,38 @@
+package com.github.javaparser.utils;
+
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class SourceRootTest {
+    private final Path root = CodeGenerationUtils.classLoaderRoot(SourceRootTest.class).resolve("com/github/javaparser/utils/");
+    private final SourceRoot sourceRoot = new SourceRoot(root);
+
+    @Test
+    public void parseTestDirectory() throws IOException {
+
+        List<ParseResult<CompilationUnit>> parseResults = sourceRoot.tryToParse();
+        List<CompilationUnit> units = sourceRoot.getCompilationUnits();
+
+        assertEquals(2, units.size());
+        assertTrue(units.stream().allMatch(unit -> !unit.getTypes().isEmpty() || unit.getModule().isPresent()));
+        assertTrue(parseResults.stream().anyMatch(cu -> cu.getResult().get().getStorage().get().getPath().toString().contains("source" + File.separator + "root")));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void fileAsRootIsNotAllowed() {
+        Path path = CodeGenerationUtils.classLoaderRoot(SourceRootTest.class).resolve("/com/github/javaparser/utils/Bla.java");
+        new SourceRoot(path);
+    }
+    
+    
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/SourceZipTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/SourceZipTest.java
new file mode 100644
index 0000000..05e80ab
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/SourceZipTest.java
@@ -0,0 +1,81 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.utils;

+

+import com.github.javaparser.ParseResult;

+import com.github.javaparser.ast.CompilationUnit;

+import org.junit.Test;

+

+import java.io.IOException;

+import java.net.URISyntaxException;

+import java.nio.file.Path;

+import java.nio.file.Paths;

+import java.util.ArrayList;

+import java.util.List;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+public class SourceZipTest {

+

+    private final Path testDir = CodeGenerationUtils.mavenModuleRoot(SourceZipTest.class)

+            .resolve(Paths.get("..", "javaparser-testing", "src", "test", "resources", "com", "github", "javaparser",

+                    "source_zip"))

+            .normalize();

+

+    @Test

+    public void parseTestDirectory() throws URISyntaxException, IOException {

+        SourceZip sourceZip = new SourceZip(testDir.resolve("test.zip"));

+        List<Pair<Path, ParseResult<CompilationUnit>>> results = sourceZip.parse();

+        assertEquals(3, results.size());

+        List<CompilationUnit> units = new ArrayList<>();

+        for (Pair<Path, ParseResult<CompilationUnit>> pr : results) {

+            units.add(pr.b.getResult().get());

+        }

+        assertTrue(units.stream().noneMatch(unit -> unit.getTypes().isEmpty()));

+    }

+

+    @Test

+    public void parseTestDirectoryWithCallback() throws URISyntaxException, IOException {

+        SourceZip sourceZip = new SourceZip(testDir.resolve("test.zip"));

+        List<Pair<Path, ParseResult<CompilationUnit>>> results = new ArrayList<>();

+

+        sourceZip.parse((path, result) -> results.add(new Pair<>(path, result)));

+

+        assertEquals(3, results.size());

+        List<CompilationUnit> units = new ArrayList<>();

+        for (Pair<Path, ParseResult<CompilationUnit>> pr : results) {

+            units.add(pr.b.getResult().get());

+        }

+        assertTrue(units.stream().noneMatch(unit -> unit.getTypes().isEmpty()));

+    }

+

+    @Test(expected = IOException.class)

+    public void dirAsZipIsNotAllowed() throws IOException {

+        new SourceZip(testDir.resolve("test")).parse();

+    }

+

+    @Test(expected = IOException.class)

+    public void fileAsZipIsNotAllowed() throws IOException {

+        new SourceZip(testDir.resolve("test.txt")).parse();

+    }

+}

diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/TestUtils.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/TestUtils.java
new file mode 100644
index 0000000..24f1767
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/TestUtils.java
@@ -0,0 +1,155 @@
+package com.github.javaparser.utils;
+
+import com.github.javaparser.*;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.validator.Java9Validator;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+import java.io.*;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.*;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.utils.CodeGenerationUtils.f;
+import static com.github.javaparser.utils.Utils.EOL;
+import static com.github.javaparser.utils.Utils.normalizeEolInTextBlock;
+import static java.util.Arrays.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class TestUtils {
+    /**
+     * Takes care of setting all the end of line character to platform specific ones.
+     */
+    public static String readResource(String resourceName) throws IOException {
+        if (resourceName.startsWith("/")) {
+            resourceName = resourceName.substring(1);
+        }
+        try (final InputStream resourceAsStream = TestUtils.class.getClassLoader().getResourceAsStream(resourceName)) {
+            if (resourceAsStream == null) {
+                fail("not found: " + resourceName);
+            }
+            try (final InputStreamReader reader = new InputStreamReader(resourceAsStream, "utf-8");
+                 final BufferedReader br = new BufferedReader(reader)) {
+                final StringBuilder builder = new StringBuilder();
+                String line;
+                while ((line = br.readLine()) != null) {
+                    builder.append(line).append(Utils.EOL);
+                }
+                return builder.toString();
+            }
+        }
+    }
+
+    public static void assertInstanceOf(Class<?> expectedType, Object instance) {
+        assertEquals(true, expectedType.isAssignableFrom(instance.getClass()), f("%s is not an instance of %s.", instance.getClass(), expectedType));
+    }
+
+    /**
+     * Unzip a zip file into a directory.
+     */
+    public static void unzip(Path zipFile, Path outputFolder) throws IOException {
+        Log.info("Unzipping %s to %s", zipFile, outputFolder);
+
+        final byte[] buffer = new byte[1024 * 1024];
+
+        outputFolder.toFile().mkdirs();
+
+        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile.toFile()))) {
+            ZipEntry ze = zis.getNextEntry();
+
+            while (ze != null) {
+                final Path newFile = outputFolder.resolve(ze.getName());
+
+                if (ze.isDirectory()) {
+                    Log.trace("mkdir %s", newFile.toAbsolutePath());
+                    newFile.toFile().mkdirs();
+                } else {
+                    Log.info("unzip %s", newFile.toAbsolutePath());
+                    try (FileOutputStream fos = new FileOutputStream(newFile.toFile())) {
+                        int len;
+                        while ((len = zis.read(buffer)) > 0) {
+                            fos.write(buffer, 0, len);
+                        }
+                    }
+                }
+                zis.closeEntry();
+                ze = zis.getNextEntry();
+            }
+
+        }
+        Log.info("Unzipped %s to %s", zipFile, outputFolder);
+    }
+
+    /**
+     * Download a file from a URL to disk.
+     */
+    public static void download(URL url, Path destination) throws IOException {
+        OkHttpClient client = new OkHttpClient();
+        Request request = new Request.Builder()
+                .url(url)
+                .build();
+
+        Response response = client.newCall(request).execute();
+        Files.write(destination, response.body().bytes());
+    }
+
+    public static String temporaryDirectory() {
+        return System.getProperty("java.io.tmpdir");
+    }
+
+    public static void assertCollections(Collection<?> expected, Collection<?> actual) {
+        final StringBuilder out = new StringBuilder();
+        for (Object e : expected) {
+            if (actual.contains(e)) {
+                actual.remove(e);
+            } else {
+                out.append("Missing: ").append(e).append(EOL);
+            }
+        }
+        for (Object a : actual) {
+            out.append("Unexpected: ").append(a).append(EOL);
+        }
+
+        String s = out.toString();
+        if (s.isEmpty()) {
+            return;
+        }
+        fail(s);
+    }
+
+    public static void assertProblems(ParseResult<?> result, String... expectedArg) {
+        assertProblems(result.getProblems(), expectedArg);
+    }
+
+    public static void assertProblems(List<Problem> result, String... expectedArg) {
+        Set<String> actual = result.stream().map(Problem::toString).collect(Collectors.toSet());
+        Set<String> expected = new HashSet<>(asList(expectedArg));
+        assertCollections(expected, actual);
+    }
+
+    public static void assertNoProblems(ParseResult<?> result) {
+        assertProblems(result);
+    }
+
+    public static void assertExpressionValid(String expression) {
+        JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_9));
+        ParseResult<Expression> result = javaParser.parse(ParseStart.EXPRESSION, provider(expression));
+        assertEquals(true, result.isSuccessful(), result.getProblems().toString());
+    }
+
+    /**
+     * Assert that "actual" equals "expected", and that any EOL characters in "actual" are correct for the platform.
+     */
+    public static void assertEqualsNoEol(String expected, String actual) {
+        assertEquals(normalizeEolInTextBlock(expected, EOL), actual);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/UtilsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/UtilsTest.java
new file mode 100644
index 0000000..21ecf4c
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/UtilsTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.utils;
+
+import org.junit.Test;
+
+import static com.github.javaparser.utils.Utils.*;
+import static org.junit.Assert.assertEquals;
+
+public class UtilsTest {
+
+    @Test
+    public void testScreamingToCamelCase() {
+        assertEquals("abc", screamingToCamelCase("ABC"));
+        assertEquals("abcDef", screamingToCamelCase("ABC_DEF"));
+        assertEquals("abc", screamingToCamelCase("ABC_"));
+    }
+
+    @Test
+    public void screamingEmptyString() {
+        assertEquals("", camelCaseToScreaming(""));
+        assertEquals("ABC", camelCaseToScreaming("abc"));
+        assertEquals("HELLO_HELLO", camelCaseToScreaming("HelloHello"));
+        assertEquals("APE_TAIL", camelCaseToScreaming("apeTail"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void capitalizeOnEmptyString() {
+        capitalize("");
+    }
+
+    @Test
+    public void capitalizeOnStringOfOneCharacter() {
+        assertEquals("F", capitalize("f"));
+    }
+
+    @Test
+    public void capitalizeOnStringOfTwoCharacters() {
+        assertEquals("Fo", capitalize("fo"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void decapitalizeOnEmptyString() {
+        decapitalize("");
+    }
+
+    @Test
+    public void decapitalizeOnStringOfOneCharacter() {
+        assertEquals("f", decapitalize("F"));
+    }
+
+    @Test
+    public void decapitalizeOnStringOfTwoCharacters() {
+        assertEquals("fo", decapitalize("Fo"));
+    }
+    
+    @Test
+    public void normalizeEolInTextBlock() {
+        String result = Utils.normalizeEolInTextBlock("\r\n \r \n", "Q");
+        assertEquals("Q Q Q", result);
+    }
+
+    @Test
+    public void testTrimTrailingSpaces() {
+        assertEquals("abc", trimTrailingSpaces("abc"));
+        assertEquals("  abc", trimTrailingSpaces("  abc"));
+        assertEquals("abc", trimTrailingSpaces("abc  "));
+        assertEquals("  abc", trimTrailingSpaces("  abc  "));
+        assertEquals("abc", trimTrailingSpaces("abc\t\0"));
+        assertEquals("", trimTrailingSpaces("    "));
+        assertEquals("", trimTrailingSpaces(""));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorListTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorListTest.java
new file mode 100644
index 0000000..c0944ec
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorListTest.java
@@ -0,0 +1,187 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.utils;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Set;

+

+import org.junit.Test;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ast.CompilationUnit;

+import com.github.javaparser.ast.visitor.ObjectIdentityEqualsVisitor;

+import com.github.javaparser.ast.visitor.ObjectIdentityHashCodeVisitor;

+

+public class VisitorListTest {

+

+    @Test

+    public void visitorAddAll() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        VisitorList<CompilationUnit> vList = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        vList.addAll(list);

+        for (int i = 0; i < list.size(); i++)

+            assertEquals(list.get(i), vList.get(i));

+    }

+

+    @Test

+    public void visitorAddAllAtIndex() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class Y{}"));

+        VisitorList<CompilationUnit> vList = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        vList.add(JavaParser.parse("class A{}"));

+        vList.add(JavaParser.parse("class B{}"));

+        vList.addAll(2, list);

+        vList.add(JavaParser.parse("class C{}"));

+        for (int i = 0; i < list.size(); i++)

+            assertEquals(list.get(i), vList.get(2 + i));

+    }

+

+    @Test

+    public void visitorListContains() {

+        CompilationUnit x1 = JavaParser.parse("class X{}");

+        VisitorList<CompilationUnit> list = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        list.add(x1);

+        assertTrue(list.contains(x1));

+    }

+

+    @Test

+    public void visitorListContainsAll() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        VisitorList<CompilationUnit> vList = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        vList.addAll(list);

+        assertTrue(vList.size() == 2 && vList.containsAll(list));

+    }

+

+    @Test

+    public void visitorListIterator() {

+        VisitorList<CompilationUnit> list = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        CompilationUnit x1 = JavaParser.parse("class X{}");

+        list.add(x1);

+        CompilationUnit x2 = JavaParser.parse("class X{}");

+        list.add(x2);

+        Iterator<CompilationUnit> itr = list.iterator();

+        assertEquals(x1, itr.next());

+        itr.remove();

+        assertTrue(list.size() == 1);

+        assertEquals(x2, itr.next());

+        itr.remove();

+        assertTrue(list.size() == 0);

+    }

+

+    @Test

+    public void visitorListListIterator() {

+        VisitorList<CompilationUnit> list = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        CompilationUnit x1 = JavaParser.parse("class X{}");

+        list.add(x1);

+        CompilationUnit x2 = JavaParser.parse("class X{}");

+        list.add(x2);

+        Iterator<CompilationUnit> itr = list.listIterator(2);

+        assertEquals(x1, itr.next());

+        itr.remove();

+        assertTrue(list.size() == 3);

+        assertEquals(x2, itr.next());

+        itr.remove();

+        assertTrue(list.size() == 2);

+    }

+

+    @Test

+    public void visitorListRemove() {

+        CompilationUnit x1 = JavaParser.parse("class X{}");

+        VisitorList<CompilationUnit> list = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        list.add(x1);

+        assertTrue(list.remove(x1));

+    }

+

+    @Test

+    public void visitorListRemoveAll() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        VisitorList<CompilationUnit> vList = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        vList.addAll(list);

+        vList.removeAll(list);

+        assertTrue(vList.size() == 0);

+    }

+

+    @Test

+    public void visitorListRetainAll() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        VisitorList<CompilationUnit> vList = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        vList.addAll(list);

+        vList.add(JavaParser.parse("class X{}"));

+        vList.retainAll(list);

+        assertTrue(vList.size() == 2);

+    }

+

+    @Test

+    public void visitorListSubList() {

+        VisitorList<CompilationUnit> list = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        assertTrue(list.size() == 4);

+        List<CompilationUnit> subLst = list.subList(1, 3);

+        assertTrue(subLst.size() == 2);

+        subLst.add(JavaParser.parse("class X{}"));

+        assertTrue(subLst.size() == 3);

+        assertTrue(list.size() == 5);

+

+    }

+

+    @Test

+    public void visitorListToArray() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        List<CompilationUnit> vList = new VisitorList<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        vList.addAll(list);

+        for (CompilationUnit u : vList.toArray(new CompilationUnit[2]))

+            assertTrue(vList.contains(u));

+    }

+

+}

diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorMapTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorMapTest.java
new file mode 100644
index 0000000..03d4b7b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorMapTest.java
@@ -0,0 +1,80 @@
+package com.github.javaparser.utils;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.visitor.ObjectIdentityEqualsVisitor;
+import com.github.javaparser.ast.visitor.ObjectIdentityHashCodeVisitor;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class VisitorMapTest {
+    @Test
+    public void normalEqualsDoesDeepCompare() {
+        CompilationUnit x1 = JavaParser.parse("class X{}");
+        CompilationUnit x2 = JavaParser.parse("class X{}");
+
+        Map<CompilationUnit, Integer> map = new HashMap<>();
+        map.put(x1, 1);
+        map.put(x2, 2);
+        assertEquals(1, map.size());
+    }
+
+    @Test
+    public void objectIdentityEqualsDoesShallowCompare() {
+        CompilationUnit x1 = JavaParser.parse("class X{}");
+        CompilationUnit x2 = JavaParser.parse("class X{}");
+
+        Map<CompilationUnit, Integer> map = new VisitorMap<>(new ObjectIdentityHashCodeVisitor(), new ObjectIdentityEqualsVisitor());
+        map.put(x1, 1);
+        map.put(x2, 2);
+        assertEquals(2, map.size());
+    }
+    
+    @Test
+    public void visitorMapGet(){
+    	CompilationUnit x1 = JavaParser.parse("class X{}");
+
+        Map<CompilationUnit, Integer> map = new VisitorMap<>(new ObjectIdentityHashCodeVisitor(), new ObjectIdentityEqualsVisitor());
+        map.put(x1, 1);
+        assertEquals(1, (int)map.get(x1));
+    }
+    
+    @Test
+    public void visitorMapContainsKey(){
+    	CompilationUnit x1 = JavaParser.parse("class X{}");
+
+        Map<CompilationUnit, Integer> map = new VisitorMap<>(new ObjectIdentityHashCodeVisitor(), new ObjectIdentityEqualsVisitor());
+        map.put(x1, 1);
+        assertTrue(map.containsKey(x1));
+    }
+    
+    @Test
+    public void visitorMapPutAll(){
+    	CompilationUnit x1 = JavaParser.parse("class X{}");
+    	CompilationUnit x2 = JavaParser.parse("class Y{}");
+    	Map<CompilationUnit, Integer> map = new HashMap<>();
+    	map.put(x1, 1);
+    	map.put(x2, 2);
+    	Map<CompilationUnit, Integer> visitorMap = new VisitorMap<>(new ObjectIdentityHashCodeVisitor(), new ObjectIdentityEqualsVisitor());
+        visitorMap.putAll(map);
+        assertEquals(2, visitorMap.size());
+    }
+    
+    @Test
+    public void remove(){
+        CompilationUnit x1 = JavaParser.parse("class X{}");
+        VisitorMap<CompilationUnit, Integer> map = new VisitorMap<>(new ObjectIdentityHashCodeVisitor(), new ObjectIdentityEqualsVisitor());
+        map.put(x1, 1);
+        assertTrue(map.containsKey(x1));
+        
+        map.remove(x1);
+        
+        assertFalse(map.containsKey(x1));
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorSetTest.java b/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorSetTest.java
new file mode 100644
index 0000000..1d7730b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/utils/VisitorSetTest.java
@@ -0,0 +1,141 @@
+/*

+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.

+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.

+ *

+ * This file is part of JavaParser.

+ *

+ * JavaParser can be used either under the terms of

+ * a) the GNU Lesser General Public License as published by

+ *     the Free Software Foundation, either version 3 of the License, or

+ *     (at your option) any later version.

+ * b) the terms of the Apache License

+ *

+ * You should have received a copy of both licenses in LICENCE.LGPL and

+ * LICENCE.APACHE. Please refer to those files for details.

+ *

+ * JavaParser is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU Lesser General Public License for more details.

+ */

+

+package com.github.javaparser.utils;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.util.ArrayList;

+import java.util.HashSet;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Set;

+

+import org.junit.Test;

+

+import com.github.javaparser.JavaParser;

+import com.github.javaparser.ast.CompilationUnit;

+import com.github.javaparser.ast.visitor.ObjectIdentityEqualsVisitor;

+import com.github.javaparser.ast.visitor.ObjectIdentityHashCodeVisitor;

+

+public class VisitorSetTest {

+

+    @Test

+    public void normalEqualsDoesDeepCompare() {

+        Set<CompilationUnit> set = new HashSet<>();

+        set.add(JavaParser.parse("class X{}"));

+        set.add(JavaParser.parse("class X{}"));

+        assertEquals(1, set.size());

+    }

+

+    @Test

+    public void objectIdentityEqualsDoesShallowCompare() {

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        set.add(JavaParser.parse("class X{}"));

+        set.add(JavaParser.parse("class X{}"));

+        assertEquals(2, set.size());

+    }

+

+    @Test

+    public void visitorSetContains() {

+        CompilationUnit x1 = JavaParser.parse("class X{}");

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        set.add(x1);

+        assertTrue(set.contains(x1));

+    }

+

+    @Test

+    public void visitorSetContainsAll() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        set.addAll(list);

+        assertTrue(set.size() == 2 && set.containsAll(list));

+    }

+

+    @Test

+    public void visitorSetIterator() {

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        CompilationUnit x1 = JavaParser.parse("class X{}");

+        set.add(x1);

+        CompilationUnit x2 = JavaParser.parse("class X{}");

+        set.add(x2);

+        Iterator<CompilationUnit> itr = set.iterator();

+        assertEquals(x1, itr.next());

+        itr.remove();

+        assertTrue(set.size() == 1);

+        assertEquals(x2, itr.next());

+        itr.remove();

+        assertTrue(set.size() == 0);

+    }

+

+    @Test

+    public void visitorSetRemove() {

+        CompilationUnit x1 = JavaParser.parse("class X{}");

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        set.add(x1);

+        assertTrue(set.remove(x1));

+    }

+

+    @Test

+    public void visitorSetRemoveAll() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        set.addAll(list);

+        set.removeAll(list);

+        assertTrue(set.size() == 0);

+    }

+

+    @Test

+    public void visitorSetRetainAll() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        set.addAll(list);

+        set.add(JavaParser.parse("class X{}"));

+        set.retainAll(list);

+        assertTrue(set.size() == 2);

+    }

+

+    @Test

+    public void visitorSetToArray() {

+        List<CompilationUnit> list = new ArrayList<>();

+        list.add(JavaParser.parse("class X{}"));

+        list.add(JavaParser.parse("class X{}"));

+        Set<CompilationUnit> set = new VisitorSet<>(new ObjectIdentityHashCodeVisitor(),

+                new ObjectIdentityEqualsVisitor());

+        set.addAll(list);

+        for (CompilationUnit u : set.toArray(new CompilationUnit[2]))

+            assertTrue(set.contains(u));

+    }

+}

diff --git a/javaparser-testing/src/test/java/com/github/javaparser/version/Java10PostProcessorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/version/Java10PostProcessorTest.java
new file mode 100644
index 0000000..4f9af27
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/version/Java10PostProcessorTest.java
@@ -0,0 +1,28 @@
+package com.github.javaparser.version;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ParseResult;
+import com.github.javaparser.ParserConfiguration;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.VarType;
+import org.junit.Test;
+
+import java.util.List;
+
+import static com.github.javaparser.ParseStart.STATEMENT;
+import static com.github.javaparser.ParserConfiguration.LanguageLevel.JAVA_10;
+import static com.github.javaparser.Providers.provider;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class Java10PostProcessorTest {
+    public static final JavaParser javaParser = new JavaParser(new ParserConfiguration().setLanguageLevel(JAVA_10));
+
+    @Test
+    public void varIsAType() {
+        ParseResult<Statement> result = javaParser.parse(STATEMENT, provider("var x=\"\";"));
+
+        List<VarType> allVarTypes = result.getResult().get().findAll(VarType.class);
+
+        assertEquals(1, allVarTypes.size());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ChangingMethodsFromAClassWithAVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ChangingMethodsFromAClassWithAVisitorTest.java
new file mode 100644
index 0000000..677cfcc
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ChangingMethodsFromAClassWithAVisitorTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import org.junit.Test;
+
+public class ChangingMethodsFromAClassWithAVisitorTest {
+    @Test
+    public void printingTheCompilationUnitToSystemOutput() throws Exception {
+        try (TestFileToken f = new TestFileToken("test.java")) {
+            MethodChanger_1.main(new String[]{});
+        }
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ChangingMethodsFromAClassWithoutAVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ChangingMethodsFromAClassWithoutAVisitorTest.java
new file mode 100644
index 0000000..9301ff5
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ChangingMethodsFromAClassWithoutAVisitorTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import org.junit.Test;
+
+public class ChangingMethodsFromAClassWithoutAVisitorTest {
+    @Test
+    public void printingTheCompilationUnitToSystemOutput() throws Exception {
+        try (TestFileToken f = new TestFileToken("test.java")) {
+            MethodChanger_2.main(new String[]{});
+        }
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ClassCreator.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ClassCreator.java
new file mode 100644
index 0000000..1e1d91b
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/ClassCreator.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.PackageDeclaration;
+import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.Parameter;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.VoidType;
+
+import java.util.EnumSet;
+
+import static com.github.javaparser.JavaParser.parseClassOrInterfaceType;
+import static com.github.javaparser.JavaParser.parseName;
+
+public class ClassCreator {
+
+    public static void main(String[] args) throws Exception {
+        // creates the compilation unit
+        CompilationUnit cu = createCU();
+
+        // prints the created compilation unit
+        System.out.println(cu.toString());
+    }
+
+    /**
+     * creates the compilation unit
+     */
+    private static CompilationUnit createCU() {
+        CompilationUnit cu = new CompilationUnit();
+        // set the package
+        cu.setPackageDeclaration(new PackageDeclaration(parseName("java.parser.test")));
+
+        // or a shortcut
+        cu.setPackageDeclaration("java.parser.test");
+
+        // create the type declaration 
+        ClassOrInterfaceDeclaration type = cu.addClass("GeneratedClass");
+
+        // create a method
+        EnumSet<Modifier> modifiers = EnumSet.of(Modifier.PUBLIC);
+        MethodDeclaration method = new MethodDeclaration(modifiers, new VoidType(), "main");
+        modifiers.add(Modifier.STATIC);
+        method.setModifiers(modifiers);
+        type.addMember(method);
+        
+        // or a shortcut
+        MethodDeclaration main2 = type.addMethod("main2", Modifier.PUBLIC, Modifier.STATIC);
+
+        // add a parameter to the method
+        Parameter param = new Parameter(parseClassOrInterfaceType("String"), "args");
+        param.setVarArgs(true);
+        method.addParameter(param);
+        
+        // or a shortcut
+        main2.addAndGetParameter(String.class, "args").setVarArgs(true);
+
+        // add a body to the method
+        BlockStmt block = new BlockStmt();
+        method.setBody(block);
+
+        // add a statement to the method body
+        NameExpr clazz = new NameExpr("System");
+        FieldAccessExpr field = new FieldAccessExpr(clazz, "out");
+        MethodCallExpr call = new MethodCallExpr(field, "println");
+        call.addArgument(new StringLiteralExpr("Hello World!"));
+        block.addStatement(call);
+
+        return cu;
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/CreatingACompilationUnitFromScratch.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/CreatingACompilationUnitFromScratch.java
new file mode 100644
index 0000000..fa256d2
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/CreatingACompilationUnitFromScratch.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import org.junit.Test;
+
+public class CreatingACompilationUnitFromScratch {
+    @Test
+    public void printingTheCompilationUnitToSystemOutput() throws Exception {
+        ClassCreator.main(new String[]{});
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/CuPrinter.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/CuPrinter.java
new file mode 100644
index 0000000..89653f4
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/CuPrinter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+
+import java.io.FileInputStream;
+
+public class CuPrinter {
+
+    public static void main(String[] args) throws Exception {
+        // creates an input stream for the file to be parsed
+        FileInputStream in = new FileInputStream("test.java");
+
+        // parse the file
+        CompilationUnit cu = JavaParser.parse(in);
+
+        // prints the resulting compilation unit to default system output
+        System.out.println(cu.toString());
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodChanger_1.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodChanger_1.java
new file mode 100644
index 0000000..1d64866
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodChanger_1.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+
+import java.io.File;
+
+public class MethodChanger_1 {
+
+    public static void main(String[] args) throws Exception {
+        // parse a file
+        CompilationUnit cu = JavaParser.parse(new File("test.java"));
+
+        // visit and change the methods names and parameters
+        cu.accept(new MethodChangerVisitor(), null);
+
+        // prints the changed compilation unit
+        System.out.println(cu);
+    }
+
+    /**
+     * Simple visitor implementation for visiting MethodDeclaration nodes.
+     */
+    private static class MethodChangerVisitor extends VoidVisitorAdapter<Void> {
+        @Override
+        public void visit(MethodDeclaration n, Void arg) {
+            // change the name of the method to upper case
+            n.setName(n.getNameAsString().toUpperCase());
+
+            // add a new parameter to the method
+            n.addParameter("int", "value");
+        }
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodChanger_2.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodChanger_2.java
new file mode 100644
index 0000000..bf0c72d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodChanger_2.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.NodeList;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.body.TypeDeclaration;
+
+import java.io.FileInputStream;
+
+import static com.github.javaparser.ast.type.PrimitiveType.intType;
+
+public class MethodChanger_2 {
+
+    public static void main(String[] args) throws Exception {
+        // creates an input stream for the file to be parsed
+        FileInputStream in = new FileInputStream("test.java");
+        
+        // parse the file
+        CompilationUnit cu = JavaParser.parse(in);
+
+        // change the methods names and parameters
+        changeMethods(cu);
+
+        // prints the changed compilation unit
+        System.out.println(cu.toString());
+    }
+
+    private static void changeMethods(CompilationUnit cu) {
+        // Go through all the types in the file
+        NodeList<TypeDeclaration<?>> types = cu.getTypes();
+        for (TypeDeclaration<?> type : types) {
+            // Go through all fields, methods, etc. in this type
+            NodeList<BodyDeclaration<?>> members = type.getMembers();
+            for (BodyDeclaration<?> member : members) {
+                if (member instanceof MethodDeclaration) {
+                    MethodDeclaration method = (MethodDeclaration) member;
+                    changeMethod(method);
+                }
+            }
+        }
+    }
+
+    private static void changeMethod(MethodDeclaration n) {
+        // change the name of the method to upper case
+        n.setName(n.getNameAsString().toUpperCase());
+
+        // create the new parameter
+        n.addParameter(intType(), "value");
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodPrinter.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodPrinter.java
new file mode 100644
index 0000000..8e1e5bf
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/MethodPrinter.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+
+import java.io.FileInputStream;
+
+public class MethodPrinter {
+
+    public static void main(String[] args) throws Exception {
+        // creates an input stream for the file to be parsed
+        FileInputStream in = new FileInputStream("test.java");
+
+        // parse it
+        CompilationUnit cu = JavaParser.parse(in);
+
+        // visit and print the methods names
+        cu.accept(new MethodVisitor(), null);
+    }
+
+    /**
+     * Simple visitor implementation for visiting MethodDeclaration nodes.
+     */
+    private static class MethodVisitor extends VoidVisitorAdapter<Void> {
+        @Override
+        public void visit(MethodDeclaration n, Void arg) {
+            /* here you can access the attributes of the method.
+             this method will be called for all methods in this 
+             CompilationUnit, including inner class methods */
+            System.out.println(n.getName());
+            super.visit(n, arg);
+        }
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/PrintingTheCompilationUnitToSystemOutputTest.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/PrintingTheCompilationUnitToSystemOutputTest.java
new file mode 100644
index 0000000..26a907e
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/PrintingTheCompilationUnitToSystemOutputTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import org.junit.Test;
+
+public class PrintingTheCompilationUnitToSystemOutputTest {
+    @Test
+    public void printingTheCompilationUnitToSystemOutput() throws Exception {
+        try (TestFileToken f = new TestFileToken("test.java")) {
+            CuPrinter.main(new String[]{});
+        }
+    }
+
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/TestFileToken.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/TestFileToken.java
new file mode 100644
index 0000000..3227c3d
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/TestFileToken.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import static org.junit.Assert.*;
+
+/**
+ * Creates a temporary test file that a sample can use. This way we don't have to rewrite the samples to fit them into
+ * these tests.
+ */
+public class TestFileToken implements AutoCloseable {
+    private final String filename;
+
+    public TestFileToken(String filename) {
+        this.filename = filename;
+        try {
+            try (InputStream i = getClass().getResourceAsStream("TestFile.java"); OutputStream o = new FileOutputStream(filename)) {
+                assertNotNull(i);
+                IOUtils.copy(i, o);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+    @Override
+    public void close() {
+        boolean deleted = new File(filename).delete();
+        assertTrue(deleted);
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/VisitingClassMethodsTest.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/VisitingClassMethodsTest.java
new file mode 100644
index 0000000..5999124
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/VisitingClassMethodsTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples;
+
+import org.junit.Test;
+
+public class VisitingClassMethodsTest {
+    @Test
+    public void testCode() throws Exception {
+        try (TestFileToken f = new TestFileToken("test.java")) {
+            MethodPrinter.main(new String[]{});
+        }
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/D.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/D.java
new file mode 100644
index 0000000..dd925bc
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/D.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples.removenode;
+
+public class D {
+
+    public void foo(int e) {
+        int a = 20;
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/ModifierVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/ModifierVisitorTest.java
new file mode 100644
index 0000000..d522c96
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/ModifierVisitorTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples.removenode;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.IntegerLiteralExpr;
+import com.github.javaparser.ast.visitor.ModifierVisitor;
+
+import java.io.FileInputStream;
+
+public class ModifierVisitorTest {
+
+    public static void main(String... args) throws Exception {
+        // parse the file
+        CompilationUnit cu = JavaParser.parse(new FileInputStream("forGitHubTest.java"));
+
+        // The visitor should remove all a=20 variable declarations.
+        cu.accept(new MyVisitor(), null);
+
+        System.out.println(cu.toString());
+    }
+}
+
+class MyVisitor extends ModifierVisitor<Void> {
+    @Override
+    public Node visit(VariableDeclarator declarator, Void args) {
+        if (declarator.getNameAsString().equals("a")
+                // the initializer is optional, first check if there is one
+                && declarator.getInitializer().isPresent()) {
+            Expression expression = declarator.getInitializer().get();
+            // We're looking for a literal integer.
+            if (expression instanceof IntegerLiteralExpr) {
+                // We found one. Is it literal integer 20?
+                if (((IntegerLiteralExpr) expression).getValue().equals("20")) {
+                    // Returning null means "remove this VariableDeclarator"
+                    return null;
+                }
+            }
+        }
+        return declarator;
+    }
+}
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/RemoveDeleteNodeFromAst.java b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/RemoveDeleteNodeFromAst.java
new file mode 100644
index 0000000..72756e9
--- /dev/null
+++ b/javaparser-testing/src/test/java/com/github/javaparser/wiki_samples/removenode/RemoveDeleteNodeFromAst.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.wiki_samples.removenode;
+
+import com.github.javaparser.wiki_samples.TestFileToken;
+import org.junit.Test;
+
+public class RemoveDeleteNodeFromAst {
+    @Test
+    public void testCode1() throws Exception {
+        try (TestFileToken f = new TestFileToken("forGitHubTest.java")) {
+            ModifierVisitorTest.main();
+        }
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/TestFileIso88591.java b/javaparser-testing/src/test/resources/com/github/javaparser/TestFileIso88591.java
new file mode 100644
index 0000000..1777f94
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/TestFileIso88591.java
@@ -0,0 +1,7 @@
+package com.github.javaparser;
+
+public class TestFile {
+
+    public String strïng = "Strange attribute name [check the i]";
+
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comment_attribution_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comment_attribution_scenarios.story
new file mode 100644
index 0000000..e509fc9
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comment_attribution_scenarios.story
@@ -0,0 +1,498 @@
+Scenario: A Class With Line Comments is processed by the Java Parser
+
+Given the class:
+package japa.parser.comments;
+
+public class ClassWithLineComments {
+
+    public void aMethod(){
+        // first comment
+        int a=0; // second comment
+        // third comment
+        // fourth comment
+    }
+}
+When the class is parsed by the Java parser
+Then the compilation unit is not commented
+Then the compilation unit has 0 orphan comments
+Then class 1 has 4 total contained comments
+Then method 1 in class 1 has 4 total contained comments
+Then method 1 in class 1 has 0 orphan comments
+Then block statement in method 1 in class 1 has 4 total contained comments
+Then block statement in method 1 in class 1 has 3 orphan comments
+
+
+
+Scenario: A Class With Line Comments is processed by the Java Parser
+
+Given the class:
+package japa.parser.comments;
+
+/**Javadoc associated with the class*/
+public class ClassWithOrphanComments {
+    //a first comment floating in the class
+
+    //comment associated to the method
+    void foo(){
+        /*comment floating inside the method*/
+    }
+
+    //a second comment floating in the class
+}
+
+//Orphan comment inside the CompilationUnit
+When the class is parsed by the Java parser
+Then the compilation unit is not commented
+Then the compilation unit has 6 contained comments
+Then the compilation unit orphan comment 1 is "Orphan comment inside the CompilationUnit"
+Then class 1 orphan comment 1 is "a first comment floating in the class"
+Then class 1 orphan comment 2 is "a second comment floating in the class"
+Then class 1 is commented "Javadoc associated with the class"
+Then class 1 has 4 total contained comments
+Then method 1 in class 1 has 0 orphan comments
+Then method 1 in class 1 is commented "comment associated to the method"
+Then comment 1 in method 1 in class 1 is "comment floating inside the method"
+Then block statement in method 1 in class 1 orphan comment 1 is "comment floating inside the method"
+
+
+Scenario: A Class With Orphan Comment in Class Declaration is parsed by the Java Parser
+
+Given the class:
+class /*Comment1*/ A {
+    //comment2
+    // comment3
+    int a;
+    /**comment4
+    *
+    * */
+    //comment5
+}
+When the class is parsed by the Java parser
+Then class 1 is not commented
+Then class 1 orphan comment 1 is "Comment2"
+
+
+Scenario: A Class With Line Comments in Multiple Methods is parsed by the Java Parser
+
+Given the class:
+package japa.parser.comments;
+
+public class ClassWithLineCommentsInMultipleMethods {
+
+    public void aMethod() {
+        // first comment
+        int a = 0; //second comment
+        // third comment
+        // fourth comment
+    }
+
+    public void anotherMethod() {
+        // a unique comment
+        // first comment
+        int a = 0; //second comment
+        // third comment
+        // fourth comment
+    }
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 9 contained comments
+Then the compilation unit has 0 orphan comments
+Then class 1 is not commented
+Then class 1 has 9 total contained comments
+Then method 1 in class 1 has 4 total contained comments
+Then method 1 in class 1 has 0 orphan comments
+Then block statement in method 1 in class 1 has 4 total contained comments
+Then block statement in method 1 in class 1 has 3 orphan comments
+Then method 2 in class 1 has 5 total contained comments
+Then method 2 in class 1 has 0 orphan comments
+Then block statement in method 2 in class 1 has 5 total contained comments
+Then block statement in method 2 in class 1 has 4 orphan comments
+
+
+
+Scenario: A Class With Line Comments in Multiple Methods is parsed by the Java Parser
+
+Given the class:
+package japa.parser.comments;
+
+public class ClassWithLineCommentInsideBlockComment {
+
+    /* comment to a method */
+    void foo(){}
+
+    /*// Line Comment put immediately after block comment
+
+    //// Comment debauchery
+
+    another orphan.
+    It spans over more lines */
+}
+When the class is parsed by the Java parser
+Then method 1 in class 1 is commented " comment to a method "
+Then class 1 orphan comment 1 is "// Line Comment put immediately after block comment
+
+                                  //// Comment debauchery
+
+                                  another orphan.
+                                  It spans over more lines "
+
+
+
+Scenario: A Class With Line Comments on Fields is parsed by the Java Parser
+
+Given the class:
+package japa.parser.comments;
+
+public class Issue43 {
+    //Case 1
+    private String field1 = null; //field1
+
+    //Case 2
+    private String field2
+            = null; //field2
+
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 4 contained comments
+Then class 1 has 4 total contained comments
+Then class 1 has 1 orphan comment
+Then class 1 orphan comment 1 is "Case 1"
+Then field 1 in class 1 contains 0 comments
+!--Then field 2 in class 1 contains 0 comments
+Then field 1 in class 1 is commented "field1"
+Then field 2 in class 1 is commented "Case 2"
+Then variable 1 value of field 2 in class 1 is commented "field2"
+
+
+Scenario: Another Class With Line Comments on Fields is parsed by the Java Parser
+
+Given the class:
+package japa.parser.comments;
+
+public class Issue43variant {
+    private String field1 = null; //field1
+
+    private String field2
+            = null; //field2
+
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 2 contained comments
+Then class 1 has 2 total contained comments
+Then field 1 in class 1 contains 0 comments
+!--Then field 2 in class 1 contains 0 comments
+Then field 1 in class 1 is commented "field1"
+Then variable 1 value of field 2 in class 1 is commented "field2"
+
+
+Scenario: A Class With Mixed Comments on Fields is parsed by the Java Parser
+
+Given the class:
+package japa.parser.javacc;
+public class Teste {
+    //line comment1
+    int a = 0; //line comment2
+    int b = 0; //line comment3
+    int c = 0; /* multi-line
+                * comment
+                */
+    int d = 0; /** multi-line
+                * javadoc */
+    int e = 0;
+}
+//final comment
+When the class is parsed by the Java parser
+Then the compilation unit has 6 contained comments
+Then class 1 has 5 total contained comments
+Then class 1 orphan comment 1 is "line comment1"
+Then field 1 in class 1 is commented "line comment2"
+Then field 2 in class 1 is commented "line comment3"
+Then field 3 in class 1 is not commented
+
+
+
+Scenario: Comment with a preceding line space is an orphan
+
+Given the class:
+//comment
+
+class A {}
+When the class is parsed by the Java parser
+Then the compilation unit orphan comment 1 is "comment"
+
+
+Scenario: Comment without a preceding line space is associated to class
+
+Given the class:
+//comment
+class A {}
+When the class is parsed by the Java parser
+Then class 1 is commented "comment"
+
+
+Scenario: Comments after Javadoc are attributed to the method if flag is active
+
+Given the class:
+class Issue40{
+    @GET
+    @Path("original")
+    /**
+    * Return the original user.
+    */
+    public User getOriginalUser(String userName) {
+        return userService.getOriginalUser(userName);
+    }
+}
+When the do not consider annotations as node start for code attribution is true on the Java parser
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit is not an orphan
+Then method 1 in class 1 is commented "* Return the original user."
+
+
+
+Scenario: Comments after Javadoc are attributed to the method if flag is not active
+
+Given the class:
+class Issue40{
+    @GET
+    @Path("original")
+    /**
+    * Return the original user.
+    */
+    public User getOriginalUser(String userName) {
+        return userService.getOriginalUser(userName);
+    }
+}
+When the do not consider annotations as node start for code attribution is false on the Java parser
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit is not an orphan
+Then type of method 1 in class 1 is commented "* Return the original user."
+
+
+Scenario: A Class With Line Comments is processed by the Java Parser
+
+Given the class:
+/*CompilationUnitComment*/
+package japa.parser.comments;
+
+public class ClassWithMixedStyleComments {
+    // line comment
+    int a = 0;
+    // another line comment
+    int b = 0;
+    // line comment
+    int c = 0;
+    /* multi-line
+       comment
+    */
+    int d = 0;
+    /**
+     * multi-line
+     */
+    int e = 0;
+    // final comment
+}
+When the class is parsed by the Java parser
+Then the compilation is commented "CompilationUnitComment"
+Then class 1 is not commented
+Then class 1 has 6 total contained comments
+Then class 1 orphan comment 1 is " final comment"
+Then field 1 in class 1 is commented " line comment"
+Then field 1 in class 1 contains 0 comments
+Then field 2 in class 1 is commented " another line comment"
+Then field 2 in class 1 contains 0 comments
+Then field 3 in class 1 is commented " line comment"
+Then field 3 in class 1 contains 0 comments
+Then field 4 in class 1 is commented " multi-line comment"
+Then field 4 in class 1 contains 0 comments
+Then field 5 in class 1 is commented " * multi-line"
+Then field 5 in class 1 contains 0 comments
+
+
+Scenario: A class with only an orphan comment is processed by the Java Parser
+
+Given the class:
+class A {
+    // orphan comment"
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit is an orphan
+Then comment 1 in compilation unit parent is ClassOrInterfaceDeclaration
+
+
+
+Scenario: A class with only a class comment is processed by the Java Parser
+
+Given the class:
+/* Comment of the class */
+class A {
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit is not an orphan
+Then comment 1 in compilation unit commented node is ClassOrInterfaceDeclaration
+
+
+
+Scenario: A Class With two comments at class level is processed by the Java Parser
+
+Given the class:
+/* Orphan comment */
+/* Comment of the class */
+class A {
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 2 contained comments
+Then comment 1 in compilation unit is an orphan
+Then the compilation unit orphan comment 1 is "Orphan comment"
+Then comment 2 in compilation unit is not an orphan
+Then comment 2 in compilation unit commented node is ClassOrInterfaceDeclaration
+
+
+Scenario: A Class has a comment associated to a field when processed by the Java Parser
+
+Given the class:
+class A {
+    int a = 0; // comment associated to the field
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit is not an orphan
+Then comment 1 in compilation unit commented node is FieldDeclaration
+
+
+Scenario: A Class has a comment associated to a the literal when processed by the Java Parser
+
+Given the class:
+class A {
+    int a
+        = 0; // comment associated to the field
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit is not an orphan
+Then comment 1 in compilation unit commented node is IntegerLiteralExpr
+
+
+
+Scenario: A Class with two line comment within a method when processed by the Java Parser
+
+Given the class:
+class A {
+    void foo() {
+        // a comment
+        int b; // another comment
+    }
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 2 contained comments
+Then comment 1 in compilation unit is an orphan
+Then comment 1 in compilation unit is "a comment"
+Then comment 2 in compilation unit is not an orphan
+Then comment 2 in compilation unit is "another comment"
+Then comment 2 in compilation unit commented node is ExpressionStmt
+
+
+Scenario: A Class with an inline comment inside a block comment is parsed by the Java Parser
+
+Given the class:
+class A {
+    /* A block comment that
+    // Contains a line comment
+    */
+    public static void main(String args[]) {
+    }
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit is "A block comment that // Contains a line comment"
+
+
+Scenario: A Class with an inline comment inbetween annotation a method declaration is parsed Java Parser
+
+Given the class:
+class A {
+    @Override
+    // Returns number of vowels in a name
+    public int countVowels(String name) {
+    }
+}
+When the class is parsed by the Java parser
+Then the compilation unit has 1 contained comments
+Then comment 1 in compilation unit commented node is PrimitiveType
+
+Scenario: We print correctly two consecutive line-comments in a class
+ 
+Given the class:
+class A {
+  // foo
+  // bar
+  void aMethod(){}
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class A {
+
+    // foo
+    // bar
+    void aMethod() {
+    }
+}
+
+Scenario: We print correctly two consecutive line-comments in a method
+
+Given the class:
+class A {
+  void aMethod(){
+     // foo
+     // bar
+     int a;
+  }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class A {
+
+    void aMethod() {
+        // foo
+        // bar
+        int a;
+    }
+}
+
+Scenario: We print correctly orphan comments in a for loop
+Given the class:
+class A {
+    public static List calcularResultadoFinal(List avaliacoes) throws SQLException, ClassNotFoundException{
+        for(Avaliacao avaliacao: avaliacoes){
+            // if(avaliacao.obterAprovacao()){
+            // avaliacao.setResultadoFinal("Aprovado");
+            // }else{
+            // avaliacao.setResultadoFinal("Reprovado");
+            // }
+            avaliacao.setEmAberto(false);
+            avaliacao.editar();
+        }
+        return avaliacoes;
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class A {
+
+    public static List calcularResultadoFinal(List avaliacoes) throws SQLException, ClassNotFoundException {
+        for (Avaliacao avaliacao : avaliacoes) {
+            // if(avaliacao.obterAprovacao()){
+            // avaliacao.setResultadoFinal("Aprovado");
+            // }else{
+            // avaliacao.setResultadoFinal("Reprovado");
+            // }
+            avaliacao.setEmAberto(false);
+            avaliacao.editar();
+        }
+        return avaliacoes;
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comment_parsing_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comment_parsing_scenarios.story
new file mode 100644
index 0000000..e41d6e4
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comment_parsing_scenarios.story
@@ -0,0 +1,281 @@
+Scenario: A Class With Line Comments is processed by the Comments Parser
+
+Given the class:
+package japa.parser.comments;
+
+public class ClassWithLineComments {
+
+    public void aMethod(){
+        // first comment
+        int a=0; // second comment
+        // third comment
+        // fourth comment
+    }
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 4
+Then line comment 1 is " first comment"
+Then line comment 2 is " second comment"
+Then line comment 3 is " third comment"
+Then line comment 4 is " fourth comment"
+Then the line comments have the following positions:
+|beginLine|beginColumn|endLine|endColumn|
+|6|9|6|25|
+|7|18|7|35|
+|8|9|8|25|
+|9|9|9|26|
+
+Scenario: A Class With Block Comments is processed by the Comments Parser
+
+Given the class:
+package japa.parser.comments;
+
+/* comment which is not attributed to the class, it floats around as an orphan */
+/* comment to a class */
+public class ClassWithBlockComments {
+
+    /* comment to a method */
+    void foo(){};
+
+    /* comment put randomly in class:
+
+    another orphan.
+    It spans over more lines */
+
+}
+
+/* a comment lost inside a compilation unit. It is orphan, I am sure you got this one */
+When the class is parsed by the comment parser
+Then the total number of comments is 5
+Then block comment 1 is " comment which is not attributed to the class, it floats around as an orphan "
+Then block comment 2 is " comment to a class "
+Then block comment 3 is " comment to a method "
+Then block comment 4 is " comment put randomly in class:    another orphan.    It spans over more lines "
+Then block comment 5 is " a comment lost inside a compilation unit. It is orphan, I am sure you got this one  "
+Then the block comments have the following positions:
+|beginLine|beginColumn|endLine|endColumn|
+|3|1|3|81|
+|4|1|4|24|
+|7|5|7|29|
+|10|5|13|31|
+|17|1|17|88|
+
+
+Scenario: A Class With Javadoc Comments is processed by the Comments Parser
+
+Given the class:
+package japa.parser.comments;
+
+/** a proper javadoc comment */
+public class ClassWithJavadocComments {
+
+    void foo(){};
+
+
+}
+/** a floating javadoc comment */
+When the class is parsed by the comment parser
+Then the total number of comments is 2
+Then Javadoc comment 1 is " a proper javadoc comment "
+Then Javadoc comment 2 is " a floating javadoc comment "
+Then the Javadoc comments have the following positions:
+|beginLine|beginColumn|endLine|endColumn|
+|3|1|3|31|
+|10|1|10|33|
+
+
+
+Scenario: A Class With Orphan Comments is processed by the Comments Parser
+
+Given the class:
+package japa.parser.comments;
+
+/**Javadoc associated with the class*/
+public class ClassWithOrphanComments {
+    //a first comment floating in the class
+
+    //comment associated to the method
+    void foo(){
+        /*comment floating inside the method*/
+    }
+
+    //a second comment floating in the class
+}
+
+//Orphan comment inside the CompilationUnit
+When the class is parsed by the comment parser
+Then the total number of comments is 6
+Then line comment 1 is "a first comment floating in the class"
+Then line comment 2 is "comment associated to the method"
+Then line comment 3 is "a second comment floating in the class"
+Then block comment 1 is "comment floating inside the method"
+Then Javadoc comment 1 is "Javadoc associated with the class"
+
+
+Scenario: A Class With Orphan Comments is processed by the Comments Parser
+
+Given the class:
+/*CompilationUnitComment*/
+package japa.parser.comments;
+
+public class ClassWithMixedStyleComments {
+    // line comment
+    int a = 0;
+    // another line comment
+    int b = 0;
+    // line comment
+    int c = 0;
+    /* multi-line
+       comment
+    */
+    int d = 0;
+    /**
+     * multi-line
+     */
+    int e = 0;
+    // final comment
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 7
+Then the line comments have the following positions:
+|beginLine|beginColumn|endLine|endColumn|
+|5|5|5|20|
+|7|5|7|28|
+|9|5|9|20|
+|19|5|19|21|
+Then the block comments have the following positions:
+|beginLine|beginColumn|endLine|endColumn|
+|1|1|1|26|
+|11|5|13|6|
+Then the Javadoc comments have the following positions:
+|beginLine|beginColumn|endLine|endColumn|
+|15|5|17|7|
+
+Scenario: A method containing two consecutive line comments is parsed correctly
+
+Given the class:
+class A {
+  void aMethod(){
+     // foo
+     // bar
+     int a;
+  }
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 2
+Then line comment 1 is " foo"
+Then line comment 2 is " bar"
+
+Scenario: Comments from a file with an non-UTF-8 encoding are parsed correctly
+
+When read sample "ClassInLatin1" using encoding "ISO-8859-1"
+Then the total number of comments is 3
+Then line comment 2 is " A l'émej in piasì che sent dësgust."
+
+Scenario: Should not recognize /*/ as a comment
+
+Given the class:
+/*/
+class Foo {}
+When the class is parsed by the comment parser
+Then the total number of comments is 0
+
+Given the class:
+/*/
+class Foo {}
+Then the Java parser cannot parse it because of an error
+
+Scenario: Should recognize /*/ inside a block comment
+
+Given the class:
+/* Foo /*/
+When the class is parsed by the comment parser
+Then the total number of comments is 1
+Then block comment 1 is " Foo /"
+
+Scenario: A Class With Character Literal is processed by the Comments Parser
+Given the class:
+class A {
+    /** comment1 */
+    private char c = '"';
+    /** comment2 */
+    private String d;
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 2
+Then Javadoc comment 1 is "comment1"
+Then Javadoc comment 2 is "comment2"
+
+Scenario: Double slash in string does not mess up comments parsing
+Given the class:
+public class b {
+
+    public void m1() {
+        String s = "\\";
+    }
+
+    /**
+     * Comment
+    */
+    public void m2() {
+        return;
+    }
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 1
+
+Scenario: Triple slash in string does not mess up comments parsing
+Given the class:
+public class b {
+
+    public void m1() {
+        String s = "\\\" // still in string";
+    }
+
+    /**
+     * Comment
+    */
+    public void m2() {
+        return;
+    }
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 1
+
+Scenario: Four slashes in string does not mess up comments parsing
+Given the class:
+public class b {
+
+    public void m1() {
+        String s = "\\\\" // out of the string";
+        ;
+    }
+
+    /**
+     * Comment
+    */
+    public void m2() {
+        return;
+    }
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 2
+
+Scenario: Five slashes in string does not mess up comments parsing
+Given the class:
+public class b {
+
+    public void m1() {
+        String s = "\\\\\" // still in string";
+        ;
+    }
+
+    /**
+     * Comment
+    */
+    public void m2() {
+        return;
+    }
+}
+When the class is parsed by the comment parser
+Then the total number of comments is 1
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comparing_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comparing_scenarios.story
new file mode 100644
index 0000000..fea7785
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/comparing_scenarios.story
@@ -0,0 +1,19 @@
+Scenario: Compare CUs containing lambdas should not crash awfully
+
+Given the first class:
+public class ArrayListGenericDemo {
+
+    public static void main(String[] args) {
+        ArrayList<String> data = new ArrayList();
+        data.forEach( s -> System.out.println(s));
+    }
+}
+Given the second class:
+public class ArrayListGenericDemo {
+
+    public static void main(String[] args) {
+        ArrayList<String> data = new ArrayList();
+        data.forEach( s -> System.out.println(s));
+    }
+}
+Then they are equals
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/manipulation_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/manipulation_scenarios.story
new file mode 100644
index 0000000..ea28279
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/manipulation_scenarios.story
@@ -0,0 +1,137 @@
+Scenario: A Node can only ever be equal to a class that extends Node
+
+Given a CompilationUnit
+Then is not equal to null
+Then is not equal to "Some String Value"
+
+
+Scenario: A BlockStmt can be created by a provided String
+
+Given a BlockStmt
+When is the String "{return x+y;}" is parsed by the JavaParser using parseBlock
+Then Statement 1 in BlockStmt toString is "return x + y;"
+
+
+Scenario: A Statement can be created by a provided String
+
+Given a Statement
+When is the String "x = x+y;" is parsed by the JavaParser using parseStatement
+Then Statement toString is "x = x + y;"
+
+
+Scenario: Adding declarations to a TryStmt it is set as the parent of all provided declarations
+
+Given a TryStmt
+Given a List of VariableDeclarations
+When the List of VariableDeclarations are set as the resources on TryStmt
+Then all the VariableDeclarations parent is the TryStmt
+
+
+Scenario: Creating a complete CompilationUnit
+
+Given a CompilationUnit
+When the package declaration is set to "japa.parser.ast.manipulation"
+When a public class called "CreateClass" is added to the CompilationUnit
+When a public static method called "main" returning void is added to class 1 in the compilation unit
+When String varargs called "args" are added to method 1 in class 1
+When a BlockStmt is added to method 1 in class 1
+When System.out.println("Hello World!"); is added to the body of method 1 in class 1
+Then the expected source should be:
+package japa.parser.ast.manipulation;
+
+public class CreateClass {
+
+    public static void main(String... args) {
+        System.out.println("Hello World!");
+    }
+}
+
+
+Scenario: Change the name of a method to be uppercase
+
+Given a CompilationUnit
+When the following source is parsed:
+package japa.parser.ast.manipulation;
+
+public class UpdateMethod {
+
+    public void changeToUpperCase(){}
+
+    public void anotherMethodToChange(){}
+}
+When method 1 in class 1 has it's name converted to uppercase
+Then method 1 in class 1 has the name "CHANGETOUPPERCASE"
+
+
+Scenario: Change the name of all methods to be uppercase using a visitor
+
+Given a CompilationUnit
+When the following source is parsed:
+package japa.parser.ast.manipulation;
+
+public class UpdateMethod {
+
+    public void changeToUpperCase(){}
+
+    public void anotherMethodToChange(){}
+}
+Given a ChangeNameToUpperCaseVisitor
+When the ChangeNameToUpperCaseVisitor visits to compilation unit
+Then method 1 in class 1 has the name "CHANGETOUPPERCASE"
+Then method 2 in class 1 has the name "ANOTHERMETHODTOCHANGE"
+
+
+Scenario: Add int arguments to a method
+
+Given a CompilationUnit
+When the following source is parsed:
+package japa.parser.ast.manipulation;
+
+public class UpdateMethod {
+
+    public void changeToUpperCase(String parameter){}
+
+    public void anotherMethodToChange(){}
+}
+When method 2 in class 1 has an int parameter called "value" added
+Then method 1 in class 1 has 1 parameters
+Then method 2 in class 1 has 1 parameter
+Then method 2 in class 1 parameter 1 is type int called "value"
+
+
+Scenario: Add int arguments to all methods using a visitor
+
+Given a CompilationUnit
+When the following source is parsed:
+package japa.parser.ast.manipulation;
+
+public class UpdateMethod {
+
+    public void changeToUpperCase(String parameter){}
+
+    public void anotherMethodToChange(){}
+}
+Given a AddNewIntParameterCalledValueVisitor
+When the AddNewIntParameterCalledValueVisitor visits to compilation unit
+Then method 1 in class 1 has 2 parameters
+Then method 2 in class 1 has 1 parameter
+Then method 1 in class 1 parameter 2 is type int called "value"
+Then method 2 in class 1 parameter 1 is type int called "value"
+
+
+Scenario: Clone a compilation unit
+
+Given a CompilationUnit
+When the following source is parsed:
+package japa.parser.ast.manipulation;
+
+public class UpdateMethod {
+
+    public void changeToUpperCase(String parameter){}
+
+    public void anotherMethodToChange(){}
+}
+When the compilation unit is cloned
+Then method 1 in class 1 has the name "changeToUpperCase"
+Then method 1 in class 1 has 1 parameters
+Then method 2 in class 1 has 0 parameter
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/parsing_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/parsing_scenarios.story
new file mode 100644
index 0000000..9f6ee24
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/parsing_scenarios.story
@@ -0,0 +1,500 @@
+Scenario: Test declaration as String for constructor on parsed class
+
+Given a CompilationUnit
+When the following source is parsed:
+class ClassWithAConstructor {
+    protected ClassWithAConstructor(int a, String b) throws This, AndThat, AndWhatElse {
+    }
+}
+Then constructor 1 in class 1 declaration as a String is "protected ClassWithAConstructor(int a, String b) throws This, AndThat, AndWhatElse"
+Then all nodes refer to their parent
+
+
+Scenario: Test declaration as String exclusing modifiers and throws for constructor on parsed class
+
+Given a CompilationUnit
+When the following source is parsed:
+class ClassWithAConstructor {
+    protected ClassWithAConstructor(int a, String b) throws This, AndThat, AndWhatElse {
+    }
+}
+Then constructor 1 in class 1 declaration short form as a String is "ClassWithAConstructor(int a, String b)"
+Then all nodes refer to their parent
+
+
+Scenario: Test declaration as String exclusing modifiers and throws for method on parsed class
+
+Given a CompilationUnit
+When the following source is parsed:
+class ClassWithAMethod {
+    /*comment1*/
+    final protected /*comment2*/ native List<String> /*comment2*/ aMethod(int a, String b) throws /*comment3*/ This, AndThat, AndWhatElse {
+
+    }
+}
+Then method 1 in class 1 declaration as a String is "protected final native List<String> aMethod(int a, String b) throws This, AndThat, AndWhatElse"
+Then all nodes refer to their parent
+
+
+Scenario: Test declaration as String exclusing modifiers and throws for method on parsed class
+
+Given a CompilationUnit
+When the following source is parsed:
+class ClassWithAMethod {
+    /*comment1*/
+    final protected /*comment2*/ native List<String> /*comment2*/ aMethod(int a, String b) throws /*comment3*/ This, AndThat, AndWhatElse {
+
+    }
+}
+Then method 1 in class 1 declaration as a String short form is "List<String> aMethod(int a, String b)"
+Then all nodes refer to their parent
+
+
+Scenario: The same class source is parsed by two different compilation units and should therefore be equal
+
+Given a CompilationUnit
+Given a second CompilationUnit
+When the following source is parsed:
+package japa.parser.comments;
+public class ClassEquality {
+
+    public void aMethod(){
+        // first comment
+        int a=0; // second comment
+    }
+}
+When the following sources is parsed by the second CompilationUnit:
+package japa.parser.comments;
+public class ClassEquality {
+
+    public void aMethod(){
+        // first comment
+        int a=0; // second comment
+    }
+}
+Then the CompilationUnit is equal to the second CompilationUnit
+Then the CompilationUnit has the same hashcode to the second CompilationUnit
+Then all nodes refer to their parent
+Then all nodes of the second compilation unit refer to their parent
+
+
+Scenario: Two different class sources are parsed by two different compilation units and should not be equal
+
+Given a CompilationUnit
+Given a second CompilationUnit
+When the following source is parsed:
+package japa.parser.comments;
+public class ClassEquality {
+
+    public void aMethod(){
+        // first comment
+        int a=0; // second comment
+    }
+}
+When the following sources is parsed by the second CompilationUnit:
+package japa.parser.comments;
+public class DifferentClass {
+
+    public void aMethod(){
+        // first comment
+        int a=0; // second comment
+    }
+}
+Then the CompilationUnit is not equal to the second CompilationUnit
+Then the CompilationUnit has a different hashcode to the second CompilationUnit
+Then all nodes refer to their parent
+Then all nodes of the second compilation unit refer to their parent
+
+
+Scenario: Classes that only differ by comments should not be equal or have the same hashcode
+
+Given a CompilationUnit
+Given a second CompilationUnit
+When the following source is parsed:
+package japa.parser.comments;
+public class ClassEquality {
+
+    public void aMethod(){
+        // first comment
+        int a=0; // second comment
+    }
+}
+When the following sources is parsed by the second CompilationUnit:
+package japa.parser.comments;
+public class ClassEquality {
+
+    public void aMethod(){
+        // first comment
+        int a=0;
+    }
+}
+Then the CompilationUnit is not equal to the second CompilationUnit
+Then the CompilationUnit has a different hashcode to the second CompilationUnit
+Then all nodes refer to their parent
+Then all nodes of the second compilation unit refer to their parent
+
+
+Scenario: A class with a colon in the annoation value is parsed by the Java Parser
+
+Given a CompilationUnit
+When the following source is parsed:
+package japa.parser.ast;
+import org.junit.Test;
+public class Issue37 {
+    public static @interface SomeAnnotation {
+        String value();
+    }
+    // Parser bug: the type of this field
+    @SomeAnnotation("http://someURL.org/")
+    protected Test test;
+}
+Then field 1 in class 1 contains annotation 1 value is ""http://someURL.org/""
+Then all nodes refer to their parent
+
+
+Scenario: A class with a Lambda is parsed by the Java Parser
+
+Given a CompilationUnit
+When the following source is parsed:
+package bdd.samples;
+import java.util.stream.Stream;
+public class Lambdas {
+
+    public static void main(String[] args) {
+        // Lambda Runnable
+        Runnable r1 = () -> System.out.println("Hello world!");
+        Runnable r2 = () -> {};
+        Runnable r3 = () -> { System.out.println("Hello world two!"); };
+
+        Stream<CharSequence> stream = Stream.generate((Supplier<CharSequence>) () -> "foo");
+    }
+}
+Then lambda in statement 1 in method 1 in class 1 is called r1
+Then lambda in statement 2 in method 1 in class 1 is called r2
+Then lambda in statement 3 in method 1 in class 1 is called r3
+Then lambda in statement 1 in method 1 in class 1 body is "System.out.println("Hello world!");"
+Then lambda in statement 2 in method 1 in class 1 block statement is null
+Then lambda in statement 3 in method 1 in class 1 block statement is "System.out.println("Hello world two!");"
+Then lambda in statement 1 in method 1 in class 1 is parent of contained body
+Then lambda in statement 3 in method 1 in class 1 is parent of contained body
+Then all nodes refer to their parent
+Then lambda in method call in statement 4 in method 1 in class 1 body is ""foo";"
+
+
+Scenario: A class with parameterized Lambdas is parsed by the Java Parser
+
+Given a CompilationUnit
+When the following source is parsed:
+package com.github.javapasrser.bdd.parsing;
+import java.util.function.Function;
+public class ParameterizedLambdas {
+    public static void main(String[] args) {
+        Function<Integer,String> f1 = (Integer i) -> String.valueOf(i);
+        Function<Integer,String> f2 = (i) -> String.valueOf(i);
+        Function<Integer,String> f3 = i -> String.valueOf(i);
+    }
+}
+Then lambda in statement 1 in method 1 in class 1 is parent of contained parameter
+Then lambda in statement 2 in method 1 in class 1 is parent of contained parameter
+Then lambda in statement 3 in method 1 in class 1 is parent of contained parameter
+Then lambda in statement 1 in method 1 in class 1 is parent of contained body
+Then lambda in statement 2 in method 1 in class 1 is parent of contained body
+Then lambda in statement 3 in method 1 in class 1 is parent of contained body
+Then lambda in statement 1 in method 1 in class 1 has parameters with non-null type
+Then lambda in statement 2 in method 1 in class 1 has parameters with non-null type
+Then lambda in statement 3 in method 1 in class 1 has parameters with non-null type
+
+
+Scenario: A class with multi-parameters Lambdas is parsed by the Java Parser
+
+Given a CompilationUnit
+When the following source is parsed:
+package com.github.javapasrser.bdd.parsing;
+import java.util.function.Function;
+public class MultiParameterizedLambdas {
+    public static void main(String[] args) {
+        BiFunction<Integer, Integer, String> f = (a, b) -> String.valueOf(a) + String.valueOf(b);
+    }
+}
+Then lambda in statement 1 in method 1 in class 1 has parameters with non-null type
+
+
+Scenario: A class with a method reference is parsed by the Java Parser
+
+Given a CompilationUnit
+When the following source is parsed:
+public class Person {
+
+    String name;
+    LocalDate birthday;
+
+    public void sortByAge(Person[] people){
+        Arrays.sort(people, Person::compareByAge);
+    }
+
+    public static int compareByAge(Person a, Person b) {
+        return a.birthday.compareTo(b.birthday);
+    }
+}
+Then method reference in statement 1 in method 1 in class 1 scope is Person
+Then method reference in statement 1 in method 1 in class 1 identifier is compareByAge
+Then all nodes refer to their parent
+
+
+Scenario: An interface with a default method is parsed by the Java Parser
+
+Given a CompilationUnit
+When the following source is parsed:
+interface MyInterface {
+    default String doSomething(){
+        return "implementation in an interface!";
+    }
+
+    String doSomethingElse();
+}
+Then method 1 class 1 is a default method
+Then method 2 class 1 is not a default method
+Then all nodes refer to their parent
+
+Scenario: A lambda expression inside a conditional expression is parsed by the Java Parser
+
+Given a CompilationUnit
+When the following source is parsed:
+public class A{
+	static <T> Predicate<T> isEqual(Object targetRef) {
+	    return (null == targetRef)? Objects::isNull : object -> targetRef.equals(object);
+	}
+}
+Then ThenExpr in the conditional expression of the statement 1 in method 1 in class 1 is LambdaExpr
+
+Scenario: Parsing array creation expressions the positions are correct
+
+Given a CompilationUnit
+When the following source is parsed (trimming space):
+public class A{
+    int[][] a = new int[][]{};
+}
+When I take the ArrayCreationExpr
+Then the begin line is 2
+Then the begin column is 17
+Then the end line is 2
+Then the end column is 29
+
+Scenario: simple cast on lambda expression can be parsed
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    static final Comparator<ChronoLocalDate> DATE_ORDER =
+        (Comparator<ChronoLocalDate>) (date1, date2) -> {
+            return Long.compare(date1.toEpochDay(), date2.toEpochDay());
+        };
+}
+Then all nodes refer to their parent
+
+
+Scenario: a combined cast on lambda expression can be parsed
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    static final Comparator<ChronoLocalDate> DATE_ORDER =
+        (Comparator<ChronoLocalDate> & Serializable) (date1, date2) -> {
+            return Long.compare(date1.toEpochDay(), date2.toEpochDay());
+        };
+}
+Then all nodes refer to their parent
+
+
+Scenario: a combined cast on a literal can be parsed
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    static int a = (Comparator<ChronoLocalDate> & Serializable) 1;
+}
+Then all nodes refer to their parent
+
+
+Scenario: Parsing excess semicolons on CompilationUnit level should work
+Given a CompilationUnit
+When the following source is parsed:
+;
+package a;
+;
+import foo.a;
+;
+class A { }
+;
+Then no errors are reported
+
+Scenario: Parsing excess semicolons in an AnnotationTypeDeclaration should work
+Given a CompilationUnit
+When the following source is parsed:
+@interface A {
+    ;
+    ;
+}
+Then no errors are reported
+
+Scenario: Classes that are thrown from a method can be annotated
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    void a() throws @Abc X {
+    }
+}
+Then no errors are reported
+
+Scenario: Classes that are thrown from a constructor can be annotated
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    A() throws @Abc X {
+    }
+}
+Then no errors are reported
+
+
+Scenario: Parsing trailing semicolons inside the imports area should work
+
+Given a CompilationUnit
+When the following source is parsed:
+import foo.a;;
+import foo.b;
+
+class A {
+}
+Then no errors are reported
+
+
+Scenario: Full package name should be parsed
+
+Given a CompilationUnit
+When the following source is parsed:
+package com.github.javaparser.bdd;
+class C {}
+When I take the PackageDeclaration
+Then the package name is com.github.javaparser.bdd
+
+
+Scenario: Strings with unescaped newlines are illegal (issue 211)
+Given the class:
+class A {
+    public void helloWorld(String greeting, String name) {
+        return "hello
+        world";
+    }
+}
+Then the Java parser cannot parse it because of an error
+
+Scenario: Chars with unescaped newlines are illegal (issue 211)
+Given the class:
+class A {
+    public void helloWorld(String greeting, String name) {
+        return '
+';
+    }
+}
+Then the Java parser cannot parse it because of an error
+
+Scenario: Diamond Operator information is exposed
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    List<String> args = new ArrayList<>();
+}
+When I take the ObjectCreationExpr
+Then the type's diamond operator flag should be true
+
+Scenario: Diamond Operator can be parsed also with space and comments
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    List<String> args = new ArrayList<  /*hello*/  >();
+}
+When I take the ObjectCreationExpr
+Then the type's diamond operator flag should be true
+
+Scenario: Type Arguments are not specified
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    List args = new ArrayList();
+}
+When I take the ObjectCreationExpr
+Then the type's diamond operator flag should be false
+
+Scenario: Type Arguments are specified
+
+Given a CompilationUnit
+When the following source is parsed:
+class A {
+    Either<Ok, Error> either = new Either<Ok, Error>();
+}
+When I take the ObjectCreationExpr
+Then the type's diamond operator flag should be false
+
+Scenario: A method reference with type arguments is parsed correctly
+Given a CompilationUnit
+When the following source is parsed:
+class X { 
+	void x() { 
+		a.orElseGet( Stream::<IVariable<?>>empty ); 
+	} 
+}
+Then no errors are reported
+
+Scenario: The target of this assignExpr is not null
+Given a CompilationUnit
+When the following source is parsed:
+public class Example {
+  private String mString;
+  public Example(String arg) {
+    mString = arg;
+  }
+}
+Then the assignExpr produced doesn't have a null target
+
+Scenario: Two comments in one line, and a unicode space
+Given a CompilationUnit
+When the following source is parsed:
+public class Example {
+  Object mAvailablePrimaryConnection;
+  public Example(String arg) {
+     ​mAvailablePrimaryConnection = openConnectionLocked(mConfiguration,
+        true /*primaryConnection*/); // comment
+  }
+}
+Then no errors are reported
+
+Scenario: alternative [] placings
+Given a CompilationUnit
+When the following source is parsed:
+class I{int[]bar(int[]x[])[]{return new int[][]{};}}
+Then no errors are reported
+
+Scenario: try requires resources, a finally or a catch (issue 442)
+Given the class:
+class A {
+    public void helloWorld() {
+        try {
+        }
+    }
+}
+Then the Java parser cannot parse it because of an error
+
+
+Scenario: Partially dimensioned arrays are fine
+Given a CompilationUnit
+When the following source is parsed:
+class X {
+    int a = new int @A [10] @A [20] @A [] [];
+    int b = new int @A [] @A []{{1}};
+}
+Then no errors are reported
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/position_range_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/position_range_scenarios.story
new file mode 100644
index 0000000..410e456
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/position_range_scenarios.story
@@ -0,0 +1,55 @@
+Scenario: a position is equal to another position at the same place
+Given the position 10, 10
+When I compare to position 10, 10
+Then the positions are equal
+And it is not before the first position
+And it is not after the first position
+
+Scenario: a position is after another position
+Given the position 10, 10
+When I compare to position 20, 20
+Then it is after the first position
+And the positions are not equal
+And it is not before the first position
+
+Scenario: a position is directly after another position
+Given the position 10, 10
+When I compare to position 10, 11
+Then it is after the first position
+And the positions are not equal
+And it is not before the first position
+
+Scenario: a position is before another position
+Given the position 10, 10
+When I compare to position 5, 5
+Then it is before the first position
+And the positions are not equal
+And it is not after the first position
+
+Scenario: a position is directly before another position
+Given the position 10, 10
+When I compare to position 10, 9
+Then it is before the first position
+And the positions are not equal
+And it is not after the first position
+
+Scenario: a range is equal to another range
+Given the range 10, 10 - 20, 20
+When I compare to range 10, 10 - 20, 20
+Then the ranges are equal
+
+Scenario: a range is before a position
+Given the position 20, 21
+When I compare to range 10, 10 - 20, 20
+Then it is before the position
+
+Scenario: a range is after a position
+Given the position 10, 9
+When I compare to range 10, 10 - 20, 20
+Then it is after the  position
+
+Scenario: a range is contained in another range
+Given the range 10, 10 - 20, 20
+When I compare to range 11, 11 - 19, 19
+Then it is contained in the first range
+
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/pretty_printing_java_concepts.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/pretty_printing_java_concepts.story
new file mode 100644
index 0000000..2b7af19
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/pretty_printing_java_concepts.story
@@ -0,0 +1,399 @@
+Scenario: Check a whole lot of things at once that should be separate tests
+
+Given the class in the file "JavaConcepts.java"
+When the class is parsed by the Java parser
+Then it is printed as:
+package japa.bdd.samples;
+
+import com.github.javaparser.JavaParser;
+import japa.parser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Ignore;
+import java.io.*;
+import java.util.*;
+
+@Ignore
+@Deprecated
+public class JavaConcepts<T extends List<int[]>, X> extends Base implements Serializable {
+
+    static Class clz1 = String.class;
+
+    protected Class clz2 = (String.class);
+
+    Class clz3 = int.class;
+
+    Class clz4 = (int.class);
+
+    int[] arr = new int[10];
+
+    byte bye = 0;
+
+    byte[] byebye = null;
+
+    short sh1, sh2 = 1;
+
+    int intWithUnderscore = 1234_5678;
+
+    long longWithUnderscore = 1234_5678L;
+
+    float floatWithUnderscore = 1_234.5_678f;
+
+    float floatWithUnderscoreAndExponent = 1_234e1_0f;
+
+    double doubleWithUnderscore = 1_234.5_678;
+
+    double doubleWithUnderscoreAndExponent = 1_234e1_0;
+
+    int binaryLiteral = 0b101101;
+
+    List<String>[][] arrLS = (List<String>[][]) new List<?>[10][];
+
+    {
+        int z = 0, y = 0;
+        int a = (z) + y;
+        a = (+z) + y;
+        byte b = (byte) +y;
+    }
+
+    List<String> diamond1 = new LinkedList<>();
+
+    @Deprecated()
+    static class Ugly {
+
+        static int x = 0;
+
+        public static void main(String[] args) {
+            x = +x;
+            x = ~x;
+            --x;
+            boolean b = !false;
+            x &= 2;
+            x |= 2;
+            x ^= 2;
+            x -= 2;
+            x %= 2;
+            x /= 2;
+            x *= 2;
+            x <<= 2;
+            x >>= 2;
+            x >>>= 2;
+            b = b || false;
+            b = b | false;
+            b = b & false;
+            b = b ^ false;
+            b = b != false;
+            b = x > 1;
+            b = x < 1;
+            b = x >= 1;
+            b = x <= 1;
+            x = x << 1;
+            x = x >> 1;
+            x = x >>> 1;
+            x = x - 1;
+            x = x * 1;
+            x = x % 1;
+            x = x / 1;
+        }
+    }
+
+    @Deprecated()
+    int[][][][] arr2 = new int[10][2][1][0];
+
+    volatile float fff = 0x1.fffeP+127f;
+
+    char cc = 'a';
+
+    int[][] arr3 = { { 1, 2 }, { 3, 4 } };
+
+    static int[][] arr4 = {};
+
+    public static JavaConcepts t;
+
+    static {
+        arr4 = new int[][] { { 2 }, { 1 } };
+    }
+
+    {
+        arr3 = new int[][] { { 2 }, { 1 } };
+    }
+
+    public enum Teste {
+
+        asc, def
+    }
+
+    public enum Sexo {
+
+        m, @Deprecated
+        f;
+
+        public enum Sexo_ implements Serializable, Cloneable {
+        }
+
+        private Sexo() {
+        }
+    }
+
+    @Deprecated
+    public enum Enum {
+
+        m(1) {
+
+            @Override
+            void mm() {
+            }
+        }
+        , f(2) {
+
+            void mm() {
+            }
+        }
+        ;
+
+        native void nnn();
+
+        transient int x;
+
+        private Enum(int x) {
+            this.x = x;
+        }
+
+        abstract void mm();
+    }
+
+    strictfp double ddd() {
+        return 0.0;
+    }
+
+    public <T, E> JavaConcepts(int x) {
+        this.arr[0] = x;
+        T val1 = null;
+        E val2 = null;
+        super.<T, E>check2(val1, val2);
+        boolean b = true, y = false;
+        abstract class X {
+
+            int i = 0;
+
+            public <D> X() {
+            }
+
+            public void m() {
+            }
+        }
+        @Deprecated
+        final class Y extends X {
+
+            public Y() {
+                super();
+                JavaConcepts.this.cc = 'c';
+                super.i = 1;
+                Y.super.m();
+            }
+
+            public Y(int y) {
+                super();
+            }
+
+            public Y(long x) {
+                this();
+            }
+        }
+    }
+
+    public <T> JavaConcepts(String str) {
+    }
+
+    private class QWE extends JavaConcepts<List<int[]>, String> {
+
+        @Deprecated
+        final int z = 0;
+
+        int i = (int) -1;
+
+        public QWE(String... x) {
+            <String>super(x[0]);
+        }
+
+        public QWE(int... x) {
+            super(x[0]);
+            i = x[0];
+            assert true;
+            assert 1 == 1 : 2;
+            {
+                int iii = 3;
+                iii += 3;
+            }
+            label: {
+                int iii = 1;
+            }
+            ;
+            ;
+            int min = -2147483648;
+            long sl = 123123123123l;
+            long minl = -9223372036854775808L;
+            switch(i) {
+            }
+            ll: switch(i) {
+                case 1:
+                    System.out.println(1);
+                    break ll;
+                default:
+                    {
+                        System.out.println("default");
+                        break;
+                    }
+                case 2:
+                    if (t instanceof Base) {
+                        System.out.println(1);
+                    }
+                    i++;
+                    ++i;
+            }
+        }
+
+        private synchronized int[] doSomething() {
+            List<? extends Number> x = new ArrayList<Integer>();
+            return new int[] { 1 };
+        }
+    }
+
+    public static void main(String[] args) throws ParseException, IOException {
+        int x = 2;
+        CompilationUnit cu = parse(new File("src/japa/parser/javacc/Parser.java"));
+        System.out.println(cu);
+        JavaConcepts teste = new JavaConcepts(2);
+        JavaConcepts.QWE qwe = teste.new QWE(1);
+        if (1 + 1 == 2) {
+            teste = null;
+            teste = new JavaConcepts(1);
+        } else {
+            x = 3;
+            teste = new JavaConcepts(1);
+            x = x == 0 ? 2 : 4;
+        }
+        if (true)
+            x = 1;
+        else
+            x = 3;
+        if (true)
+            x = 1;
+        else if (false)
+            x = 3;
+        else
+            x = 2;
+        while (true) {
+            xxx: while (x == 3) continue xxx;
+            break;
+        }
+        do {
+            x++;
+        } while (x < 100);
+        do x++; while (x < 100);
+        for (@Deprecated int i : arr4[0]) {
+            x--;
+        }
+        for (@Deprecated final int i = 0, j = 1; i < 10; x++) {
+            break;
+        }
+        int i, j;
+        for (i = 0, j = 1; i < 10 && j < 2; i++, j--) {
+            break;
+        }
+    }
+
+    public static CompilationUnit parse(@Deprecated File file) throws ParseException, IOException {
+        String a = ((String) "qwe");
+        String x = ((String) clz1.getName());
+        int y = ((Integer) (Object) x).intValue();
+        synchronized (file) {
+            file = null;
+            file = new File("");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (final NullPointerException e) {
+            System.out.println("catch");
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream();
+            InputStream in2 = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        }
+        try {
+            System.out.println("whatever");
+        } catch (RuntimeException e) {
+            System.out.println(e);
+        } catch (final Exception | Error e) {
+            System.out.println(e);
+        }
+        return JavaParser.parse(file);
+    }
+
+    class A<T extends Integer & Serializable> implements XXX, Serializable {
+
+        public <ABC> A(Integer integer, ABC string) throws Exception, IOException {
+        }
+    }
+
+    private <Y> void x(Map<? extends X, ? super T> x) {
+        @Deprecated Comparator c = new Comparator() {
+
+            public int compare(Object o1, Object o2) {
+                try {
+                    A<Integer> a = new <String> A<Integer>(new Integer(11), "foo") {
+                    };
+                } catch (Exception e) {
+                }
+                return 0;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return super.equals(obj);
+            }
+        };
+    }
+
+    private static InputStream createInputStream() {
+        return new ByteArrayInputStream(null);
+    }
+}
+
+class Base {
+
+    public <A, B> void check2(A val1, B val2) {
+    }
+}
+
+interface XXX extends Serializable, Cloneable {
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/pretty_printing_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/pretty_printing_scenarios.story
new file mode 100644
index 0000000..5450cb0
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/pretty_printing_scenarios.story
@@ -0,0 +1,519 @@
+Scenario: When printing the instantiation we should use the right amount of spaces
+
+Given the class:
+public class A {
+    Object foo = new Object();
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class A {
+
+    Object foo = new Object();
+}
+
+
+Scenario: When printing the lambda expression we should use the right indentation
+
+Given the class:
+public class B {
+	Runnable runnable = ()-> System.out.println("running");
+    Consumer<Integer> consumer = i->{ i+=1; System.out.println(i);};
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class B {
+
+    Runnable runnable = () -> System.out.println("running");
+
+    Consumer<Integer> consumer = i -> {
+        i += 1;
+        System.out.println(i);
+    };
+}
+
+
+Scenario: Printing orphan comments in empty method
+Given the class:
+class A {
+    public void helloWorld(String greeting, String name) {
+        //sdfsdfsdf
+            //sdfds
+        /*
+                            dgfdgfdgfdgfdgfd
+         */
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class A {
+
+    public void helloWorld(String greeting, String name) {
+    // sdfsdfsdf
+    // sdfds
+    /*
+                            dgfdgfdgfdgfdgfd
+         */
+    }
+}
+
+
+
+Scenario: Printing orphan comments in empty method (issue 192)
+Given the class:
+public class StepImplementation {
+    @Step("A step")
+    public void contextStep() {
+        // Foo bar
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class StepImplementation {
+
+    @Step("A step")
+    public void contextStep() {
+    // Foo bar
+    }
+}
+
+
+Scenario: Printing orphan comments in for loop (issue 192)
+Given the class:
+public class StepImplementation {
+    public void contextStep() {
+        for (int i = 0; i < 5; i++) {
+            // foo bar
+        }
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class StepImplementation {
+
+    public void contextStep() {
+        for (int i = 0; i < 5; i++) {
+        // foo bar
+        }
+    }
+}
+
+
+Scenario: Printing orphan and attributed comments in for loop (issue 192)
+Given the class:
+public class StepImplementation {
+public void contextStep() {
+        for (int i = 0; i < 5; i++) {
+            // foo bar
+            System.out.println();
+            // another foo bar
+        }
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class StepImplementation {
+
+    public void contextStep() {
+        for (int i = 0; i < 5; i++) {
+            // foo bar
+            System.out.println();
+        // another foo bar
+        }
+    }
+}
+
+
+Scenario: An empty Enum is printed correctly
+Given the compilation unit:
+package test; enum XYZ {}
+When the class is parsed by the Java parser
+Then it is printed as:
+package test;
+
+enum XYZ {
+}
+
+Scenario: An enum without fields has no () on its members
+Given the compilation unit:
+package test; enum XYZ {A,B,C}
+When the class is parsed by the Java parser
+Then it is printed as:
+package test;
+
+enum XYZ {
+
+    A, B, C
+}
+
+Scenario: Strings with escaped newlines are parsed correctly
+Given the class:
+class A {
+    public void helloWorld(String greeting, String name) {
+        return "hello\nworld";
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class A {
+
+    public void helloWorld(String greeting, String name) {
+        return "hello\nworld";
+    }
+}
+
+Scenario: A multi-catch is printed correctly
+Given the class:
+class A {
+    public void a() {
+        try {
+        } catch (IndexOutOfBoundException | IOException e) { 
+        } 
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class A {
+
+    public void a() {
+        try {
+        } catch (IndexOutOfBoundException | IOException e) {
+        }
+    }
+}
+
+Scenario: An empty import does not fail
+Given the class:
+package a.b.c;
+
+;
+When the class is parsed by the Java parser
+Then it is printed as:
+package a.b.c;
+
+Scenario: we can parse blocks
+Given the block:
+{
+    a=2;
+    b=3;
+}
+When the block is parsed by the Java parser
+Then it is printed as:
+{
+    a = 2;
+    b = 3;
+}
+
+Scenario: we can parse statements
+Given the statement:
+while (true) {
+}
+When the statement is parsed by the Java parser
+Then it is printed as:
+while (true) {
+}
+
+Scenario: we can parse static on demand imports
+Given the import:
+import static a.b.c.Abc.*;
+When the import is parsed by the Java parser
+Then it is printed as:
+import static a.b.c.Abc.*;
+
+Scenario: we can parse static type imports
+Given the import:
+import static a.b.c.Abc;
+When the import is parsed by the Java parser
+Then it is printed as:
+import static a.b.c.Abc;
+
+Scenario: we can parse on demand imports
+Given the import:
+import a.b.c.*;
+When the import is parsed by the Java parser
+Then it is printed as:
+import a.b.c.*;
+
+Scenario: we can parse type imports
+Given the import:
+import a.b.c.Abc;
+When the import is parsed by the Java parser
+Then it is printed as:
+import a.b.c.Abc;
+
+Scenario: we can parse annotations
+Given the annotation:
+@Abc
+When the annotation is parsed by the Java parser
+Then it is printed as:
+@Abc
+
+Scenario: we can parse body declarations
+Given the body:
+String author();
+When the annotation body declaration is parsed by the Java parser
+Then it is printed as:
+String author();
+
+Scenario: we can parse class body declarations
+Given the body:
+public int xyz() {}
+When the class body declaration is parsed by the Java parser
+Then it is printed as:
+public int xyz() {
+}
+
+Scenario: we can parse interface body declarations
+Given the body:
+int xyz();
+When the interface body declaration is parsed by the Java parser
+Then it is printed as:
+int xyz();
+
+Scenario: It doesn't throw NPE when using a modifierVisitorAdapter
+Given the class:
+public class Example {
+  private String mString;
+  public Example(String arg) {
+    mString = arg;
+  }
+}
+When the class is parsed by the Java parser
+When the class is visited by an empty ModifierVisitorAdapter
+Then it is printed as:
+public class Example {
+
+    private String mString;
+
+    public Example(String arg) {
+        mString = arg;
+    }
+}
+
+Scenario: JavaDoc OR comment is printed, not both.
+Given the class:
+public class Foo {
+    /** This line gets duplicated */
+    public void foo() {
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class Foo {
+
+    /**
+     * This line gets duplicated
+     */
+    public void foo() {
+    }
+}
+
+Scenario: various lamba casts (issue 418)
+Given the class:
+public class TestLambda {
+    void okMethod() {
+        return (ITF) () -> {
+            return true;
+        };
+    }
+    void faliingMethod() {
+        testThis(check ? null : (ITF) () -> {
+            return true;
+        });
+    }
+}
+When the class body declaration is parsed by the Java parser
+Then it is printed as:
+public class TestLambda {
+
+    void okMethod() {
+        return (ITF) () -> {
+            return true;
+        };
+    }
+
+    void faliingMethod() {
+        testThis(check ? null : (ITF) () -> {
+            return true;
+        });
+    }
+}
+
+Scenario: Duplicate methods are not a parsing error (#416)
+Given the class:
+public class Foo {
+    public void foo() {
+    }
+    public void foo() {
+    }
+    public void foo() {
+    }
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class Foo {
+
+    public void foo() {
+    }
+
+    public void foo() {
+    }
+
+    public void foo() {
+    }
+}
+
+Scenario: Both array syntaxes are supported (#416)
+Given the class:
+public class Foo {
+    public void m1(boolean[] boolArray) {}
+    public void m1(boolean boolArray[]) {}
+    public void m1(boolean[] boolArray[]) {}
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+public class Foo {
+
+    public void m1(boolean[] boolArray) {
+    }
+
+    public void m1(boolean[] boolArray) {
+    }
+
+    public void m1(boolean[][] boolArray) {
+    }
+}
+
+
+Scenario: Array parts can be annotated
+Given the class:
+class Foo {
+    void m1(@Boo boolean @Index1 [] @ Index2 [] boolArray) {}
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class Foo {
+
+    void m1(@Boo boolean @Index1 [] @Index2 [] boolArray) {
+    }
+}
+
+Scenario: Annotations are supported on annotations
+Given the class:
+@C @interface D {
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+@C
+@interface D {
+}
+
+Scenario: Annotations are supported on interfaces
+Given the class:
+@C interface Abc {
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+@C
+interface Abc {
+}
+
+Scenario: Annotations are supported on enums
+Given the class:
+@C enum Abc {
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+@C
+enum Abc {
+}
+
+Scenario: Annotations are supported on classes (issue 436 is the commented part)
+Given the compilation unit:
+@C
+public class Abc<@C A, @C X extends @C String & @C Serializable> {
+
+	@C int @C[] @C []f;
+
+	@C
+	public Abc(@C int p, List<@C ? extends Object> aa){
+		@C int b;
+	}
+	public @C void a(@C int o) {
+/*		try {
+			throw new IOException();
+		} catch (@C NullPointerException | @C IOException e) {
+		}
+*/	}
+}
+When the compilation unit is parsed by the Java parser
+Then it is printed as:
+@C
+public class Abc<@C A, @C X extends @C String & @C Serializable> {
+
+    @C
+    int @C [] @C [] f;
+
+    @C
+    public Abc(@C int p, List<@C ? extends Object> aa) {
+        @C int b;
+    }
+
+    @C
+    public void a(@C int o) {
+    /*		try {
+			throw new IOException();
+		} catch (@C NullPointerException | @C IOException e) {
+		}
+*/
+    }
+}
+
+
+Scenario: Annotations are supported inside catch (issue 436)
+Given the compilation unit:
+public class Abc {
+	public void a() {
+		try {
+		} catch (@C NullPointerException | @C IOException e) {
+		}
+	}
+}
+When the compilation unit is parsed by the Java parser
+Then it is printed as:
+public class Abc {
+
+    public void a() {
+        try {
+        } catch (@C NullPointerException | @C IOException e) {
+        }
+    }
+}
+
+Scenario: Inner class notation does not confuse annotations (#107)
+Given the class:
+class A extends @Ann1 B.@Ann2 C {
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+class A extends @Ann1 B.@Ann2 C {
+}
+
+Scenario: Make sure interface extends can be annotated
+Given the class:
+interface A extends @X B, @Y C, @Z D {
+}
+When the class is parsed by the Java parser
+Then it is printed as:
+interface A extends @X B, @Y C, @Z D {
+}
+
+Scenario: default modifier isn't printed twice
+Given the class:
+interface X {default String author(){}}
+When the annotation body declaration is parsed by the Java parser
+Then it is printed as:
+interface X {
+
+    default String author() {
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/ClassInLatin1.java b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/ClassInLatin1.java
new file mode 100644
index 0000000..096c70a
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/ClassInLatin1.java
@@ -0,0 +1,6 @@
+// Comment in Latin1:
+// A l'émej in piasì che sent dësgust.
+// For the curios reader, this is Piedmontese dialect
+class A {
+
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/JavaConcepts.java b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/JavaConcepts.java
new file mode 100644
index 0000000..8e6dc92
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/JavaConcepts.java
@@ -0,0 +1,397 @@
+package japa.bdd.samples;
+
+import com.github.javaparser.JavaParser;
+import japa.parser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Ignore;
+
+import java.io.*;
+import java.util.*;
+
+@Ignore
+@Deprecated
+public class JavaConcepts<T extends List<int[]>, X> extends Base implements Serializable {
+
+    static Class clz1 = String.class;
+
+    protected Class clz2 = (String.class);
+
+    Class clz3 = int.class;
+
+    Class clz4 = (int.class);
+
+    int[] arr = new int[10];
+
+    byte bye = 0;
+
+    byte byebye[] = null;
+
+    short sh1, sh2 = 1;
+
+    int intWithUnderscore = 1234_5678;
+
+    long longWithUnderscore = 1234_5678L;
+
+    float floatWithUnderscore = 1_234.5_678f;
+
+    float floatWithUnderscoreAndExponent = 1_234e1_0f;
+
+    double doubleWithUnderscore = 1_234.5_678;
+
+    double doubleWithUnderscoreAndExponent = 1_234e1_0;
+
+    int binaryLiteral = 0b101101;
+
+    List<String>[][] arrLS = (List<String>[][]) new List<?>[10][];
+
+    ;
+
+    {
+        int z = 0, y = 0;
+        int a = (z) + y;
+        a = (+z) + y;
+        byte b = (byte) +y;
+    }
+
+    List<String> diamond1 = new LinkedList<>();
+
+    @Deprecated()
+    static class Ugly {
+
+        static int x = 0;
+
+        public static void main(String[] args) {
+            x = +x;
+            x = ~x;
+            --x;
+            boolean b = !false;
+            x &= 2;
+            x |= 2;
+            x ^= 2;
+            x -= 2;
+            x %= 2;
+            x /= 2;
+            x *= 2;
+            x <<= 2;
+            x >>= 2;
+            x >>>= 2;
+            b = b || false;
+            b = b | false;
+            b = b & false;
+            b = b ^ false;
+            b = b != false;
+            b = x > 1;
+            b = x < 1;
+            b = x >= 1;
+            b = x <= 1;
+            x = x << 1;
+            x = x >> 1;
+            x = x >>> 1;
+            x = x - 1;
+            x = x * 1;
+            x = x % 1;
+            x = x / 1;
+        }
+    }
+
+    ;
+
+    @Deprecated()
+    int[][][][] arr2 = new int[10][2][1][0];
+
+    volatile float fff = 0x1.fffeP+127f;
+
+    char cc = 'a';
+
+    int[][] arr3 = {{1, 2}, {3, 4}};
+
+    static int[] arr4[] = {};
+
+    public static JavaConcepts t;
+
+    static {
+        arr4 = new int[][]{{2}, {1}};
+    }
+
+    {
+        arr3 = new int[][]{{2}, {1}};
+    }
+
+    public enum Teste {
+
+        asc, def
+    }
+
+    public enum Sexo {
+
+        m, @Deprecated
+        f;
+
+        public enum Sexo_ implements Serializable, Cloneable {
+        }
+
+        private Sexo() {
+        }
+    }
+
+    @Deprecated
+    public enum Enum {
+
+        m(1) {
+            @Override
+            void mm() {
+            }
+        }, f(2) {
+            void mm() {
+            }
+        };
+
+        native void nnn();
+
+        transient int x;
+
+        private Enum(int x) {
+            this.x = x;
+        }
+
+        abstract void mm();
+    }
+
+    strictfp double ddd() {
+        return 0.0;
+    }
+
+    public <T, E> JavaConcepts(int x) {
+        this.arr[0] = x;
+        T val1 = null;
+        E val2 = null;
+        super.<T, E>check2(val1, val2);
+        boolean b = true, y = false;
+        abstract class X {
+
+            int i = 0;
+
+            public <D> X() {
+            }
+
+            public void m() {
+            }
+        }
+        @Deprecated
+        final class Y extends X {
+
+            public Y() {
+                super();
+                JavaConcepts.this.cc = 'c';
+                super.i = 1;
+                Y.super.m();
+            }
+
+            public Y(int y) {
+                super();
+            }
+
+            public Y(long x) {
+                this();
+            }
+        }
+    }
+
+    public <T> JavaConcepts(String str) {
+    }
+
+    private class QWE extends JavaConcepts<List<int[]>, String> {
+
+        @Deprecated
+        final int z = 0;
+
+        int i = (int) -1;
+
+        public QWE(String... x) {
+            <String>super(x[0]);
+        }
+
+        public QWE(int... x) {
+            super(x[0]);
+            i = x[0];
+            assert true;
+            assert 1 == 1 : 2;
+            {
+                int iii = 3;
+                iii += 3;
+            }
+            label:
+            {
+                int iii = 1;
+            }
+            ;
+            ;
+            int min = -2147483648;
+            long sl = 123123123123l;
+            long minl = -9223372036854775808L;
+            switch (i) {
+            }
+            ll:
+            switch (i) {
+                case 1:
+                    System.out.println(1);
+                    break ll;
+                default: {
+                    System.out.println("default");
+                    break;
+                }
+                case 2:
+                    if (t instanceof Base) {
+                        System.out.println(1);
+                    }
+                    i++;
+                    ++i;
+            }
+        }
+
+        private synchronized int doSomething()[] {
+            List<? extends Number> x = new ArrayList<Integer>();
+            return new int[]{1};
+        }
+    }
+
+    public static void main(String[] args) throws ParseException, IOException {
+        int x = 2;
+        CompilationUnit cu = parse(new File("src/japa/parser/javacc/Parser.java"));
+        System.out.println(cu);
+        JavaConcepts teste = new JavaConcepts(2);
+        JavaConcepts.QWE qwe = teste.new QWE(1);
+        if (1 + 1 == 2) {
+            teste = null;
+            teste = new JavaConcepts(1);
+        } else {
+            x = 3;
+            teste = new JavaConcepts(1);
+            x = x == 0 ? 2 : 4;
+        }
+        if (true)
+            x = 1;
+        else
+            x = 3;
+        if (true)
+            x = 1;
+        else if (false)
+            x = 3;
+        else
+            x = 2;
+        while (true) {
+            xxx:
+            while (x == 3) continue xxx;
+            break;
+        }
+        do {
+            x++;
+        } while (x < 100);
+        do x++; while (x < 100);
+        for (@Deprecated int i : arr4[0]) {
+            x--;
+        }
+        for (@Deprecated final int i = 0, j = 1; i < 10; x++) {
+            break;
+        }
+        int i, j;
+        for (i = 0, j = 1; i < 10 && j < 2; i++, j--) {
+            break;
+        }
+    }
+
+    public static CompilationUnit parse(@Deprecated File file) throws ParseException, IOException {
+        String a = ((String) "qwe");
+        String x = ((String) clz1.getName());
+        int y = ((Integer) (Object) x).intValue();
+        synchronized (file) {
+            file = null;
+            file = new File("");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (final NullPointerException e) {
+            System.out.println("catch");
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream();
+             InputStream in2 = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        }
+        try {
+            System.out.println("whatever");
+        } catch (RuntimeException e) {
+            System.out.println(e);
+        } catch (final Exception | Error e) {
+            System.out.println(e);
+        }
+        return JavaParser.parse(file);
+    }
+
+    class A<T extends Integer & Serializable> implements XXX, Serializable {
+
+        public <ABC> A(Integer integer, ABC string) throws Exception, IOException {
+        }
+    }
+
+    private <Y> void x(Map<? extends X, ? super T> x) {
+        @Deprecated Comparator c = new Comparator() {
+
+            public int compare(Object o1, Object o2) {
+                try {
+                    A<Integer> a = new <String>A<Integer>(new Integer(11), "foo") {
+                    };
+                } catch (Exception e) {
+                }
+                return 0;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return super.equals(obj);
+            }
+        };
+    }
+
+    private static InputStream createInputStream() {
+        return new ByteArrayInputStream(null);
+    }
+}
+
+class Base {
+
+    public <A, B> void check2(A val1, B val2) {
+    }
+}
+
+interface XXX extends Serializable, Cloneable {
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/package-info.java b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/package-info.java
new file mode 100644
index 0000000..5703eb4
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/samples/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * This package contains class for doing some stuff.
+ */
+@C
+package com.company.stuff;
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bdd/visitor_scenarios.story b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/visitor_scenarios.story
new file mode 100644
index 0000000..634a9f2
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bdd/visitor_scenarios.story
@@ -0,0 +1,67 @@
+Scenario: A class that is replicated using a CloneVisitor should be equal to the source
+
+Given a CompilationUnit
+Given a second CompilationUnit
+When the following source is parsed:
+package japa.parser;
+public class ClassEquality {
+
+    public void aMethod(){
+        int a=0; // second comment
+    }
+}
+When the CompilationUnit is cloned to the second CompilationUnit
+Then the CompilationUnit is equal to the second CompilationUnit
+Then the CompilationUnit has the same hashcode to the second CompilationUnit
+
+
+Scenario: A classes variable name is changed to uppercase VoidVisitorAdapter
+
+Given a CompilationUnit
+Given a VoidVisitorAdapter with a visit method that changes variable names to uppercase
+When the following source is parsed:
+package japa.parser;
+public class ToUpperClass {
+    private int zero = 0;
+}
+When the CompilationUnit is visited by the to uppercase visitor
+Then the expected source should be:
+package japa.parser;
+public class ToUpperClass {
+    private int ZERO = 0;
+}
+
+Scenario: A class with a try statement is visited using by a VoidVisitorAdapter
+
+Given a CompilationUnit
+Given a VoidVisitorAdapter with a visit method and collects the variable names
+When the following source is parsed:
+package japa.parser;
+public class ToUpperClass {
+    public void aMethod(){
+        try {
+            int zero = 0;
+        }catch (Exception exception) {
+        }
+    }
+}
+When the CompilationUnit is visited by the variable name collector visitor
+Then the collected variable name is "exception;zero;"
+
+
+Scenario: A class with a try statement is visited using by a GenericVisitorAdapter
+
+Given a CompilationUnit
+Given a GenericVisitorAdapter with a visit method that returns variable names
+When the following source is parsed:
+package japa.parser;
+public class ToUpperClass {
+    public void aMethod(){
+        try {
+            int zero = 0;
+        }catch (Exception exception) {
+        }
+    }
+}
+When the CompilationUnit is visited by the visitor that returns variable names
+Then the return variable name is "zero"
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/javaparser_test_results.txt b/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/javaparser_test_results.txt
new file mode 100644
index 0000000..8a9fcbe
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/javaparser_test_results.txt
@@ -0,0 +1 @@
+0 problems in 0 files
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/openjdk_src_repo_test_results.txt b/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/openjdk_src_repo_test_results.txt
new file mode 100644
index 0000000..b3d4e57
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/openjdk_src_repo_test_results.txt
@@ -0,0 +1,655 @@
+langtools-19293ea3999f/test/jdk/javadoc/doclet/testAnchorNames/pkg1/RegClass.java
+(line 68,col 16) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/jdk/javadoc/doclet/testSourceTab/DoubleTab/C.java
+Lexical error at line 33, column 2.  Encountered: "t" (116), after : "\\"
+
+langtools-19293ea3999f/test/jdk/javadoc/doclet/testSourceTab/SingleTab/C.java
+Lexical error at line 33, column 2.  Encountered: "t" (116), after : "\\"
+
+langtools-19293ea3999f/test/jdk/javadoc/doclet/testUnnamedPackage/BadSource.java
+Parse error. Found  "Just" <IDENTIFIER>, expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/jdk/javadoc/tool/6964914/Error.java
+(line 25,col 12) Parse error. Found "}", expected "("
+
+langtools-19293ea3999f/test/jdk/javadoc/tool/6964914/JavacWarning.java
+(line 25,col 12) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/jdk/javadoc/tool/enum/docComments/pkg1/Operation.java
+(line 33,col 1) 'abstract' is not allowed here.
+
+langtools-19293ea3999f/test/jdk/javadoc/tool/T4994049/FileWithTabs.java
+Lexical error at line 25, column 2.  Encountered: "t" (116), after : "\\"
+
+langtools-19293ea3999f/test/tools/javac/6302184/T6302184.java
+Lexical error at line 28, column 9.  Encountered: "\ufffd" (65533), after : ""
+
+langtools-19293ea3999f/test/tools/javac/6440583/A.java
+(line 25,col 28) Parse error. Found  "1" <INTEGER_LITERAL>, expected "}"
+
+langtools-19293ea3999f/test/tools/javac/annotations/AnnotationTypeElementModifiers.java
+(line 17,col 5) 'private' is not allowed here.
+(line 18,col 5) 'private' is not allowed here.
+(line 20,col 5) 'protected' is not allowed here.
+(line 21,col 5) 'protected' is not allowed here.
+(line 23,col 5) 'static' is not allowed here.
+(line 24,col 5) 'static' is not allowed here.
+(line 26,col 5) 'final' is not allowed here.
+(line 27,col 5) 'final' is not allowed here.
+(line 29,col 5) 'synchronized' is not allowed here.
+(line 30,col 5) 'synchronized' is not allowed here.
+(line 32,col 5) 'volatile' is not allowed here.
+(line 33,col 5) 'volatile' is not allowed here.
+(line 35,col 5) 'transient' is not allowed here.
+(line 36,col 5) 'transient' is not allowed here.
+(line 38,col 5) 'native' is not allowed here.
+(line 39,col 5) 'native' is not allowed here.
+(line 41,col 5) 'strictfp' is not allowed here.
+(line 42,col 5) 'strictfp' is not allowed here.
+(line 44,col 5) 'default' is not allowed here.
+(line 45,col 5) 'default' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/annotations/FinalReceiverTest.java
+(line 11,col 43) Parse error. Found ".", expected one of  ")" "," "@" "["
+(line 14,col 2) Parse error. Found <EOF>, expected "}"
+(line 14,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/AnnComma.java
+(line 12,col 35) Parse error. Found ")", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/NoDefault.java
+(line 8,col 19) Parse error. Found "{", expected one of  ";" "default"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/NoDefaultAbstract.java
+(line 8,col 5) 'default' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/NoStatic.java
+(line 9,col 18) Parse error. Found "{", expected one of  ";" "default"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/NoStaticAbstract.java
+(line 9,col 5) 'static' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Syntax1.java
+(line 17,col 21) Parse error. Found ",", expected one of  "!=" "%" "&" "&&" "(" ")" "*" "+" "-" "/" "<" "<=" "==" ">" ">=" "?" "^" "instanceof" "|" "||"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z12.java
+(line 10,col 15) Parse error. Found "void", expected one of  ";" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "volatile" "with" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z13.java
+(line 11,col 11) Parse error. Found "throws", expected one of  ";" "default"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z14.java
+(line 10,col 12) Parse error. Found "<", expected "{"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z2.java
+(line 13,col 17) Parse error. Found "default", expected one of  ";" "@" "[" "throws" "{"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z3.java
+(line 13,col 17) Parse error. Found "default", expected one of  ";" "@" "[" "throws" "{"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z5.java
+(line 12,col 12) Parse error. Found "extends", expected "{"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z8.java
+(line 11,col 10) Parse error. Found "int", expected ")"
+
+langtools-19293ea3999f/test/tools/javac/annotations/neg/Z9.java
+(line 10,col 15) Parse error. Found "<", expected one of  ";" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "volatile" "with" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/6967002/T6967002.java
+(line 33,col 16) Parse error. Found "...", expected one of  "!=" "%" "%=" "&" "&&" "&=" "(" ")" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedClassExpr.java
+(line 12,col 15) Parse error. Found "@", expected one of  "!" "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 13,col 8) Parse error. Found "@", expected one of  "!" "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 17,col 8) Parse error. Found "@", expected one of  "!" "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 18,col 8) Parse error. Found "@", expected one of  "!" "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/failures/AnnotatedMethodSelectorTest.java
+(line 12,col 14) Parse error. Found ".", expected one of  "%=" "&=" "(" "*=" "++" "+=" "--" "-=" "/=" ";" "<<=" "=" ">>=" ">>>=" "^=" "|="
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/failures/BadCast.java
+(line 12,col 16) Parse error. Found "@", expected one of  "!" "(" ")" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/failures/IncompleteArray.java
+(line 11,col 11) Parse error. Found "@", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/failures/IndexArray.java
+(line 12,col 11) Parse error. Found "@", expected one of  "!=" "%" "%=" "&" "&&" "&=" "(" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/failures/OldArray.java
+(line 12,col 10) Parse error. Found "@", expected one of  "]"
+
+langtools-19293ea3999f/test/tools/javac/annotations/typeAnnotations/failures/StaticFields.java
+(line 13,col 10) Parse error. Found "@", expected one of  "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 17,col 9) Parse error. Found "@", expected one of  "!" "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/api/T6265137a.java
+(line 24,col 1) Parse error. Found <EOF>, expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/BadAnnotation.java
+(line 11,col 21) Parse error. Found "int", expected ")"
+
+langtools-19293ea3999f/test/tools/javac/BadHexConstant.java
+(line 12,col 14) Parse error. Found  "xL" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/declaration/method/MethodVoidParameter.java
+(line 7,col 16) Parse error. Found "void", expected one of  ")" "@" "abstract" "boolean" "byte" "char" "default" "double" "enum" "exports" "final" "float" "int" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "volatile" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/defaultMethods/private/Private02.java
+(line 13,col 9) Cannot be 'abstract' and also 'private'.
+
+langtools-19293ea3999f/test/tools/javac/defaultMethods/private/Private07.java
+(line 9,col 5) 'private' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/defaultMethods/private/Private08.java
+(line 13,col 9) Can have only one of 'public', 'private'.
+(line 14,col 9) Cannot be 'abstract' and also 'private'.
+
+langtools-19293ea3999f/test/tools/javac/defaultMethods/private/Private09.java
+(line 9,col 17) Duplicated modifier
+
+langtools-19293ea3999f/test/tools/javac/defaultMethods/private/Private10.java
+(line 11,col 9) Cannot be 'abstract' and also 'private'.
+(line 14,col 9) Cannot be 'abstract' and also 'private'.
+
+langtools-19293ea3999f/test/tools/javac/DefiniteAssignment/ConstantInfiniteWhile.java
+Lexical error at line 68, column 0.  Encountered: <EOF> after : ""
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/AnnotationMustBeNameValue.java
+(line 32,col 15) Parse error. Found ",", expected one of  "!=" "%" "&" "&&" ")" "*" "+" "-" "/" "<" "<=" "==" ">" ">=" "?" "^" "instanceof" "|" "||"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ArrayAndReceiver.java
+(line 27,col 29) Parse error. Found "[", expected one of  ")" ","
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/AssertAsIdentifier2.java
+(line 27,col 5) Parse error. Found "assert", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/CallMustBeFirst.java
+(line 28,col 18) Parse error. Found "super", expected "}"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/CantAssignToThis.java
+(line 28,col 9) Illegal left hand side of an assignment.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/CantExtendIntfAnno.java
+(line 28,col 12) Parse error. Found "extends", expected "{"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/CatchWithoutTry.java
+(line 27,col 14) Parse error. Found "catch", expected "}"
+(line 30,col 5) Parse error. Found "}", expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/DefaultAllowedInIntfAnnotationMember.java
+(line 27,col 18) Parse error. Found "default", expected one of  ";" "@" "[" "throws" "{"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/DotClassExpected.java
+(line 27,col 11) Parse error. Found "int", expected one of  "!" "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ElseWithoutIf.java
+(line 27,col 14) Parse error. Found "else", expected "}"
+(line 30,col 5) Parse error. Found "}", expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/EmptyCharLiteral.java
+Lexical error at line 27, column 15.  Encountered: "\'" (39), after : "\'"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/EnumAsIdentifier2.java
+(line 27,col 9) 'enum' cannot be used as an identifier as it is a keyword.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/Expected2.java
+(line 30,col 13) Parse error. Found ";", expected one of  "(" "@" "["
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/Expected3.java
+Parse error. Found "int", expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ExpectedModule.java
+(line 26,col 1) Parse error. Found "class", expected "module"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/FinallyWithoutTry.java
+(line 27,col 14) Parse error. Found "finally", expected "}"
+(line 30,col 5) Parse error. Found "}", expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ForeachBadInitialization.java
+(line 29,col 14) Parse error. Found ":", expected one of  "!=" "%" "%=" "&" "&&" "&=" "(" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 31,col 2) Parse error. Found <EOF>, expected "}"
+(line 31,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IdentifierExpected.java
+(line 30,col 1) Parse error. Found "{", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalAnnotationDeclaration.java
+(line 27,col 5) Parse error. Found "@", expected "}"
+(line 29,col 5) Parse error. Found "}", expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalChar.java
+Lexical error at line 27, column 13.  Encountered: "`" (96), after : ""
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalComboModifiers.java
+(line 27,col 5) Can have only one of 'public', 'private'.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalDot.java
+(line 27,col 12) Parse error. Found ".", expected one of  "..." "@" "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalEscapeChar.java
+Lexical error at line 27, column 18.  Encountered: "!" (33), after : "\"\\"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalLineEndInCharLit.java
+Lexical error at line 27, column 15.  Encountered: "\n" (10), after : "\'"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalNonAsciiDigit.java
+(line 27,col 13) Parse error. Found  "\\u0660" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalStartOfExpr.java
+(line 27,col 11) Parse error. Found "=", expected one of  "!" "(" "+" "++" "-" "--" "@" "boolean" "byte" "char" "double" "enum" "exports" "false" "float" "int" "long" "module" "new" "null" "open" "opens" "provides" "requires" "short" "strictfp" "super" "this" "to" "transitive" "true" "uses" "void" "with" "{" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalStartOfStmt.java
+(line 29,col 17) Parse error. Found "}", expected one of  "(" "++" "--" ";" "@" "assert" "boolean" "break" "byte" "char" "continue" "do" "double" "enum" "exports" "false" "float" "for" "if" "int" "long" "module" "new" "null" "open" "opens" "provides" "requires" "return" "short" "strictfp" "super" "switch" "synchronized" "this" "throw" "to" "transitive" "true" "try" "uses" "void" "while" "with" "{" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 31,col 2) Parse error. Found <EOF>, expected one of  "else" "}"
+(line 31,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalStartOfType.java
+(line 27,col 27) Parse error. Found ")", expected one of  "boolean" "byte" "char" "double" "float" "int" "long" "short"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalUnderscore.java
+(line 27,col 13) Parse error. Found  "_" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IllegalUnicodeEscape.java
+Lexical error at line 27, column 15.  Encountered: ";" (59), after : "\\u"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/InitializerNotAllowed.java
+(line 27,col 5) An interface cannot have initializers.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/InterfaceNotAllowed.java
+(line 28,col 9) There is no such thing as a local interface.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IntfAnnotationCantHaveTypeParams.java
+(line 26,col 12) Parse error. Found "<", expected "{"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IntfAnnotationsCantHaveParams.java
+(line 27,col 17) Parse error. Found "int", expected ")"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/IntfAnnotationsCantHaveTypeParams.java
+(line 26,col 14) Parse error. Found "<", expected one of  ";" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "volatile" "with" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/InvalidBinaryNumber.java
+(line 27,col 13) Parse error. Found  "b201000010" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/InvalidHexNumber.java
+(line 28,col 13) Parse error. Found  "xz1357abc" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/InvalidModuleDirective/module-info.java
+(line 27,col 21) Parse error. Found  "resuires" <IDENTIFIER>, expected one of  "exports" "opens" "provides" "requires" "uses" "}"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/LocalEnum.java
+(line 28,col 14) Parse error. Found "{", expected one of  "," ";" "=" "@" "["
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/MalformedFpLit.java
+(line 28,col 15) Parse error. Found  "e" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ModifierNotAllowed.java
+(line 26,col 1) 'synchronized' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/NoAnnotationsOnDotClass.java
+(line 30,col 14) Parse error. Found "@", expected one of  "!" "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/NotAllowedClass.java
+(line 28,col 17) Parse error. Found "class", expected one of  "(" "++" "--" ";" "@" "assert" "boolean" "break" "byte" "char" "continue" "do" "double" "enum" "exports" "false" "float" "for" "if" "int" "long" "module" "new" "null" "open" "opens" "provides" "requires" "return" "short" "strictfp" "super" "switch" "synchronized" "this" "throw" "to" "transitive" "true" "try" "uses" "void" "while" "with" "{" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 31,col 2) Parse error. Found <EOF>, expected one of  "else" "}"
+(line 31,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/NotAllowedVariable.java
+(line 28,col 17) Parse error. Found "int", expected one of  "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/NotAStatement.java
+(line 27,col 14) Parse error. Found  "x" <IDENTIFIER>, expected "}"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/Orphaned.java
+(line 27,col 14) Parse error. Found "case", expected "}"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/PrematureEOF.java
+(line 26,col 20) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ProcessorWrongType/ProcessorWrongType.java
+Parse error. Found  "clas" <IDENTIFIER>, expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/RepeatedModifier.java
+(line 27,col 12) Duplicated modifier
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ThisAsIdentifier.java
+(line 27,col 5) Parse error. Found "this", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/ThrowsNotAllowedInAnno.java
+(line 27,col 18) Parse error. Found "throws", expected one of  ";" "default"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/TryWithoutCatchOrFinally.java
+(line 29,col 9) Try has no finally, no catch, and no resources.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/TryWithoutCatchOrFinallyOrResource.java
+(line 28,col 9) Try has no finally, no catch, and no resources.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/TypeReqClassArray.java
+(line 30,col 34) Parse error. Found ")", expected "["
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/UnclosedCharLiteral.java
+Lexical error at line 27, column 16.  Encountered: ";" (59), after : "\'a"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/UnclosedComment.java
+Lexical error at line 31, column 0.  Encountered: <EOF> after : ""
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/UnclosedStringLiteral.java
+Lexical error at line 27, column 21.  Encountered: "\n" (10), after : "\"abc;"
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/UnderscoreAsIdentifierError.java
+(line 27,col 12) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/UnderscoreAsIdentifierWarning.java
+(line 28,col 12) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/UnderscoreInLambdaExpression.java
+(line 26,col 52) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/UnexpectedTokenInModuleInfo/module-info.java
+Parse error. Found  "weak" <IDENTIFIER>, expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/diags/examples/VarargsAndReceiver.java
+(line 27,col 30) Parse error. Found "this", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/Digits.java
+(line 11,col 40) Parse error. Found  "\\u0663" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/enum/EnumAsIdentifier.java
+(line 11,col 9) 'enum' cannot be used as an identifier as it is a keyword.
+
+langtools-19293ea3999f/test/tools/javac/enum/EnumMembersOrder.java
+(line 11,col 10) Parse error. Found  "d" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "(" ")" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/enum/ExplicitlyAbstractEnum1.java
+(line 9,col 1) 'abstract' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/enum/ExplicitlyAbstractEnum2.java
+(line 9,col 1) 'abstract' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/enum/ExplicitlyFinalEnum1.java
+(line 9,col 1) 'final' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/enum/ExplicitlyFinalEnum2.java
+(line 9,col 1) 'final' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/enum/LocalEnum.java
+(line 11,col 14) Parse error. Found "{", expected one of  "," ";" "=" "@" "["
+(line 13,col 2) Parse error. Found <EOF>, expected "}"
+(line 13,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/EOI.java
+(line 10,col 16) Parse error. Found  "foobar\u001a" <IDENTIFIER>, expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/ExtendArray.java
+(line 11,col 34) Parse error. Found "[", expected one of  "," "implements" "{"
+
+langtools-19293ea3999f/test/tools/javac/ExtraneousEquals.java
+(line 10,col 22) Parse error. Found "=", expected one of  "!" "(" "+" "++" "-" "--" "@" "]" "boolean" "byte" "char" "double" "enum" "exports" "false" "float" "int" "long" "module" "new" "null" "open" "opens" "provides" "requires" "short" "strictfp" "super" "this" "to" "transitive" "true" "uses" "void" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/failover/FailOver01.java
+(line 10,col 20) Parse error. Found "}", expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 10,col 26) Parse error. Found <EOF>, expected "}"
+(line 10,col 26) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/failover/FailOver15.java
+(line 17,col 9) Parse error. Found "}", expected one of  "%=" "&=" "*=" "++" "+=" "--" "-=" "/=" ";" "<<=" "=" ">>=" ">>>=" "^=" "|="
+(line 19,col 2) Parse error. Found <EOF>, expected "}"
+(line 19,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/FloatingPointChanges/BadConstructorModifiers.java
+(line 12,col 5) 'strictfp' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/generics/typevars/5060485/Compatibility02.java
+(line 36,col 9) 'static' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/generics/typevars/6680106/T6680106.java
+(line 11,col 24) Parse error. Found "[", expected one of  "&" "," ">"
+
+langtools-19293ea3999f/test/tools/javac/IllegalAnnotation.java
+(line 9,col 5) Parse error. Found "@", expected "}"
+(line 11,col 5) Parse error. Found "}", expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/incompleteStatements/T8000484.java
+(line 9,col 14) Parse error. Found "catch", expected "}"
+(line 10,col 29) Parse error. Found "else", expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/LabeledDeclaration.java
+(line 12,col 8) Parse error. Found "int", expected one of  "(" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/lambda/8131742/T8131742.java
+(line 8,col 32) Parse error. Found ".", expected one of  ")" "," "@" "["
+
+langtools-19293ea3999f/test/tools/javac/lambda/BadLambdaPos.java
+(line 18,col 26) Parse error. Found "+", expected one of  ")" ","
+(line 19,col 26) Parse error. Found "instanceof", expected one of  ")" ","
+(line 23,col 30) Parse error. Found "+", expected one of  "," ";"
+(line 24,col 33) Parse error. Found "instanceof", expected one of  "," ";"
+
+langtools-19293ea3999f/test/tools/javac/lambda/BadStatementInLambda.java
+(line 18,col 19) Parse error. Found  "1" <INTEGER_LITERAL>, expected "}"
+
+langtools-19293ea3999f/test/tools/javac/lambda/funcInterfaces/LambdaTest1_neg1.java
+(line 13,col 64) Parse error. Found "}", expected one of  "," ";"
+(line 15,col 2) Parse error. Found <EOF>, expected "}"
+(line 15,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/lambda/IdentifierTest.java
+(line 41,col 11) '_' is a reserved keyword.
+(line 44,col 16) '_' is a reserved keyword.
+(line 45,col 20) '_' is a reserved keyword.
+(line 46,col 22) '_' is a reserved keyword.
+(line 51,col 13) '_' is a reserved keyword.
+(line 51,col 15) '_' is a reserved keyword.
+(line 51,col 23) '_' is a reserved keyword.
+(line 53,col 13) '_' is a reserved keyword.
+(line 55,col 13) '_' is a reserved keyword.
+(line 61,col 21) '_' is a reserved keyword.
+(line 62,col 42) '_' is a reserved keyword.
+(line 63,col 67) '_' is a reserved keyword.
+(line 70,col 13) '_' is a reserved keyword.
+(line 71,col 14) '_' is a reserved keyword.
+(line 72,col 18) '_' is a reserved keyword.
+(line 77,col 22) '_' is a reserved keyword.
+(line 79,col 13) '_' is a reserved keyword.
+(line 79,col 15) '_' is a reserved keyword.
+(line 81,col 13) '_' is a reserved keyword.
+(line 81,col 15) '_' is a reserved keyword.
+(line 88,col 10) '_' is a reserved keyword.
+(line 88,col 38) '_' is a reserved keyword.
+(line 94,col 14) '_' is a reserved keyword.
+(line 101,col 17) '_' is a reserved keyword.
+(line 101,col 26) '_' is a reserved keyword.
+(line 118,col 20) '_' is a reserved keyword.
+(line 123,col 10) '_' is a reserved keyword.
+(line 128,col 17) '_' is a reserved keyword.
+(line 131,col 17) '_' is a reserved keyword.
+(line 138,col 17) '_' is a reserved keyword.
+(line 138,col 24) '_' is a reserved keyword.
+(line 138,col 33) '_' is a reserved keyword.
+(line 139,col 39) '_' is a reserved keyword.
+(line 143,col 13) '_' is a reserved keyword.
+(line 144,col 15) '_' is a reserved keyword.
+(line 145,col 13) '_' is a reserved keyword.
+(line 150,col 15) '_' is a reserved keyword.
+(line 151,col 17) '_' is a reserved keyword.
+(line 157,col 16) '_' is a reserved keyword.
+(line 159,col 25) '_' is a reserved keyword.
+(line 168,col 5) '_' is a reserved keyword.
+(line 172,col 26) '_' is a reserved keyword.
+(line 174,col 19) '_' is a reserved keyword.
+(line 180,col 11) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/tools/javac/lambda/lambdaExpression/InvalidExpression1.java
+(line 15,col 66) Parse error. Found "}", expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 16,col 5) Parse error. Found "}", expected one of  "," ";"
+(line 17,col 2) Parse error. Found <EOF>, expected "}"
+(line 17,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/lambda/UnderscoreAsIdent.java
+(line 30,col 9) '_' is a reserved keyword.
+(line 30,col 9) '_' is a reserved keyword.
+(line 32,col 8) '_' is a reserved keyword.
+(line 32,col 8) '_' is a reserved keyword.
+(line 34,col 7) '_' is a reserved keyword.
+(line 35,col 12) '_' is a reserved keyword.
+(line 36,col 10) '_' is a reserved keyword.
+(line 36,col 19) '_' is a reserved keyword.
+(line 38,col 16) '_' is a reserved keyword.
+(line 41,col 18) '_' is a reserved keyword.
+(line 41,col 25) '_' is a reserved keyword.
+(line 41,col 33) '_' is a reserved keyword.
+(line 44,col 34) '_' is a reserved keyword.
+(line 47,col 9) '_' is a reserved keyword.
+(line 49,col 19) '_' is a reserved keyword.
+(line 51,col 9) '_' is a reserved keyword.
+(line 53,col 22) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/tools/javac/lambda/VoidLambdaParameter.java
+(line 7,col 18) Parse error. Found "void", expected one of  "!" "(" ")" "enum" "exports" "false" "module" "new" "null" "open" "opens" "provides" "requires" "strictfp" "super" "this" "to" "transitive" "true" "uses" "with" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/literals/BadBinaryLiterals.java
+(line 11,col 20) Parse error. Found  "2" <INTEGER_LITERAL>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/literals/BadUnderscoreLiterals.java
+(line 15,col 14) Parse error. Found  "_" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/literals/T6891079.java
+(line 8,col 14) Parse error. Found  "B" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/modules/InvalidModuleDirective/module-info.java
+(line 9,col 21) Parse error. Found  "resuires" <IDENTIFIER>, expected one of  "exports" "opens" "provides" "requires" "uses" "}"
+
+langtools-19293ea3999f/test/tools/javac/overrridecrash/A.java
+(line 25,col 5) Can have only one of 'protected', 'private'.
+
+langtools-19293ea3999f/test/tools/javac/overrridecrash/B.java
+(line 12,col 5) Can have only one of 'protected', 'private'.
+
+langtools-19293ea3999f/test/tools/javac/Parens3.java
+(line 12,col 9) Parse error. Found ":", expected one of  "%=" "&=" "*=" "++" "+=" "--" "-=" "/=" ";" "<<=" "=" ">>=" ">>>=" "^=" "|="
+
+langtools-19293ea3999f/test/tools/javac/ParseConditional.java
+(line 23,col 13) Illegal left hand side of an assignment.
+
+langtools-19293ea3999f/test/tools/javac/parser/7157165/T7157165.java
+(line 11,col 19) Parse error. Found "|", expected one of  "," ">"
+
+langtools-19293ea3999f/test/tools/javac/parser/8081769/T8081769.java
+(line 9,col 20) Parse error. Found ".", expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 10,col 20) Parse error. Found ".", expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 11,col 20) Parse error. Found ".", expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 12,col 20) Parse error. Found ".", expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 14,col 31) Parse error. Found ".", expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/parser/ErroneousParameters.java
+(line 11,col 34) Parse error. Found "...", expected one of  ")" "," "@" "["
+
+langtools-19293ea3999f/test/tools/javac/parser/MissingClosingBrace.java
+(line 13,col 1) Parse error. Found <EOF>, expected one of  "else" "}"
+(line 13,col 2) Parse error. Found <EOF>, expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/parser/SingleCommaAnnotationValueFail.java
+(line 34,col 11) Parse error. Found  "0" <INTEGER_LITERAL>, expected "}"
+
+langtools-19293ea3999f/test/tools/javac/parser/T4881269.java
+(line 32,col 10) Parse error. Found ".", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/policy/test3/A.java
+(line 5,col 36) Parse error. Found  "0" <INTEGER_LITERAL>, expected "}"
+
+langtools-19293ea3999f/test/tools/javac/processing/6994946/SyntaxErrorTest.java
+(line 14,col 9) Parse error. Found "}", expected "("
+
+langtools-19293ea3999f/test/tools/javac/processing/errors/TestParseErrors/ParseErrors.java
+(line 37,col 36) Parse error. Found ",", expected one of  "..." "@" "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/quid/T6999438.java
+Lexical error at line 8, column 9.  Encountered: "#" (35), after : ""
+
+langtools-19293ea3999f/test/tools/javac/rawDiags/Error.java
+(line 9,col 17) Parse error. Found <EOF>, expected "("
+
+langtools-19293ea3999f/test/tools/javac/StoreClass.java
+(line 12,col 9) Illegal left hand side of an assignment.
+(line 13,col 9) Illegal left hand side of an assignment.
+
+langtools-19293ea3999f/test/tools/javac/SynchronizedClass.java
+(line 9,col 1) 'synchronized' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javac/T4994049/T4994049.java
+(line 11,col 5) Parse error. Found  "BAR" <IDENTIFIER>, expected one of  "," ";" "}"
+
+langtools-19293ea3999f/test/tools/javac/T6882235.java
+(line 10,col 11) Parse error. Found ";", expected one of  "!" "(" "+" "++" "-" "--" "@" "boolean" "byte" "char" "double" "enum" "exports" "false" "float" "int" "long" "module" "new" "null" "open" "opens" "provides" "requires" "short" "strictfp" "super" "this" "to" "transitive" "true" "uses" "void" "with" "{" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+
+langtools-19293ea3999f/test/tools/javac/T8026963/TypeAnnotationsCrashWithErroneousTreeTest.java
+(line 9,col 19) Parse error. Found "this", expected one of  ")" "@" "abstract" "boolean" "byte" "char" "default" "double" "enum" "exports" "final" "float" "int" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "volatile" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/T8171325/NPEClearingLocalClassNameIndexesTest.java
+(line 19,col 42) Type arguments may not be primitive.
+
+langtools-19293ea3999f/test/tools/javac/T8175198/AnnotationsAndFormalParamsTest.java
+(line 9,col 14) Parse error. Found "int", expected ")"
+
+langtools-19293ea3999f/test/tools/javac/T8181464/LambdaInAnnotationsCausesNPETest1.java
+(line 10,col 15) Parse error. Found "->", expected one of  "!=" "%" "&" "&&" "(" ")" "*" "+" "," "-" "/" "<" "<=" "==" ">" ">=" "?" "^" "instanceof" "|" "||"
+
+langtools-19293ea3999f/test/tools/javac/T8181464/LambdaInAnnotationsCausesNPETest2.java
+(line 10,col 24) Parse error. Found "->", expected one of  "!=" "%" "&" "&&" ")" "*" "+" "," "-" "/" "<" "<=" "==" ">" ">=" "?" "^" "instanceof" "|" "||"
+
+langtools-19293ea3999f/test/tools/javac/TryWithResources/BadTwrSyntax.java
+(line 14,col 42) Parse error. Found ";", expected ")"
+(line 14,col 43) Parse error. Found ")", expected "}"
+(line 16,col 9) Parse error. Found "try", expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/TryWithResources/PlainTry.java
+(line 11,col 9) Try has no finally, no catch, and no resources.
+
+langtools-19293ea3999f/test/tools/javac/TryWithResources/ResDeclOutsideTry.java
+(line 14,col 14) Parse error. Found "=", expected one of  "(" ")"
+(line 14,col 48) Parse error. Found ")", expected "}"
+(line 15,col 9) Parse error. Found "return", expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/TryWithResources/TwrForVariable2.java
+(line 13,col 13) Parse error. Found "final", expected one of  "(" "@" "boolean" "byte" "char" "double" "enum" "exports" "false" "float" "int" "long" "module" "new" "null" "open" "opens" "provides" "requires" "short" "strictfp" "super" "this" "to" "transitive" "true" "uses" "void" "with" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 15,col 9) Parse error. Found "try", expected one of  ";" "<" "@" "abstract" "boolean" "byte" "char" "class" "default" "double" "enum" "exports" "final" "float" "int" "interface" "long" "module" "native" "open" "opens" "private" "protected" "provides" "public" "requires" "short" "static" "strictfp" "synchronized" "to" "transient" "transitive" "uses" "void" "volatile" "with" "{" "}" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javac/unicode/FirstChar2.java
+Parse error. Found  "\\u0070ublic" <IDENTIFIER>, expected one of  ";" "@" "\u001a" "abstract" "class" "default" "enum" "final" "import" "interface" "module" "native" "open" "private" "protected" "public" "static" "strictfp" "synchronized" "transient" "transitive" "volatile" <EOF>
+
+langtools-19293ea3999f/test/tools/javac/unicode/NonasciiDigit.java
+(line 13,col 18) Parse error. Found  "\\uff11" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 16,col 21) Parse error. Found  ".0" <FLOATING_POINT_LITERAL>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "(" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 17,col 21) Parse error. Found  "\\uff11" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 18,col 21) Parse error. Found  "P\\uff11" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 19,col 21) Parse error. Found  "E\\uff11" <IDENTIFIER>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+(line 20,col 19) Parse error. Found ".", expected one of  "!" "(" "+" "++" "-" "--" "@" "boolean" "byte" "char" "double" "enum" "exports" "false" "float" "int" "long" "module" "new" "null" "open" "opens" "provides" "requires" "short" "strictfp" "super" "this" "to" "transitive" "true" "uses" "void" "with" "{" "~" <CHARACTER_LITERAL> <FLOATING_POINT_LITERAL> <IDENTIFIER> <INTEGER_LITERAL> <LONG_LITERAL> <STRING_LITERAL>
+(line 21,col 21) Parse error. Found  ".0" <FLOATING_POINT_LITERAL>, expected one of  "!=" "%" "%=" "&" "&&" "&=" "(" "*" "*=" "+" "+=" "," "-" "-=" "->" "/" "/=" "::" ";" "<" "<<=" "<=" "=" "==" ">" ">=" ">>=" ">>>=" "?" "^" "^=" "instanceof" "|" "|=" "||"
+
+langtools-19293ea3999f/test/tools/javac/unicode/TripleQuote.java
+Lexical error at line 13, column 15.  Encountered: "\'" (39), after : "\'"
+
+langtools-19293ea3999f/test/tools/javac/unicode/UnicodeAtEOL.java
+(line 33,col 13) Parse error. Found  "\\u000D" <IDENTIFIER>, expected "}"
+
+langtools-19293ea3999f/test/tools/javac/unicode/UnicodeCommentDelimiter.java
+(line 44,col 22) Parse error. Found  "plugh" <IDENTIFIER>, expected one of  "," ";" "=" "@" "["
+
+langtools-19293ea3999f/test/tools/javac/VoidArray.java
+(line 12,col 5) Parse error. Found "[", expected one of  "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" <IDENTIFIER>
+
+langtools-19293ea3999f/test/tools/javadoc/6964914/Error.java
+(line 25,col 12) Parse error. Found "}", expected "("
+
+langtools-19293ea3999f/test/tools/javadoc/6964914/JavacWarning.java
+(line 25,col 12) '_' is a reserved keyword.
+
+langtools-19293ea3999f/test/tools/javadoc/enum/docComments/pkg1/Operation.java
+(line 33,col 1) 'abstract' is not allowed here.
+
+langtools-19293ea3999f/test/tools/javadoc/T4994049/FileWithTabs.java
+Lexical error at line 25, column 2.  Encountered: "t" (116), after : "\\"
+
+304 problems in 175 files
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/openjdk_src_zip_test_results.txt b/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/openjdk_src_zip_test_results.txt
new file mode 100644
index 0000000..8e95fac
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/bulk_test_results/openjdk_src_zip_test_results.txt
@@ -0,0 +1,4 @@
+com/sun/xml/internal/rngom/parse/compact/CompactSyntax.java
+Lexical error at line 244, column 38.  Encountered: "n" (110), after : "\'\\u005c"
+
+1 problems in 1 files
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/Issue290.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/Issue290.java.txt
new file mode 100644
index 0000000..2b39ff8
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/Issue290.java.txt
@@ -0,0 +1,34 @@
+package org.test;
+
+import com.github.javaparser.JavaParser;
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.body.MethodDeclaration;
+import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+public class TestComments {
+    String str = "\\";
+
+    /**
+     * Comment that is ignored
+     */
+    public void someTestMethod() {}
+
+    public static void main(String[] args) throws Exception {
+        // Correct path so that it will point to the file with this code
+        try (FileInputStream in = new FileInputStream(
+                new File(".\\src\\main\\java\\org\\test\\TestComments.java"))) {
+            CompilationUnit compilationUnit = JavaParser.parse(in);
+
+            new VoidVisitorAdapter<Object>() {
+                public void visit(MethodDeclaration method, Object arg) {
+                    System.out.println("Method: " + method.getName());
+                    System.out.println("Comment: " + method.getComment());
+                    System.out.println("JavaDoc: " + method.getJavaDoc() + "\n");
+                }
+            }.visit(compilationUnit, null);
+        }
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/Issue624.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/Issue624.java.txt
new file mode 100644
index 0000000..de86d11
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/Issue624.java.txt
@@ -0,0 +1,14 @@
+package z;
+public class A  {
+
+	@Override
+	protected void getDataForCalcul() {
+
+		a.b(c)//
+				.success(data -> {
+					// DATA STD MACHINE
+					dosomething();
+				})//
+				.error(defaultErrorConsumer);
+	}
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/issue1003.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/issue1003.java.txt
new file mode 100644
index 0000000..0f8f460
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/issue_samples/issue1003.java.txt
@@ -0,0 +1,1470 @@
+package com.trigtech.privateme.server.am;
+
+import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.SparseArray;
+import com.trigtech.privateme.client.AppInterface;
+import com.trigtech.privateme.client.g;
+import com.trigtech.privateme.helper.proto.AppSetting;
+import com.trigtech.privateme.helper.proto.AppTaskInfo;
+import com.trigtech.privateme.helper.proto.i;
+import com.trigtech.privateme.helper.utils.k;
+import com.trigtech.privateme.helper.utils.v;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+class ActivityStack
+{
+  private static final String b = ActivityStack.class.getSimpleName();
+  final SparseArray<p> a = new SparseArray();
+  private final ActivityManager c;
+  private final TActivityManagerService d;
+  private com.trigtech.privateme.helper.utils.a<Integer, p> e = new com.trigtech.privateme.helper.utils.a();
+  private com.trigtech.privateme.helper.utils.a<Integer, f> f = new com.trigtech.privateme.helper.utils.a();
+  private com.trigtech.privateme.helper.utils.a<Integer, List<c>> g = new com.trigtech.privateme.helper.utils.a();
+  private com.trigtech.privateme.helper.utils.a<Integer, List<c>> h = new com.trigtech.privateme.helper.utils.a();
+
+  ActivityStack(TActivityManagerService paramTActivityManagerService)
+  {
+    this.d = paramTActivityManagerService;
+    this.c = ((ActivityManager)AppInterface.e().i().getSystemService("activity"));
+  }
+
+  private Intent a(int paramInt, c paramc, Intent paramIntent, ActivityInfo paramActivityInfo)
+  {
+    Intent localIntent1 = new Intent(paramIntent);
+    j localj = this.d.startProcessIfNeedLocked(paramActivityInfo.processName, paramInt, paramActivityInfo.packageName);
+    if (localj == null)
+      return null;
+    Intent localIntent2 = new Intent();
+    localIntent2.setClassName(AppInterface.e().k(), a(localj.i, paramActivityInfo));
+    ComponentName localComponentName1 = localIntent1.getComponent();
+    if (localComponentName1 == null)
+      localComponentName1 = k.a(paramActivityInfo);
+    localIntent2.setType(localComponentName1.flattenToString());
+    if (((0x80 & paramActivityInfo.flags) != 0) || (b(localIntent1, 1073741824)))
+      localIntent2.addFlags(1073741824);
+    if (paramc != null);
+    for (ComponentName localComponentName2 = paramc.b; ; localComponentName2 = null)
+    {
+      i locali = new i(localIntent1, paramActivityInfo, localComponentName2, paramInt);
+      localIntent2.putExtra("_PM_|_intent_", locali.a);
+      localIntent2.putExtra("_PM_|_info_", locali.b);
+      localIntent2.putExtra("_PM_|_caller_", locali.c);
+      localIntent2.putExtra("_PM_|_user_id_", locali.d);
+      return localIntent2;
+    }
+  }
+
+  private static c a(p paramp)
+  {
+    while (true)
+    {
+      int i;
+      synchronized (paramp.e)
+      {
+        i = -1 + paramp.e.size();
+        if (i >= 0)
+        {
+          c localc = (c)paramp.e.get(i);
+          if (!localc.i)
+            return localc;
+        }
+        else
+        {
+          return null;
+        }
+      }
+      i--;
+    }
+  }
+
+  private p a(int paramInt, Intent paramIntent)
+  {
+    for (int i = 0; i < this.a.size(); i++)
+    {
+      p localp = (p)this.a.valueAt(i);
+      if ((paramInt == localp.b) && (localp.d != null) && (paramIntent.getComponent().equals(localp.d.getComponent())))
+        return localp;
+    }
+    return null;
+  }
+
+  // ERROR //
+  private static String a(int paramInt, ActivityInfo paramActivityInfo)
+  {
+    // Byte code:
+    //   0: getstatic 214	tbox/com/android/internal/R_Hide$styleable:Window	Ltbox/RefStaticObject;
+    //   3: invokevirtual 219	tbox/RefStaticObject:get	()Ljava/lang/Object;
+    //   6: checkcast 221	[I
+    //   9: astore 9
+    //   11: getstatic 225	tbox/com/android/internal/R_Hide$styleable:Window_windowIsTranslucent	Ltbox/RefStaticInt;
+    //   14: invokevirtual 229	tbox/RefStaticInt:get	()I
+    //   17: istore 10
+    //   19: getstatic 232	tbox/com/android/internal/R_Hide$styleable:Window_windowIsFloating	Ltbox/RefStaticInt;
+    //   22: invokevirtual 229	tbox/RefStaticInt:get	()I
+    //   25: istore 11
+    //   27: getstatic 235	tbox/com/android/internal/R_Hide$styleable:Window_windowShowWallpaper	Ltbox/RefStaticInt;
+    //   30: invokevirtual 229	tbox/RefStaticInt:get	()I
+    //   33: istore 12
+    //   35: invokestatic 240	com/trigtech/privateme/server/am/h:a	()Lcom/trigtech/privateme/server/am/h;
+    //   38: aload_1
+    //   39: getfield 88	android/content/pm/ActivityInfo:packageName	Ljava/lang/String;
+    //   42: aload_1
+    //   43: getfield 243	android/content/pm/ActivityInfo:theme	I
+    //   46: aload 9
+    //   48: invokevirtual 246	com/trigtech/privateme/server/am/h:a	(Ljava/lang/String;I[I)Lcom/trigtech/privateme/server/am/h$a;
+    //   51: astore 13
+    //   53: aload 13
+    //   55: ifnull +154 -> 209
+    //   58: aload 13
+    //   60: getfield 251	com/trigtech/privateme/server/am/h$a:b	Landroid/content/res/TypedArray;
+    //   63: ifnull +146 -> 209
+    //   66: aload 13
+    //   68: getfield 251	com/trigtech/privateme/server/am/h$a:b	Landroid/content/res/TypedArray;
+    //   71: iload 12
+    //   73: iconst_0
+    //   74: invokevirtual 257	android/content/res/TypedArray:getBoolean	(IZ)Z
+    //   77: istore 14
+    //   79: iload 14
+    //   81: istore 5
+    //   83: aload 13
+    //   85: getfield 251	com/trigtech/privateme/server/am/h$a:b	Landroid/content/res/TypedArray;
+    //   88: iload 10
+    //   90: iconst_0
+    //   91: invokevirtual 257	android/content/res/TypedArray:getBoolean	(IZ)Z
+    //   94: istore 17
+    //   96: iload 17
+    //   98: istore 6
+    //   100: aload 13
+    //   102: getfield 251	com/trigtech/privateme/server/am/h$a:b	Landroid/content/res/TypedArray;
+    //   105: iload 11
+    //   107: iconst_0
+    //   108: invokevirtual 257	android/content/res/TypedArray:getBoolean	(IZ)Z
+    //   111: istore 19
+    //   113: iload 19
+    //   115: istore 7
+    //   117: iload 7
+    //   119: ifne +16 -> 135
+    //   122: iload 6
+    //   124: ifne +11 -> 135
+    //   127: iconst_0
+    //   128: istore 8
+    //   130: iload 5
+    //   132: ifeq +6 -> 138
+    //   135: iconst_1
+    //   136: istore 8
+    //   138: iload 8
+    //   140: ifeq +31 -> 171
+    //   143: iload_0
+    //   144: invokestatic 262	com/trigtech/privateme/client/stub/a:b	(I)Ljava/lang/String;
+    //   147: areturn
+    //   148: astore_2
+    //   149: iconst_0
+    //   150: istore_3
+    //   151: iconst_0
+    //   152: istore 4
+    //   154: aload_2
+    //   155: invokevirtual 265	java/lang/Throwable:printStackTrace	()V
+    //   158: iload_3
+    //   159: istore 5
+    //   161: iload 4
+    //   163: istore 6
+    //   165: iconst_0
+    //   166: istore 7
+    //   168: goto -51 -> 117
+    //   171: iload_0
+    //   172: invokestatic 267	com/trigtech/privateme/client/stub/a:a	(I)Ljava/lang/String;
+    //   175: areturn
+    //   176: astore 15
+    //   178: iload 5
+    //   180: istore 16
+    //   182: aload 15
+    //   184: astore_2
+    //   185: iload 16
+    //   187: istore_3
+    //   188: iconst_0
+    //   189: istore 4
+    //   191: goto -37 -> 154
+    //   194: astore 18
+    //   196: iload 6
+    //   198: istore 4
+    //   200: iload 5
+    //   202: istore_3
+    //   203: aload 18
+    //   205: astore_2
+    //   206: goto -52 -> 154
+    //   209: iconst_0
+    //   210: istore 5
+    //   212: iconst_0
+    //   213: istore 6
+    //   215: iconst_0
+    //   216: istore 7
+    //   218: goto -101 -> 117
+    //
+    // Exception table:
+    //   from	to	target	type
+    //   0	53	148	java/lang/Throwable
+    //   58	79	148	java/lang/Throwable
+    //   83	96	176	java/lang/Throwable
+    //   100	113	194	java/lang/Throwable
+  }
+
+  private void a()
+  {
+    ArrayList localArrayList = new ArrayList(this.c.getRecentTasks(2147483647, 3));
+    int i = this.a.size();
+    int j = i - 1;
+    p localp;
+    int k;
+    if (i > 0)
+    {
+      localp = (p)this.a.valueAt(j);
+      ListIterator localListIterator = localArrayList.listIterator();
+      while (localListIterator.hasNext())
+        if (((ActivityManager.RecentTaskInfo)localListIterator.next()).id == localp.a)
+        {
+          k = 1;
+          localListIterator.remove();
+        }
+    }
+    while (true)
+    {
+      if (k == 0)
+      {
+        this.a.removeAt(j);
+        b(localp);
+      }
+      i = j;
+      break;
+      return;
+      k = 0;
+    }
+  }
+
+  private static void a(Intent paramIntent, int paramInt)
+  {
+    paramIntent.setFlags(paramIntent.getFlags() & (paramInt ^ 0xFFFFFFFF));
+  }
+
+  private static boolean a(p paramp, ClearTarget paramClearTarget, ComponentName paramComponentName)
+  {
+    boolean bool1 = false;
+    boolean bool3;
+    switch (e.a[paramClearTarget.ordinal()])
+    {
+    default:
+      return false;
+    case 1:
+      synchronized (paramp.e)
+      {
+        Iterator localIterator2 = paramp.e.iterator();
+        while (localIterator2.hasNext())
+        {
+          ((c)localIterator2.next()).i = true;
+          bool1 = true;
+        }
+        return bool1;
+      }
+    case 2:
+      synchronized (paramp.e)
+      {
+        Iterator localIterator1 = paramp.e.iterator();
+        if (localIterator1.hasNext())
+        {
+          c localc = (c)localIterator1.next();
+          if (localc.b.equals(paramComponentName))
+          {
+            localc.i = true;
+            bool3 = true;
+            break label307;
+          }
+        }
+        else
+        {
+          return bool1;
+        }
+      }
+    case 3:
+    }
+    while (true)
+    {
+      int i;
+      int j;
+      boolean bool2;
+      int k;
+      synchronized (paramp.e)
+      {
+        i = paramp.e.size();
+        j = i - 1;
+        bool2 = false;
+        if (i <= 0)
+          break label313;
+        if (!((c)paramp.e.get(j)).b.equals(paramComponentName))
+          break label325;
+        bool2 = true;
+        break label313;
+        int m = k + 1;
+        if (k < -1 + paramp.e.size())
+        {
+          ((c)paramp.e.get(m)).i = true;
+          k = m;
+          continue;
+        }
+        return bool2;
+      }
+      bool3 = bool1;
+      label307: bool1 = bool3;
+      break;
+      label313: if (bool2)
+      {
+        k = j;
+        continue;
+        label325: i = j;
+      }
+    }
+  }
+
+  private p b(int paramInt, String paramString)
+  {
+    for (int i = 0; i < this.a.size(); i++)
+    {
+      p localp = (p)this.a.valueAt(i);
+      if ((paramInt == localp.b) && (paramString.equals(localp.c)))
+        return localp;
+    }
+    return null;
+  }
+
+  private void b()
+  {
+    int j;
+    for (int i = this.a.size(); ; i = j)
+    {
+      j = i - 1;
+      if (i <= 0)
+        break;
+      Iterator localIterator = ((p)this.a.valueAt(j)).e.iterator();
+      while (localIterator.hasNext())
+      {
+        c localc = (c)localIterator.next();
+        if (localc.i)
+          g.a().post(new d(this, localc));
+      }
+    }
+  }
+
+  private void b(p paramp)
+  {
+    Iterator localIterator1 = this.h.keySet().iterator();
+    while (localIterator1.hasNext())
+    {
+      Integer localInteger2 = (Integer)localIterator1.next();
+      List localList2 = (List)this.h.get(localInteger2);
+      Iterator localIterator4 = paramp.e.iterator();
+      while (localIterator4.hasNext())
+      {
+        c localc2 = (c)localIterator4.next();
+        if (localList2.contains(localc2))
+        {
+          v.a(b, "optimizeActivities started, activity: %s", new Object[] { localc2 });
+          localList2.remove(localc2);
+        }
+      }
+    }
+    Iterator localIterator2 = this.g.keySet().iterator();
+    while (localIterator2.hasNext())
+    {
+      Integer localInteger1 = (Integer)localIterator2.next();
+      List localList1 = (List)this.g.get(localInteger1);
+      Iterator localIterator3 = paramp.e.iterator();
+      while (localIterator3.hasNext())
+      {
+        c localc1 = (c)localIterator3.next();
+        if (localList1.contains(localc1))
+        {
+          v.a(b, "optimizeActivities resumed, activity: %s", new Object[] { localc1 });
+          localList1.remove(localc1);
+        }
+      }
+    }
+  }
+
+  private static boolean b(Intent paramIntent, int paramInt)
+  {
+    return (paramInt & paramIntent.getFlags()) != 0;
+  }
+
+  private List<c> e(int paramInt)
+  {
+    Object localObject = (List)this.g.get(Integer.valueOf(paramInt));
+    if (localObject == null)
+    {
+      localObject = new ArrayList();
+      this.g.put(Integer.valueOf(paramInt), localObject);
+    }
+    return localObject;
+  }
+
+  private f f(int paramInt)
+  {
+    f localf = (f)this.f.get(Integer.valueOf(paramInt));
+    if (localf == null)
+    {
+      localf = new f();
+      this.f.put(Integer.valueOf(paramInt), localf);
+    }
+    return localf;
+  }
+
+  // ERROR //
+  final int a(int paramInt1, Intent paramIntent, ActivityInfo paramActivityInfo, IBinder paramIBinder, android.os.Bundle paramBundle, String paramString, int paramInt2)
+  {
+    // Byte code:
+    //   0: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   3: astore 8
+    //   5: iconst_2
+    //   6: anewarray 4	java/lang/Object
+    //   9: astore 9
+    //   11: aload 9
+    //   13: iconst_0
+    //   14: aload_3
+    //   15: getfield 402	android/content/pm/ActivityInfo:name	Ljava/lang/String;
+    //   18: aastore
+    //   19: aload 9
+    //   21: iconst_1
+    //   22: aload 4
+    //   24: aastore
+    //   25: aload 8
+    //   27: ldc_w 404
+    //   30: aload 9
+    //   32: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   35: aload_0
+    //   36: invokespecial 406	com/trigtech/privateme/server/am/ActivityStack:a	()V
+    //   39: aload_0
+    //   40: iload_1
+    //   41: aload 4
+    //   43: invokevirtual 409	com/trigtech/privateme/server/am/ActivityStack:a	(ILandroid/os/IBinder;)Lcom/trigtech/privateme/server/am/c;
+    //   46: astore 10
+    //   48: aload 10
+    //   50: ifnull +594 -> 644
+    //   53: aload 10
+    //   55: getfield 412	com/trigtech/privateme/server/am/c:a	Lcom/trigtech/privateme/server/am/p;
+    //   58: astore 11
+    //   60: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   63: ldc_w 414
+    //   66: iconst_1
+    //   67: anewarray 4	java/lang/Object
+    //   70: dup
+    //   71: iconst_0
+    //   72: aload 11
+    //   74: aastore
+    //   75: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   78: getstatic 420	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:CURRENT	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   81: astore 12
+    //   83: getstatic 424	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:NOTHING	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   86: astore 13
+    //   88: aload_2
+    //   89: ldc_w 425
+    //   92: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   95: istore 14
+    //   97: aload_2
+    //   98: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   101: ifnonnull +36 -> 137
+    //   104: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   107: ldc_w 427
+    //   110: iconst_0
+    //   111: anewarray 4	java/lang/Object
+    //   114: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   117: aload_2
+    //   118: new 121	android/content/ComponentName
+    //   121: dup
+    //   122: aload_3
+    //   123: getfield 88	android/content/pm/ActivityInfo:packageName	Ljava/lang/String;
+    //   126: aload_3
+    //   127: getfield 402	android/content/pm/ActivityInfo:name	Ljava/lang/String;
+    //   130: invokespecial 430	android/content/ComponentName:<init>	(Ljava/lang/String;Ljava/lang/String;)V
+    //   133: invokevirtual 434	android/content/Intent:setComponent	(Landroid/content/ComponentName;)Landroid/content/Intent;
+    //   136: pop
+    //   137: aload 10
+    //   139: ifnull +33 -> 172
+    //   142: aload 10
+    //   144: getfield 436	com/trigtech/privateme/server/am/c:g	I
+    //   147: iconst_3
+    //   148: if_icmpne +24 -> 172
+    //   151: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   154: ldc_w 438
+    //   157: iconst_0
+    //   158: anewarray 4	java/lang/Object
+    //   161: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   164: aload_2
+    //   165: ldc_w 439
+    //   168: invokevirtual 139	android/content/Intent:addFlags	(I)Landroid/content/Intent;
+    //   171: pop
+    //   172: iload 14
+    //   174: ifeq +28 -> 202
+    //   177: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   180: ldc_w 441
+    //   183: iconst_0
+    //   184: anewarray 4	java/lang/Object
+    //   187: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   190: aload_2
+    //   191: ldc_w 442
+    //   194: invokestatic 444	com/trigtech/privateme/server/am/ActivityStack:a	(Landroid/content/Intent;I)V
+    //   197: getstatic 447	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:TOP	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   200: astore 13
+    //   202: aload_2
+    //   203: ldc_w 448
+    //   206: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   209: ifeq +31 -> 240
+    //   212: aload_2
+    //   213: ldc_w 439
+    //   216: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   219: ifeq +431 -> 650
+    //   222: getstatic 451	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:TASK	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   225: astore 13
+    //   227: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   230: ldc_w 453
+    //   233: iconst_0
+    //   234: anewarray 4	java/lang/Object
+    //   237: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   240: getstatic 458	android/os/Build$VERSION:SDK_INT	I
+    //   243: bipush 21
+    //   245: if_icmplt +31 -> 276
+    //   248: aload_3
+    //   249: getfield 461	android/content/pm/ActivityInfo:documentLaunchMode	I
+    //   252: tableswitch	default:+24 -> 276, 1:+421->673, 2:+434->686
+    //   277: getfield 464	android/content/pm/ActivityInfo:launchMode	I
+    //   280: tableswitch	default:+28 -> 308, 1:+414->694, 2:+466->746, 3:+509->789
+    //   309: ldc_w 465
+    //   312: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   315: ifeq +1290 -> 1605
+    //   318: aload 13
+    //   320: astore 19
+    //   322: aconst_null
+    //   323: astore 17
+    //   325: aload 12
+    //   327: astore 18
+    //   329: iconst_1
+    //   330: istore 20
+    //   332: aload 19
+    //   334: getstatic 424	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:NOTHING	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   337: if_acmpne +1261 -> 1598
+    //   340: aload_2
+    //   341: ldc_w 442
+    //   344: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   347: ifeq +1251 -> 1598
+    //   350: getstatic 468	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:SPEC_ACTIVITY	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   353: astore 21
+    //   355: aload 11
+    //   357: ifnonnull +16 -> 373
+    //   360: aload 18
+    //   362: getstatic 420	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:CURRENT	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   365: if_acmpne +8 -> 373
+    //   368: getstatic 471	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:AFFINITY	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   371: astore 18
+    //   373: aload_3
+    //   374: invokestatic 474	com/trigtech/privateme/helper/utils/k:a	(Landroid/content/pm/ActivityInfo;)Ljava/lang/String;
+    //   377: astore 22
+    //   379: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   382: ldc_w 476
+    //   385: iconst_2
+    //   386: anewarray 4	java/lang/Object
+    //   389: dup
+    //   390: iconst_0
+    //   391: aload 22
+    //   393: aastore
+    //   394: dup
+    //   395: iconst_1
+    //   396: aload 17
+    //   398: aastore
+    //   399: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   402: getstatic 478	com/trigtech/privateme/server/am/e:b	[I
+    //   405: aload 18
+    //   407: invokevirtual 479	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:ordinal	()I
+    //   410: iaload
+    //   411: istore 23
+    //   413: aconst_null
+    //   414: astore 24
+    //   416: iload 23
+    //   418: tableswitch	default:+26 -> 444, 1:+400->818, 2:+412->830, 3:+423->841
+    //   445: aconst_null
+    //   446: <illegal opcode>
+    //   447: aload 22
+    //   449: invokevirtual 338	java/lang/String:equals	(Ljava/lang/Object;)Z
+    //   452: ifeq +19 -> 471
+    //   455: aload_0
+    //   456: getfield 40	com/trigtech/privateme/server/am/ActivityStack:e	Lcom/trigtech/privateme/helper/utils/a;
+    //   459: iload_1
+    //   460: invokestatic 385	java/lang/Integer:valueOf	(I)Ljava/lang/Integer;
+    //   463: invokevirtual 366	com/trigtech/privateme/helper/utils/a:get	(Ljava/lang/Object;)Ljava/lang/Object;
+    //   466: checkcast 177	com/trigtech/privateme/server/am/p
+    //   469: astore 24
+    //   471: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   474: ldc_w 483
+    //   477: iconst_1
+    //   478: anewarray 4	java/lang/Object
+    //   481: dup
+    //   482: iconst_0
+    //   483: aload 24
+    //   485: aastore
+    //   486: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   489: aload 24
+    //   491: ifnonnull +383 -> 874
+    //   494: invokestatic 489	android/os/SystemClock:elapsedRealtime	()J
+    //   497: lstore 53
+    //   499: aload_0
+    //   500: iload_1
+    //   501: aconst_null
+    //   502: aload_2
+    //   503: aload_3
+    //   504: invokespecial 491	com/trigtech/privateme/server/am/ActivityStack:a	(ILcom/trigtech/privateme/server/am/c;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;)Landroid/content/Intent;
+    //   507: astore 55
+    //   509: aload 55
+    //   511: ifnull +68 -> 579
+    //   514: aload 55
+    //   516: ldc_w 439
+    //   519: invokevirtual 139	android/content/Intent:addFlags	(I)Landroid/content/Intent;
+    //   522: pop
+    //   523: aload 55
+    //   525: ldc_w 492
+    //   528: invokevirtual 139	android/content/Intent:addFlags	(I)Landroid/content/Intent;
+    //   531: pop
+    //   532: aload 55
+    //   534: ldc_w 493
+    //   537: invokevirtual 139	android/content/Intent:addFlags	(I)Landroid/content/Intent;
+    //   540: pop
+    //   541: getstatic 458	android/os/Build$VERSION:SDK_INT	I
+    //   544: bipush 21
+    //   546: if_icmpge +302 -> 848
+    //   549: aload 55
+    //   551: ldc_w 494
+    //   554: invokevirtual 139	android/content/Intent:addFlags	(I)Landroid/content/Intent;
+    //   557: pop
+    //   558: getstatic 458	android/os/Build$VERSION:SDK_INT	I
+    //   561: bipush 16
+    //   563: if_icmplt +297 -> 860
+    //   566: invokestatic 58	com/trigtech/privateme/client/AppInterface:e	()Lcom/trigtech/privateme/client/AppInterface;
+    //   569: invokevirtual 62	com/trigtech/privateme/client/AppInterface:i	()Landroid/content/Context;
+    //   572: aload 55
+    //   574: aload 5
+    //   576: invokevirtual 498	android/content/Context:startActivity	(Landroid/content/Intent;Landroid/os/Bundle;)V
+    //   579: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   582: astore 56
+    //   584: iconst_1
+    //   585: anewarray 4	java/lang/Object
+    //   588: astore 57
+    //   590: aload 57
+    //   592: iconst_0
+    //   593: invokestatic 489	android/os/SystemClock:elapsedRealtime	()J
+    //   596: lload 53
+    //   598: lsub
+    //   599: invokestatic 503	java/lang/Long:valueOf	(J)Ljava/lang/Long;
+    //   602: aastore
+    //   603: aload 56
+    //   605: ldc_w 505
+    //   608: aload 57
+    //   610: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   613: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   616: astore 31
+    //   618: iconst_1
+    //   619: anewarray 4	java/lang/Object
+    //   622: astore 32
+    //   624: aload 32
+    //   626: iconst_0
+    //   627: aload_3
+    //   628: getfield 402	android/content/pm/ActivityInfo:name	Ljava/lang/String;
+    //   631: aastore
+    //   632: aload 31
+    //   634: ldc_w 507
+    //   637: aload 32
+    //   639: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   642: iconst_0
+    //   643: ireturn
+    //   644: aconst_null
+    //   645: astore 11
+    //   647: goto -587 -> 60
+    //   650: aload_2
+    //   651: ldc_w 448
+    //   654: invokestatic 444	com/trigtech/privateme/server/am/ActivityStack:a	(Landroid/content/Intent;I)V
+    //   657: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   660: ldc_w 509
+    //   663: iconst_0
+    //   664: anewarray 4	java/lang/Object
+    //   667: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   670: goto -430 -> 240
+    //   673: getstatic 451	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:TASK	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   676: astore 13
+    //   678: getstatic 512	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:DOCUMENT	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   681: astore 12
+    //   683: goto -407 -> 276
+    //   686: getstatic 515	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:MULTIPLE	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   689: astore 12
+    //   691: goto -415 -> 276
+    //   694: aload_2
+    //   695: ldc_w 439
+    //   698: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   701: ifeq +18 -> 719
+    //   704: aload_2
+    //   705: ldc_w 492
+    //   708: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   711: ifeq +27 -> 738
+    //   714: getstatic 515	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:MULTIPLE	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   717: astore 12
+    //   719: aload 13
+    //   721: astore 19
+    //   723: ldc_w 517
+    //   726: astore 17
+    //   728: aload 12
+    //   730: astore 18
+    //   732: iconst_1
+    //   733: istore 20
+    //   735: goto -403 -> 332
+    //   738: getstatic 471	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:AFFINITY	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   741: astore 12
+    //   743: goto -24 -> 719
+    //   746: getstatic 447	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:TOP	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   749: astore 19
+    //   751: aload_2
+    //   752: ldc_w 492
+    //   755: invokestatic 135	com/trigtech/privateme/server/am/ActivityStack:b	(Landroid/content/Intent;I)Z
+    //   758: ifeq +23 -> 781
+    //   761: getstatic 515	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:MULTIPLE	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   764: astore 63
+    //   766: aload 63
+    //   768: astore 18
+    //   770: ldc_w 519
+    //   773: astore 17
+    //   775: iconst_0
+    //   776: istore 20
+    //   778: goto -446 -> 332
+    //   781: getstatic 471	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:AFFINITY	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   784: astore 63
+    //   786: goto -20 -> 766
+    //   789: getstatic 447	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:TOP	Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;
+    //   792: astore 15
+    //   794: getstatic 471	com/trigtech/privateme/server/am/ActivityStack$ReuseTarget:AFFINITY	Lcom/trigtech/privateme/server/am/ActivityStack$ReuseTarget;
+    //   797: astore 16
+    //   799: ldc_w 521
+    //   802: astore 17
+    //   804: aload 16
+    //   806: astore 18
+    //   808: aload 15
+    //   810: astore 19
+    //   812: iconst_0
+    //   813: istore 20
+    //   815: goto -483 -> 332
+    //   818: aload_0
+    //   819: iload_1
+    //   820: aload 22
+    //   822: invokespecial 523	com/trigtech/privateme/server/am/ActivityStack:b	(ILjava/lang/String;)Lcom/trigtech/privateme/server/am/p;
+    //   825: astore 24
+    //   827: goto -383 -> 444
+    //   830: aload_0
+    //   831: iload_1
+    //   832: aload_2
+    //   833: invokespecial 525	com/trigtech/privateme/server/am/ActivityStack:a	(ILandroid/content/Intent;)Lcom/trigtech/privateme/server/am/p;
+    //   836: astore 24
+    //   838: goto -394 -> 444
+    //   841: aload 11
+    //   843: astore 24
+    //   845: goto -401 -> 444
+    //   848: aload 55
+    //   850: ldc_w 494
+    //   853: invokevirtual 139	android/content/Intent:addFlags	(I)Landroid/content/Intent;
+    //   856: pop
+    //   857: goto -299 -> 558
+    //   860: invokestatic 58	com/trigtech/privateme/client/AppInterface:e	()Lcom/trigtech/privateme/client/AppInterface;
+    //   863: invokevirtual 62	com/trigtech/privateme/client/AppInterface:i	()Landroid/content/Context;
+    //   866: aload 55
+    //   868: invokevirtual 527	android/content/Context:startActivity	(Landroid/content/Intent;)V
+    //   871: goto -292 -> 579
+    //   874: aload_0
+    //   875: getfield 74	com/trigtech/privateme/server/am/ActivityStack:c	Landroid/app/ActivityManager;
+    //   878: aload 24
+    //   880: getfield 297	com/trigtech/privateme/server/am/p:a	I
+    //   883: iconst_0
+    //   884: invokevirtual 531	android/app/ActivityManager:moveTaskToFront	(II)V
+    //   887: iload 14
+    //   889: ifne +654 -> 1543
+    //   892: aload 24
+    //   894: getfield 202	com/trigtech/privateme/server/am/p:d	Landroid/content/Intent;
+    //   897: astore 49
+    //   899: aload_2
+    //   900: ifnull +637 -> 1537
+    //   903: aload 49
+    //   905: ifnull +632 -> 1537
+    //   908: aload_2
+    //   909: invokevirtual 534	android/content/Intent:getAction	()Ljava/lang/String;
+    //   912: aload 49
+    //   914: invokevirtual 534	android/content/Intent:getAction	()Ljava/lang/String;
+    //   917: invokestatic 539	com/trigtech/privateme/helper/a/f:a	(Ljava/lang/Object;Ljava/lang/Object;)Z
+    //   920: ifne +460 -> 1380
+    //   923: iconst_0
+    //   924: istore 50
+    //   926: iload 50
+    //   928: ifeq +615 -> 1543
+    //   931: iconst_1
+    //   932: istore 25
+    //   934: aload 24
+    //   936: aload 11
+    //   938: if_acmpne +653 -> 1591
+    //   941: aload 24
+    //   943: invokevirtual 541	com/trigtech/privateme/server/am/p:a	()Z
+    //   946: ifne +645 -> 1591
+    //   949: iconst_0
+    //   950: istore 26
+    //   952: aload 21
+    //   954: getfield 544	com/trigtech/privateme/server/am/ActivityStack$ClearTarget:deliverIntent	Z
+    //   957: ifne +11 -> 968
+    //   960: iconst_0
+    //   961: istore 27
+    //   963: iload 20
+    //   965: ifeq +620 -> 1585
+    //   968: aload 24
+    //   970: aload 21
+    //   972: aload_2
+    //   973: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   976: invokestatic 546	com/trigtech/privateme/server/am/ActivityStack:a	(Lcom/trigtech/privateme/server/am/p;Lcom/trigtech/privateme/server/am/ActivityStack$ClearTarget;Landroid/content/ComponentName;)Z
+    //   979: istore 27
+    //   981: aload 24
+    //   983: invokestatic 548	com/trigtech/privateme/server/am/ActivityStack:a	(Lcom/trigtech/privateme/server/am/p;)Lcom/trigtech/privateme/server/am/c;
+    //   986: astore 45
+    //   988: iload 14
+    //   990: ifeq +24 -> 1014
+    //   993: iload 20
+    //   995: ifne +19 -> 1014
+    //   998: aload 45
+    //   1000: ifnull +14 -> 1014
+    //   1003: iload 27
+    //   1005: ifeq +9 -> 1014
+    //   1008: aload 45
+    //   1010: iconst_1
+    //   1011: putfield 193	com/trigtech/privateme/server/am/c:i	Z
+    //   1014: aload 45
+    //   1016: ifnull +569 -> 1585
+    //   1019: aload 45
+    //   1021: getfield 193	com/trigtech/privateme/server/am/c:i	Z
+    //   1024: ifne +561 -> 1585
+    //   1027: aload 45
+    //   1029: getfield 144	com/trigtech/privateme/server/am/c:b	Landroid/content/ComponentName;
+    //   1032: aload_2
+    //   1033: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   1036: invokevirtual 206	android/content/ComponentName:equals	(Ljava/lang/Object;)Z
+    //   1039: ifeq +546 -> 1585
+    //   1042: aload 45
+    //   1044: ifnull +39 -> 1083
+    //   1047: aload 10
+    //   1049: ifnull +500 -> 1549
+    //   1052: aload 10
+    //   1054: getfield 144	com/trigtech/privateme/server/am/c:b	Landroid/content/ComponentName;
+    //   1057: invokevirtual 551	android/content/ComponentName:getPackageName	()Ljava/lang/String;
+    //   1060: astore 46
+    //   1062: aload 45
+    //   1064: getfield 554	com/trigtech/privateme/server/am/c:f	Lcom/trigtech/privateme/server/am/j;
+    //   1067: getfield 557	com/trigtech/privateme/server/am/j:e	Lcom/trigtech/privateme/client/AppClient;
+    //   1070: aload 46
+    //   1072: aload 45
+    //   1074: getfield 560	com/trigtech/privateme/server/am/c:d	Landroid/os/IBinder;
+    //   1077: aload_2
+    //   1078: invokeinterface 566 4 0
+    //   1083: iconst_1
+    //   1084: istore 28
+    //   1086: iload 27
+    //   1088: ifeq +19 -> 1107
+    //   1091: aload_0
+    //   1092: getfield 45	com/trigtech/privateme/server/am/ActivityStack:a	Landroid/util/SparseArray;
+    //   1095: astore 43
+    //   1097: aload 43
+    //   1099: monitorenter
+    //   1100: aload_0
+    //   1101: invokespecial 568	com/trigtech/privateme/server/am/ActivityStack:b	()V
+    //   1104: aload 43
+    //   1106: monitorexit
+    //   1107: iload 26
+    //   1109: ifne -496 -> 613
+    //   1112: iload 28
+    //   1114: ifne -501 -> 613
+    //   1117: aload_0
+    //   1118: iload_1
+    //   1119: aload 10
+    //   1121: aload_2
+    //   1122: aload_3
+    //   1123: invokespecial 491	com/trigtech/privateme/server/am/ActivityStack:a	(ILcom/trigtech/privateme/server/am/c;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;)Landroid/content/Intent;
+    //   1126: astore 29
+    //   1128: aload 29
+    //   1130: ifnull -517 -> 613
+    //   1133: aload 24
+    //   1135: invokestatic 548	com/trigtech/privateme/server/am/ActivityStack:a	(Lcom/trigtech/privateme/server/am/p;)Lcom/trigtech/privateme/server/am/c;
+    //   1138: astore 30
+    //   1140: aload 30
+    //   1142: ifnull +222 -> 1364
+    //   1145: aload_0
+    //   1146: aload 24
+    //   1148: getfield 200	com/trigtech/privateme/server/am/p:b	I
+    //   1151: aload 30
+    //   1153: aload 29
+    //   1155: aload_3
+    //   1156: invokespecial 491	com/trigtech/privateme/server/am/ActivityStack:a	(ILcom/trigtech/privateme/server/am/c;Landroid/content/Intent;Landroid/content/pm/ActivityInfo;)Landroid/content/Intent;
+    //   1159: ifnull +205 -> 1364
+    //   1162: aload 30
+    //   1164: getfield 560	com/trigtech/privateme/server/am/c:d	Landroid/os/IBinder;
+    //   1167: astore 33
+    //   1169: getstatic 573	tbox/android/app/IActivityManager:startActivity	Ltbox/RefMethod;
+    //   1172: invokevirtual 579	tbox/RefMethod:paramList	()[Ljava/lang/Class;
+    //   1175: astore 34
+    //   1177: aload 34
+    //   1179: arraylength
+    //   1180: anewarray 4	java/lang/Object
+    //   1183: astore 35
+    //   1185: aload 34
+    //   1187: iconst_0
+    //   1188: aaload
+    //   1189: getstatic 585	tbox/android/app/IApplicationThread:TYPE	Ljava/lang/Class;
+    //   1192: if_acmpne +20 -> 1212
+    //   1195: aload 35
+    //   1197: iconst_0
+    //   1198: getstatic 590	tbox/android/app/ActivityThread:getApplicationThread	Ltbox/RefMethod;
+    //   1201: invokestatic 592	com/trigtech/privateme/client/AppInterface:g	()Ljava/lang/Object;
+    //   1204: iconst_0
+    //   1205: anewarray 4	java/lang/Object
+    //   1208: invokevirtual 596	tbox/RefMethod:call	(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+    //   1211: aastore
+    //   1212: aload 34
+    //   1214: ldc 77
+    //   1216: invokestatic 601	com/trigtech/privateme/helper/utils/e:a	([Ljava/lang/Class;Ljava/lang/Class;)I
+    //   1219: istore 36
+    //   1221: aload 34
+    //   1223: ldc_w 603
+    //   1226: iconst_2
+    //   1227: invokestatic 606	com/trigtech/privateme/helper/utils/e:a	([Ljava/lang/Class;Ljava/lang/Class;I)I
+    //   1230: istore 37
+    //   1232: aload 34
+    //   1234: ldc_w 608
+    //   1237: invokestatic 601	com/trigtech/privateme/helper/utils/e:a	([Ljava/lang/Class;Ljava/lang/Class;)I
+    //   1240: istore 38
+    //   1242: iload 36
+    //   1244: iconst_1
+    //   1245: iadd
+    //   1246: istore 39
+    //   1248: iload 37
+    //   1250: iconst_1
+    //   1251: iadd
+    //   1252: istore 40
+    //   1254: iload 37
+    //   1256: iconst_2
+    //   1257: iadd
+    //   1258: istore 41
+    //   1260: aload 35
+    //   1262: iload 36
+    //   1264: aload 29
+    //   1266: aastore
+    //   1267: aload 35
+    //   1269: iload 37
+    //   1271: aload 33
+    //   1273: aastore
+    //   1274: aload 35
+    //   1276: iload 40
+    //   1278: aload 6
+    //   1280: aastore
+    //   1281: aload 35
+    //   1283: iload 41
+    //   1285: iload 7
+    //   1287: invokestatic 385	java/lang/Integer:valueOf	(I)Ljava/lang/Integer;
+    //   1290: aastore
+    //   1291: iload 38
+    //   1293: iconst_m1
+    //   1294: if_icmpeq +10 -> 1304
+    //   1297: aload 35
+    //   1299: iload 38
+    //   1301: aload 5
+    //   1303: aastore
+    //   1304: aload 35
+    //   1306: iload 39
+    //   1308: aload 29
+    //   1310: invokevirtual 611	android/content/Intent:getType	()Ljava/lang/String;
+    //   1313: aastore
+    //   1314: getstatic 458	android/os/Build$VERSION:SDK_INT	I
+    //   1317: bipush 18
+    //   1319: if_icmplt +16 -> 1335
+    //   1322: aload 35
+    //   1324: iload 36
+    //   1326: iconst_1
+    //   1327: isub
+    //   1328: invokestatic 58	com/trigtech/privateme/client/AppInterface:e	()Lcom/trigtech/privateme/client/AppInterface;
+    //   1331: invokevirtual 98	com/trigtech/privateme/client/AppInterface:k	()Ljava/lang/String;
+    //   1334: aastore
+    //   1335: aload 34
+    //   1337: aload 35
+    //   1339: invokestatic 616	com/trigtech/privateme/helper/utils/i:a	([Ljava/lang/Class;[Ljava/lang/Object;)V
+    //   1342: getstatic 573	tbox/android/app/IActivityManager:startActivity	Ltbox/RefMethod;
+    //   1345: getstatic 622	tbox/android/app/ActivityManagerNative:getDefault	Ltbox/RefStaticMethod;
+    //   1348: iconst_0
+    //   1349: anewarray 4	java/lang/Object
+    //   1352: invokevirtual 627	tbox/RefStaticMethod:call	([Ljava/lang/Object;)Ljava/lang/Object;
+    //   1355: aload 35
+    //   1357: checkcast 629	[Ljava/lang/Object;
+    //   1360: invokevirtual 596	tbox/RefMethod:call	(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
+    //   1363: pop
+    //   1364: getstatic 31	com/trigtech/privateme/server/am/ActivityStack:b	Ljava/lang/String;
+    //   1367: ldc_w 631
+    //   1370: iconst_0
+    //   1371: anewarray 4	java/lang/Object
+    //   1374: invokestatic 376	com/trigtech/privateme/helper/utils/v:a	(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+    //   1377: goto -764 -> 613
+    //   1380: aload_2
+    //   1381: invokevirtual 635	android/content/Intent:getData	()Landroid/net/Uri;
+    //   1384: aload 49
+    //   1386: invokevirtual 635	android/content/Intent:getData	()Landroid/net/Uri;
+    //   1389: invokestatic 539	com/trigtech/privateme/helper/a/f:a	(Ljava/lang/Object;Ljava/lang/Object;)Z
+    //   1392: ifne +9 -> 1401
+    //   1395: iconst_0
+    //   1396: istore 50
+    //   1398: goto -472 -> 926
+    //   1401: aload_2
+    //   1402: invokevirtual 611	android/content/Intent:getType	()Ljava/lang/String;
+    //   1405: aload 49
+    //   1407: invokevirtual 611	android/content/Intent:getType	()Ljava/lang/String;
+    //   1410: invokestatic 539	com/trigtech/privateme/helper/a/f:a	(Ljava/lang/Object;Ljava/lang/Object;)Z
+    //   1413: ifne +9 -> 1422
+    //   1416: iconst_0
+    //   1417: istore 50
+    //   1419: goto -493 -> 926
+    //   1422: aload_2
+    //   1423: invokevirtual 638	android/content/Intent:getPackage	()Ljava/lang/String;
+    //   1426: astore 51
+    //   1428: aload 51
+    //   1430: ifnonnull +19 -> 1449
+    //   1433: aload_2
+    //   1434: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   1437: ifnull +12 -> 1449
+    //   1440: aload_2
+    //   1441: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   1444: invokevirtual 551	android/content/ComponentName:getPackageName	()Ljava/lang/String;
+    //   1447: astore 51
+    //   1449: aload 49
+    //   1451: invokevirtual 638	android/content/Intent:getPackage	()Ljava/lang/String;
+    //   1454: astore 52
+    //   1456: aload 52
+    //   1458: ifnonnull +21 -> 1479
+    //   1461: aload 49
+    //   1463: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   1466: ifnull +13 -> 1479
+    //   1469: aload 49
+    //   1471: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   1474: invokevirtual 551	android/content/ComponentName:getPackageName	()Ljava/lang/String;
+    //   1477: astore 52
+    //   1479: aload 51
+    //   1481: aload 52
+    //   1483: invokestatic 539	com/trigtech/privateme/helper/a/f:a	(Ljava/lang/Object;Ljava/lang/Object;)Z
+    //   1486: ifne +9 -> 1495
+    //   1489: iconst_0
+    //   1490: istore 50
+    //   1492: goto -566 -> 926
+    //   1495: aload_2
+    //   1496: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   1499: aload 49
+    //   1501: invokevirtual 114	android/content/Intent:getComponent	()Landroid/content/ComponentName;
+    //   1504: invokestatic 539	com/trigtech/privateme/helper/a/f:a	(Ljava/lang/Object;Ljava/lang/Object;)Z
+    //   1507: ifne +9 -> 1516
+    //   1510: iconst_0
+    //   1511: istore 50
+    //   1513: goto -587 -> 926
+    //   1516: aload_2
+    //   1517: invokevirtual 641	android/content/Intent:getCategories	()Ljava/util/Set;
+    //   1520: aload 49
+    //   1522: invokevirtual 641	android/content/Intent:getCategories	()Ljava/util/Set;
+    //   1525: invokestatic 539	com/trigtech/privateme/helper/a/f:a	(Ljava/lang/Object;Ljava/lang/Object;)Z
+    //   1528: ifne +9 -> 1537
+    //   1531: iconst_0
+    //   1532: istore 50
+    //   1534: goto -608 -> 926
+    //   1537: iconst_1
+    //   1538: istore 50
+    //   1540: goto -614 -> 926
+    //   1543: iconst_0
+    //   1544: istore 25
+    //   1546: goto -612 -> 934
+    //   1549: ldc_w 643
+    //   1552: astore 46
+    //   1554: goto -492 -> 1062
+    //   1557: astore 48
+    //   1559: aload 48
+    //   1561: invokevirtual 644	android/os/RemoteException:printStackTrace	()V
+    //   1564: goto -481 -> 1083
+    //   1567: astore 47
+    //   1569: aload 47
+    //   1571: invokevirtual 645	java/lang/NullPointerException:printStackTrace	()V
+    //   1574: goto -491 -> 1083
+    //   1577: astore 44
+    //   1579: aload 43
+    //   1581: monitorexit
+    //   1582: aload 44
+    //   1584: athrow
+    //   1585: iconst_0
+    //   1586: istore 28
+    //   1588: goto -502 -> 1086
+    //   1591: iload 25
+    //   1593: istore 26
+    //   1595: goto -643 -> 952
+    //   1598: aload 19
+    //   1600: astore 21
+    //   1602: goto -1247 -> 355
+    //   1605: aload 13
+    //   1607: astore 19
+    //   1609: aload 12
+    //   1611: astore 18
+    //   1613: aconst_null
+    //   1614: astore 17
+    //   1616: iconst_0
+    //   1617: istore 20
+    //   1619: goto -1287 -> 332
+    //
+    // Exception table:
+    //   from	to	target	type
+    //   1062	1083	1557	android/os/RemoteException
+    //   1062	1083	1567	java/lang/NullPointerException
+    //   1100	1107	1577	finally
+    //   1579	1582	1577	finally
+  }
+
+  final c a(int paramInt)
+  {
+    List localList = e(paramInt);
+    if (!localList.isEmpty())
+      return (c)localList.get(-1 + localList.size());
+    return null;
+  }
+
+  final c a(int paramInt, IBinder paramIBinder)
+  {
+    Object localObject1 = null;
+    if (paramIBinder != null);
+    for (int i = 0; ; i++)
+    {
+      p localp;
+      if (i < this.a.size())
+      {
+        localp = (p)this.a.valueAt(i);
+        if (localp.b != paramInt);
+      }
+      else
+      {
+        while (true)
+        {
+          synchronized (localp.e)
+          {
+            Iterator localIterator = localp.e.iterator();
+            if (localIterator.hasNext())
+            {
+              localObject3 = (c)localIterator.next();
+              if (((c)localObject3).d != paramIBinder)
+                break label116;
+              break label119;
+            }
+          }
+          return localObject1;
+        }
+      }
+    }
+  }
+
+  final void a(int paramInt, String paramString)
+  {
+    if (paramInt != -1)
+      f(paramInt).a(paramString);
+    while (true)
+    {
+      return;
+      Iterator localIterator = this.f.keySet().iterator();
+      while (localIterator.hasNext())
+        f(((Integer)localIterator.next()).intValue()).a(paramString);
+    }
+  }
+
+  final void a(j paramj)
+  {
+    while (true)
+    {
+      int j;
+      synchronized (this.a)
+      {
+        a();
+        i = this.a.size();
+        j = i - 1;
+        if (i <= 0)
+          break;
+        p localp = (p)this.a.valueAt(j);
+        synchronized (localp.e)
+        {
+          Iterator localIterator = localp.e.iterator();
+          if (localIterator.hasNext())
+          {
+            c localc = (c)localIterator.next();
+            if (localc.f.g != paramj.g)
+              continue;
+            localIterator.remove();
+            if (localp.e.isEmpty())
+              this.a.remove(localp.a);
+            this.g.remove(localc);
+          }
+        }
+      }
+      int i = j;
+    }
+  }
+
+  final void a(j paramj, ComponentName paramComponentName1, ComponentName paramComponentName2, IBinder paramIBinder, Intent paramIntent, String paramString, int paramInt1, int paramInt2, int paramInt3)
+  {
+    v.a(b, "onActivityCreated>>>>>>>>>>>>>>>token: %s", new Object[] { paramIBinder });
+    while (true)
+    {
+      p localp1;
+      synchronized (this.a)
+      {
+        a();
+        localp1 = (p)this.a.get(paramInt1);
+        if (localp1 == null)
+        {
+          localp2 = new p(paramInt1, paramj.j, paramString, paramIntent);
+          this.a.put(paramInt1, localp2);
+          c localc = new c(localp2, paramComponentName1, paramComponentName2, paramIBinder, paramj.j, paramj, paramInt2, paramInt3, paramString);
+          synchronized (localp2.e)
+          {
+            localp2.e.add(localc);
+            return;
+          }
+        }
+      }
+      p localp2 = localp1;
+    }
+  }
+
+  final List<c> b(int paramInt)
+  {
+    Object localObject = (List)this.h.get(Integer.valueOf(paramInt));
+    if (localObject == null)
+    {
+      localObject = new ArrayList();
+      this.h.put(Integer.valueOf(paramInt), localObject);
+    }
+    return localObject;
+  }
+
+  final void b(int paramInt, IBinder paramIBinder)
+  {
+    v.a(b, "onActivityResumed>>>>>>>>>>>>>>>token: %s", new Object[] { paramIBinder });
+    synchronized (this.a)
+    {
+      a();
+      c localc = a(paramInt, paramIBinder);
+      v.a(b, "onActivityResumed, r: %s", new Object[] { localc });
+      if (localc != null)
+        if (localc.b != null)
+        {
+          a.a();
+          a.a(localc.b.getPackageName());
+          f localf = f(paramInt);
+          String str = localc.b.getPackageName();
+          localf.a(AppInterface.e().b(str));
+        }
+      synchronized (localc.a.e)
+      {
+        localc.a.e.remove(localc);
+        localc.a.e.add(localc);
+        this.e.put(Integer.valueOf(paramInt), localc.a);
+        List localList2 = e(paramInt);
+        if (!localList2.contains(localc))
+        {
+          v.a(b, "onActivityResumed, add r: %s", new Object[] { localc });
+          localList2.add(localc);
+        }
+        return;
+      }
+    }
+  }
+
+  final List<AppSetting> c(int paramInt)
+  {
+    return f(paramInt).a();
+  }
+
+  final void c(int paramInt, IBinder paramIBinder)
+  {
+    v.a(b, "onActivityStarted>>>>>>>>>>>>>>>token: %s", new Object[] { paramIBinder });
+    synchronized (this.a)
+    {
+      a();
+      c localc = a(paramInt, paramIBinder);
+      v.a(b, "onActivityStarted, r: %s", new Object[] { localc });
+      List localList = b(paramInt);
+      if ((localc != null) && (!localList.contains(localc)))
+      {
+        localList.add(localc);
+        v.a(b, "onActivityStarted, add r: %s", new Object[] { localc });
+      }
+      return;
+    }
+  }
+
+  final AppTaskInfo d(int paramInt)
+  {
+    synchronized (this.a)
+    {
+      p localp = (p)this.a.get(paramInt);
+      if (localp != null)
+      {
+        int i = localp.e.size();
+        if (i <= 0);
+        ComponentName localComponentName;
+        for (AppTaskInfo localAppTaskInfo = null; ; localAppTaskInfo = new AppTaskInfo(localp.a, localp.d, localp.d.getComponent(), localComponentName))
+        {
+          return localAppTaskInfo;
+          localComponentName = ((c)localp.e.get(i - 1)).b;
+        }
+      }
+      return null;
+    }
+  }
+
+  final void d(int paramInt, IBinder paramIBinder)
+  {
+    v.a(b, "onActivityPaused>>>>>>>>>>>>>>>token: %s", new Object[] { paramIBinder });
+    synchronized (this.a)
+    {
+      a();
+      c localc = a(paramInt, paramIBinder);
+      v.a(b, "onActivityPaused, r: %s", new Object[] { localc });
+      List localList = e(paramInt);
+      if ((localc != null) && (localList.contains(localc)))
+      {
+        localList.remove(localc);
+        v.a(b, "onActivityPaused, remove r: %s", new Object[] { localc });
+      }
+      return;
+    }
+  }
+
+  final void e(int paramInt, IBinder paramIBinder)
+  {
+    v.a(b, "onActivityStopped>>>>>>>>>>>>>>>token: %s", new Object[] { paramIBinder });
+    synchronized (this.a)
+    {
+      a();
+      c localc = a(paramInt, paramIBinder);
+      v.a(b, "onActivityStopped, r: %s", new Object[] { localc });
+      List localList = b(paramInt);
+      if ((localc != null) && (localList.contains(localc)))
+      {
+        localList.remove(localc);
+        v.a(b, "onActivityStopped, remove r: %s", new Object[] { localc });
+      }
+      return;
+    }
+  }
+
+  final boolean f(int paramInt, IBinder paramIBinder)
+  {
+    v.a(b, "onActivityDestroyed>>>>>>>>>>>>>>>token: %s", new Object[] { paramIBinder });
+    synchronized (this.a)
+    {
+      c localc = a(paramInt, paramIBinder);
+      v.a(b, "onActivityDestroyed, r: %s", new Object[] { localc });
+      if (localc != null);
+      synchronized (localc.a.e)
+      {
+        localc.a.e.remove(localc);
+        List localList2 = e(paramInt);
+        if (localList2.contains(localc))
+        {
+          localList2.remove(localc);
+          v.a(b, "onActivityDestroyed, remove resumed r: %s", new Object[] { localc });
+        }
+        List localList3 = b(paramInt);
+        if (localList3.contains(localc))
+        {
+          localList3.remove(localc);
+          v.a(b, "onActivityDestroyed, remove started r: %s", new Object[] { localc });
+        }
+        a();
+        return false;
+      }
+    }
+  }
+
+  final String g(int paramInt, IBinder paramIBinder)
+  {
+    synchronized (this.a)
+    {
+      c localc = a(paramInt, paramIBinder);
+      if (localc != null)
+      {
+        String str = localc.b.getPackageName();
+        return str;
+      }
+      return null;
+    }
+  }
+
+  final ComponentName h(int paramInt, IBinder paramIBinder)
+  {
+    synchronized (this.a)
+    {
+      c localc = a(paramInt, paramIBinder);
+      if (localc != null)
+      {
+        ComponentName localComponentName = localc.c;
+        return localComponentName;
+      }
+      return null;
+    }
+  }
+
+  public final String i(int paramInt, IBinder paramIBinder)
+  {
+    synchronized (this.a)
+    {
+      c localc = a(paramInt, paramIBinder);
+      if (localc != null)
+      {
+        ComponentName localComponentName = localc.c;
+        String str = null;
+        if (localComponentName != null)
+          str = localc.c.getPackageName();
+        return str;
+      }
+      return null;
+    }
+  }
+
+  final ComponentName j(int paramInt, IBinder paramIBinder)
+  {
+    synchronized (this.a)
+    {
+      c localc = a(paramInt, paramIBinder);
+      if (localc != null)
+      {
+        ComponentName localComponentName = localc.b;
+        return localComponentName;
+      }
+      return null;
+    }
+  }
+
+
+}
+
+/* Location:
+ * Qualified Name:     com.trigtech.privateme.server.am.ActivityStack
+ * Java Class Version: 6 (50.0)
+ * JD-Core Version:    0.6.1-SNAPSHOT
+ */
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting.java.txt
new file mode 100644
index 0000000..400c026
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting.java.txt
@@ -0,0 +1,26 @@
+package com.github.javaparser.examples;
+
+
+/**
+ * A class with some uncommon formatting, to check the lexical preservation
+ */
+public class
+ASimpleClass
+{
+
+    boolean aField;
+
+    public ASimpleClass(boolean aField)
+    {
+        this.aField = aField;
+    }
+
+
+    // Some empty lines
+
+
+    public boolean getAField()
+    {
+        return aField;
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step1.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step1.java.txt
new file mode 100644
index 0000000..0ce70e6
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step1.java.txt
@@ -0,0 +1,26 @@
+package com.github.javaparser.examples;
+
+
+/**
+ * A class with some uncommon formatting, to check the lexical preservation
+ */
+public class
+MyRenamedClass
+{
+
+    boolean aField;
+
+    public ASimpleClass(boolean aField)
+    {
+        this.aField = aField;
+    }
+
+
+    // Some empty lines
+
+
+    public boolean getAField()
+    {
+        return aField;
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step2.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step2.java.txt
new file mode 100644
index 0000000..84ceb29
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step2.java.txt
@@ -0,0 +1,29 @@
+package com.github.javaparser.examples;
+
+
+/**
+ * A class with some uncommon formatting, to check the lexical preservation
+ */
+public class
+MyRenamedClass
+{
+
+    boolean aField;
+
+    public ASimpleClass(boolean aField)
+    {
+        this.aField = aField;
+    }
+
+
+    // Some empty lines
+
+
+    public boolean getAField()
+    {
+        return aField;
+    }
+    
+    public void setAField() {
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step3.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step3.java.txt
new file mode 100644
index 0000000..56d5940
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step3.java.txt
@@ -0,0 +1,29 @@
+package com.github.javaparser.examples;
+
+
+/**
+ * A class with some uncommon formatting, to check the lexical preservation
+ */
+public class
+MyRenamedClass
+{
+
+    boolean aField;
+
+    public ASimpleClass(boolean aField)
+    {
+        this.aField = aField;
+    }
+
+
+    // Some empty lines
+
+
+    public boolean getAField()
+    {
+        return aField;
+    }
+    
+    public void setAField(boolean aField) {
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step4.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step4.java.txt
new file mode 100644
index 0000000..6465334
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/ASimpleClassWithMoreFormatting_step4.java.txt
@@ -0,0 +1,30 @@
+package com.github.javaparser.examples;
+
+
+/**
+ * A class with some uncommon formatting, to check the lexical preservation
+ */
+public class
+MyRenamedClass
+{
+
+    boolean aField;
+
+    public ASimpleClass(boolean aField)
+    {
+        this.aField = aField;
+    }
+
+
+    // Some empty lines
+
+
+    public boolean getAField()
+    {
+        return aField;
+    }
+    
+    public void setAField(boolean aField) {
+        this.aField = aField;
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example10_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example10_expected.java.txt
new file mode 100644
index 0000000..1313788
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example10_expected.java.txt
@@ -0,0 +1,11 @@
+// some example
+/** Super extra cool this annotation!!!*/
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example1_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example1_expected.java.txt
new file mode 100644
index 0000000..33545c2
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example1_expected.java.txt
@@ -0,0 +1,11 @@
+// some example
+
+@interface NewName {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example1_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example1_original.java.txt
new file mode 100644
index 0000000..e2ec99c
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example1_original.java.txt
@@ -0,0 +1,11 @@
+// some example
+
+@interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example2_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example2_expected.java.txt
new file mode 100644
index 0000000..2f4a813
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example2_expected.java.txt
@@ -0,0 +1,11 @@
+// some example
+
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example3_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example3_expected.java.txt
new file mode 100644
index 0000000..e2ec99c
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example3_expected.java.txt
@@ -0,0 +1,11 @@
+// some example
+
+@interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example3_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example3_original.java.txt
new file mode 100644
index 0000000..2f4a813
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example3_original.java.txt
@@ -0,0 +1,11 @@
+// some example
+
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example4_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example4_expected.java.txt
new file mode 100644
index 0000000..8d1c03c
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example4_expected.java.txt
@@ -0,0 +1,11 @@
+// some example
+
+protected @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example5_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example5_expected.java.txt
new file mode 100644
index 0000000..1faad99
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example5_expected.java.txt
@@ -0,0 +1,12 @@
+// some example
+
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+   int foo();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example6_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example6_expected.java.txt
new file mode 100644
index 0000000..9690ec4
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example6_expected.java.txt
@@ -0,0 +1,10 @@
+// some example
+
+public @interface ClassPreamble {
+   String author();
+   String date();
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example7_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example7_expected.java.txt
new file mode 100644
index 0000000..9bc5a61
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example7_expected.java.txt
@@ -0,0 +1,11 @@
+// some example
+
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int foo();
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example8_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example8_expected.java.txt
new file mode 100644
index 0000000..2a5fd93
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example8_expected.java.txt
@@ -0,0 +1,12 @@
+// some example
+
+/** Cool this annotation!*/
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example9_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example9_expected.java.txt
new file mode 100644
index 0000000..a5deb80
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example9_expected.java.txt
@@ -0,0 +1,10 @@
+// some example
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example9_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example9_original.java.txt
new file mode 100644
index 0000000..cd7edcd
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/AnnotationDeclaration_Example9_original.java.txt
@@ -0,0 +1,11 @@
+// some example
+/**Cool this annotation!*/
+public @interface ClassPreamble {
+   String author();
+   String date();
+   int currentRevision() default 1;
+   String lastModified() default "N/A";
+   String lastModifiedBy() default "N/A";
+   // Note use of array
+   String[] reviewers();
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example10_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example10_expected.java.txt
new file mode 100644
index 0000000..d1edb05
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example10_expected.java.txt
@@ -0,0 +1,3 @@
+// This is my class, with my comment
+class A {
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example10_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example10_original.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example10_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example1_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example1_expected.java.txt
new file mode 100644
index 0000000..e6c1ee7
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example1_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    static int a;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example1_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example1_original.java.txt
new file mode 100644
index 0000000..5b62bcf
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example1_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example2_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example2_expected.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example2_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example2_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example2_original.java.txt
new file mode 100644
index 0000000..5b62bcf
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example2_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example3_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example3_expected.java.txt
new file mode 100644
index 0000000..5b62bcf
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example3_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example3_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example3_original.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example3_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example4_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example4_original.java.txt
new file mode 100644
index 0000000..da4651d
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example4_original.java.txt
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser;
+
+import com.github.javaparser.ast.CompilationUnit;
+import com.github.javaparser.ast.Node;
+import com.github.javaparser.ast.body.BodyDeclaration;
+import com.github.javaparser.ast.comments.CommentsCollection;
+import com.github.javaparser.ast.expr.AnnotationExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.imports.ImportDeclaration;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.stmt.Statement;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+
+import static com.github.javaparser.ParseStart.*;
+import static com.github.javaparser.Providers.UTF8;
+import static com.github.javaparser.Providers.provider;
+import static com.github.javaparser.Providers.resourceProvider;
+import static com.github.javaparser.utils.Utils.assertNotNull;
+
+/**
+ * Parse Java source code and creates Abstract Syntax Trees.
+ *
+ * @author Júlio Vilmar Gesser
+ */
+public final class JavaParser {
+    private static final JavaParser defaultInstance = new JavaParser();
+
+    private final CommentsInserter commentsInserter;
+    private final ParserConfiguration configuration;
+
+    private ASTParser astParser = null;
+
+    /**
+     * Instantiate the parser with default configuration. Note that parsing can also be done with the static methods on
+     * this class.
+     * Creating an instance will reduce setup time between parsing files.
+     */
+    public JavaParser() {
+        this(new ParserConfiguration());
+    }
+
+    /**
+     * Instantiate the parser. Note that parsing can also be done with the static methods on this class.
+     * Creating an instance will reduce setup time between parsing files.
+     */
+    public JavaParser(ParserConfiguration configuration) {
+        this.configuration = configuration;
+        commentsInserter = new CommentsInserter(configuration);
+    }
+
+    private ASTParser getParserForProvider(Provider provider) {
+        if (astParser == null) {
+            astParser = new ASTParser(provider);
+        } else {
+            astParser.reset(provider);
+        }
+        astParser.setTabSize(configuration.getTabSize());
+        return astParser;
+    }
+
+    /**
+     * Parses source code.
+     * It takes the source code from a Provider.
+     * The start indicates what can be found in the source code (compilation unit, block, import...)
+     *
+     * @param start refer to the constants in ParseStart to see what can be parsed.
+     * @param provider refer to Providers to see how you can read source.
+     * @param <N> the subclass of Node that is the result of parsing in the start.
+     * @return the parse result, a collection of encountered problems, and some extra data.
+     */
+    public <N extends Node> ParseResult<N> parse(ParseStart<N> start, Provider provider) {
+        assertNotNull(start);
+        assertNotNull(provider);
+        try {
+            final ASTParser parser = getParserForProvider(provider);
+            N resultNode = start.parse(parser);
+            if (configuration.isAttributeComments()) {
+                final CommentsCollection comments = parser.getCommentsCollection();
+                commentsInserter.insertComments(resultNode, comments.copy().getComments());
+            }
+
+            return new ParseResult<>(resultNode, parser.problems, parser.getTokens(),
+                    parser.getCommentsCollection());
+        } catch (Exception e) {
+            return new ParseResult<>(e);
+        } finally {
+            try {
+                provider.close();
+            } catch (IOException e) {
+                // Since we're done parsing and have our result, we don't care about any errors.
+            }
+        }
+    }
+
+    /**
+     * Parses the Java code contained in the {@link InputStream} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param in {@link InputStream} containing Java source code
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final InputStream in, Charset encoding) {
+        return simplifiedParse(COMPILATION_UNIT, provider(in, encoding));
+    }
+
+    /**
+     * Parses the Java code contained in the {@link InputStream} and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param in {@link InputStream} containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final InputStream in) {
+        return parse(in, UTF8);
+    }
+
+    /**
+     * Parses the Java code contained in a {@link File} and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param file {@link File} containing Java source code
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws FileNotFoundException the file was not found
+     */
+    public static CompilationUnit parse(final File file, final Charset encoding) throws FileNotFoundException {
+        return simplifiedParse(COMPILATION_UNIT, provider(file, encoding));
+    }
+
+    /**
+     * Parses the Java code contained in a {@link File} and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param file {@link File} containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws FileNotFoundException the file was not found
+     */
+    public static CompilationUnit parse(final File file) throws FileNotFoundException {
+        return simplifiedParse(COMPILATION_UNIT, provider(file));
+    }
+
+    /**
+     * Parses the Java code contained in a file and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param path path to a file containing Java source code
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws IOException the path could not be accessed
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final Path path, final Charset encoding) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, provider(path, encoding));
+    }
+
+    /**
+     * Parses the Java code contained in a file and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param path path to a file containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parse(final Path path) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, provider(path));
+    }
+
+    /**
+     * Parses the Java code contained in a resource and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     * Note: Uses UTF-8 encoding
+     *
+     * @param path path to a resource containing Java source code. As resource is
+     * accessed through a class loader, a leading "/" is not allowed in pathToResource
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parseResource(final String path) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, resourceProvider(path));
+    }
+
+    /**
+     * Parses the Java code contained in a resource and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     *
+     * @param path path to a resource containing Java source code. As resource is
+     * accessed through a class loader, a leading "/" is not allowed in pathToResource
+     * @param encoding encoding of the source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parseResource(final String path, Charset encoding) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, resourceProvider(path, encoding));
+    }
+
+    /**
+     * Parses the Java code contained in a resource and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     *
+     * @param classLoader the classLoader that is asked to load the resource
+     * @param path path to a resource containing Java source code. As resource is
+     * accessed through a class loader, a leading "/" is not allowed in pathToResource
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     * @throws IOException the path could not be accessed
+     */
+    public static CompilationUnit parseResource(final ClassLoader classLoader, final String path, Charset encoding) throws IOException {
+        return simplifiedParse(COMPILATION_UNIT, resourceProvider(classLoader, path, encoding));
+    }
+
+    /**
+     * Parses Java code from a Reader and returns a
+     * {@link CompilationUnit} that represents it.<br>
+     *
+     * @param reader the reader containing Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(final Reader reader) {
+        return simplifiedParse(COMPILATION_UNIT, provider(reader));
+    }
+
+    /**
+     * Parses the Java code contained in code and returns a
+     * {@link CompilationUnit} that represents it.
+     *
+     * @param code Java source code
+     * @return CompilationUnit representing the Java source code
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static CompilationUnit parse(String code) {
+        return simplifiedParse(COMPILATION_UNIT, provider(code));
+    }
+
+    /**
+     * Parses the Java block contained in a {@link String} and returns a
+     * {@link BlockStmt} that represents it.
+     *
+     * @param blockStatement {@link String} containing Java block code
+     * @return BlockStmt representing the Java block
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static BlockStmt parseBlock(final String blockStatement) {
+        return simplifiedParse(BLOCK, provider(blockStatement));
+    }
+
+    /**
+     * Parses the Java statement contained in a {@link String} and returns a
+     * {@link Statement} that represents it.
+     *
+     * @param statement {@link String} containing Java statement code
+     * @return Statement representing the Java statement
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static Statement parseStatement(final String statement) {
+        return simplifiedParse(STATEMENT, provider(statement));
+    }
+
+    private static <T extends Node> T simplifiedParse(ParseStart<T> context, Provider provider) {
+        ParseResult<T> result = defaultInstance.parse(context, provider);
+        if (result.isSuccessful()) {
+            return result.getResult().get();
+        }
+        throw new ParseProblemException(result.getProblems());
+    }
+
+    /**
+     * Parses the Java import contained in a {@link String} and returns a
+     * {@link ImportDeclaration} that represents it.
+     *
+     * @param importDeclaration {@link String} containing Java import code
+     * @return ImportDeclaration representing the Java import declaration
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static ImportDeclaration parseImport(final String importDeclaration) {
+        return simplifiedParse(IMPORT_DECLARATION, provider(importDeclaration));
+    }
+
+    /**
+     * Parses the Java expression contained in a {@link String} and returns a
+     * {@link Expression} that represents it.
+     *
+     * @param expression {@link String} containing Java expression
+     * @return Expression representing the Java expression
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    @SuppressWarnings("unchecked")
+    public static <T extends Expression> T parseExpression(final String expression) {
+        return (T) simplifiedParse(EXPRESSION, provider(expression));
+    }
+
+    /**
+     * Parses the Java annotation contained in a {@link String} and returns a
+     * {@link AnnotationExpr} that represents it.
+     *
+     * @param annotation {@link String} containing Java annotation
+     * @return AnnotationExpr representing the Java annotation
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static AnnotationExpr parseAnnotation(final String annotation) {
+        return simplifiedParse(ANNOTATION, provider(annotation));
+    }
+
+    /**
+     * Parses the Java annotation body declaration(e.g fields or methods) contained in a
+     * {@link String} and returns a {@link BodyDeclaration} that represents it.
+     *
+     * @param body {@link String} containing Java body declaration
+     * @return BodyDeclaration representing the Java annotation
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static BodyDeclaration<?> parseAnnotationBodyDeclaration(final String body) {
+        return simplifiedParse(ANNOTATION_BODY, provider(body));
+    }
+
+    /**
+     * Parses a Java class body declaration(e.g fields or methods) and returns a
+     * {@link BodyDeclaration} that represents it.
+     *
+     * @param body the body of a class
+     * @return BodyDeclaration representing the Java class body
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static BodyDeclaration<?> parseClassBodyDeclaration(String body) {
+        return simplifiedParse(CLASS_BODY, provider(body));
+    }
+
+    /**
+     * Parses a Java interface body declaration(e.g fields or methods) and returns a
+     * {@link BodyDeclaration} that represents it.
+     *
+     * @param body the body of an interface
+     * @return BodyDeclaration representing the Java interface body
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static BodyDeclaration parseInterfaceBodyDeclaration(String body) {
+        return simplifiedParse(INTERFACE_BODY, provider(body));
+    }
+
+    /**
+     * Parses a Java type name and returns a {@link ClassOrInterfaceType} that represents it.
+     *
+     * @param type the type name like a.b.c.X or Y
+     * @return ClassOrInterfaceType representing the type
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static ClassOrInterfaceType parseClassOrInterfaceType(String type) {
+        return simplifiedParse(CLASS_OR_INTERFACE_TYPE, provider(type));
+    }
+
+    /**
+     * Parses a variable declaration expression and returns a {@link com.github.javaparser.ast.expr.VariableDeclarationExpr} that represents it.
+     *
+     * @param declaration a variable declaration like <code>int x=2;</code>
+     * @return VariableDeclarationExpr representing the type
+     * @throws ParseProblemException if the source code has parser errors
+     */
+    public static VariableDeclarationExpr parseVariableDeclarationExpr(String declaration) {
+        return simplifiedParse(VARIABLE_DECLARATION_EXPR, provider(declaration));
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example5_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example5_expected.java.txt
new file mode 100644
index 0000000..18a5420
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example5_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = null;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example5_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example5_original.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example5_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example6_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example6_expected.java.txt
new file mode 100644
index 0000000..91a79fe
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example6_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int someOtherName = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example6_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example6_original.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example6_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example7_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example7_expected.java.txt
new file mode 100644
index 0000000..ee17fd3
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example7_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int[] a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example7_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example7_original.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example7_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example8_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example8_expected.java.txt
new file mode 100644
index 0000000..b8b7350
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example8_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10, b;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example8_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example8_original.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example8_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example9_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example9_expected.java.txt
new file mode 100644
index 0000000..e23818f
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example9_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10, b[];
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example9_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example9_original.java.txt
new file mode 100644
index 0000000..2021255
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example9_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int a = 10;
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param1_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param1_expected.java.txt
new file mode 100644
index 0000000..867c4a1
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param1_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    void foo(int p1) { }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param1_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param1_original.java.txt
new file mode 100644
index 0000000..d90f55e
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param1_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    void foo() { }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param2_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param2_expected.java.txt
new file mode 100644
index 0000000..81a85e7
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param2_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    void foo(int[] p1, char p2) { }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param3_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param3_expected.java.txt
new file mode 100644
index 0000000..88c866a
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param3_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    void foo(char p2) { }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param3_original.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param3_original.java.txt
new file mode 100644
index 0000000..a833bd9
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param3_original.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    void foo(int p1, char p2) { }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param4_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param4_expected.java.txt
new file mode 100644
index 0000000..867c4a1
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param4_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    void foo(int p1) { }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param5_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param5_expected.java.txt
new file mode 100644
index 0000000..f883e12
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param5_expected.java.txt
@@ -0,0 +1,6 @@
+// This is my class, with my comment
+class A {
+    int foo(int p1, char p2) {
+        return p1;
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param5b_expected.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param5b_expected.java.txt
new file mode 100644
index 0000000..9e3a4fa
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/Example_param5b_expected.java.txt
@@ -0,0 +1,4 @@
+// This is my class, with my comment
+class A {
+    int foo(int p1, char p2) { }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/MethodWithOneStatement.java.txt b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/MethodWithOneStatement.java.txt
new file mode 100644
index 0000000..a3db955
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/lexical_preservation_samples/MethodWithOneStatement.java.txt
@@ -0,0 +1,5 @@
+class A {
+    public void someMethod() {
+        String test = "";
+    }
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/printer/JavaConcepts_prettyprinted b/javaparser-testing/src/test/resources/com/github/javaparser/printer/JavaConcepts_prettyprinted
new file mode 100644
index 0000000..c83d8e4
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/printer/JavaConcepts_prettyprinted
@@ -0,0 +1,395 @@
+package japa.bdd.samples;
+
+import com.github.javaparser.JavaParser;
+import japa.parser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Ignore;
+import java.io.*;
+import java.util.*;
+
+@Ignore
+@Deprecated
+public class JavaConcepts<T extends List<int[]>, X> extends Base implements Serializable {
+
+    static Class clz1 = String.class;
+
+    protected Class clz2 = (String.class);
+
+    Class clz3 = int.class;
+
+    Class clz4 = (int.class);
+
+    int[] arr = new int[10];
+
+    byte bye = 0;
+
+    byte[] byebye = null;
+
+    short sh1, sh2 = 1;
+
+    int intWithUnderscore = 1234_5678;
+
+    long longWithUnderscore = 1234_5678L;
+
+    float floatWithUnderscore = 1_234.5_678f;
+
+    float floatWithUnderscoreAndExponent = 1_234e1_0f;
+
+    double doubleWithUnderscore = 1_234.5_678;
+
+    double doubleWithUnderscoreAndExponent = 1_234e1_0;
+
+    int binaryLiteral = 0b101101;
+
+    List<String>[][] arrLS = (List<String>[][]) new List<?>[10][];
+
+    {
+        int z = 0, y = 0;
+        int a = (z) + y;
+        a = (+z) + y;
+        byte b = (byte) +y;
+    }
+
+    List<String> diamond1 = new LinkedList<>();
+
+    @Deprecated()
+    static class Ugly {
+
+        static int x = 0;
+
+        public static void main(String[] args) {
+            x = +x;
+            x = ~x;
+            --x;
+            boolean b = !false;
+            x &= 2;
+            x |= 2;
+            x ^= 2;
+            x -= 2;
+            x %= 2;
+            x /= 2;
+            x *= 2;
+            x <<= 2;
+            x >>= 2;
+            x >>>= 2;
+            b = b || false;
+            b = b | false;
+            b = b & false;
+            b = b ^ false;
+            b = b != false;
+            b = x > 1;
+            b = x < 1;
+            b = x >= 1;
+            b = x <= 1;
+            x = x << 1;
+            x = x >> 1;
+            x = x >>> 1;
+            x = x - 1;
+            x = x * 1;
+            x = x % 1;
+            x = x / 1;
+        }
+    }
+
+    @Deprecated()
+    int[][][][] arr2 = new int[10][2][1][0];
+
+    volatile float fff = 0x1.fffeP+127f;
+
+    char cc = 'a';
+
+    int[][] arr3 = { { 1, 2 }, { 3, 4 } };
+
+    static int[][] arr4 = {};
+
+    public static JavaConcepts t;
+
+    static {
+        arr4 = new int[][] { { 2 }, { 1 } };
+    }
+
+    {
+        arr3 = new int[][] { { 2 }, { 1 } };
+    }
+
+    public enum Teste {
+
+        asc, def
+    }
+
+    public enum Sexo {
+
+        m, @Deprecated
+        f;
+
+        public enum Sexo_ implements Serializable, Cloneable {
+
+        }
+
+        private Sexo() {
+        }
+    }
+
+    @Deprecated
+    public enum Enum {
+
+        m(1) {
+
+            @Override
+            void mm() {
+            }
+        }
+        , f(2) {
+
+            void mm() {
+            }
+        }
+        ;
+
+        native void nnn();
+
+        transient int x;
+
+        private Enum(int x) {
+            this.x = x;
+        }
+
+        abstract void mm();
+    }
+
+    strictfp double ddd() {
+        return 0.0;
+    }
+
+    public <T, E> JavaConcepts(int x) {
+        this.arr[0] = x;
+        T val1 = null;
+        E val2 = null;
+        super.<T, E>check2(val1, val2);
+        boolean b = true, y = false;
+        abstract class X {
+
+            int i = 0;
+
+            public <D> X() {
+            }
+
+            public void m() {
+            }
+        }
+        @Deprecated
+        final class Y extends X {
+
+            public Y() {
+                super();
+                JavaConcepts.this.cc = 'c';
+                super.i = 1;
+                Y.super.m();
+            }
+
+            public Y(int y) {
+                super();
+            }
+
+            public Y(long x) {
+                this();
+            }
+        }
+    }
+
+    public <T> JavaConcepts(String str) {
+    }
+
+    private class QWE extends JavaConcepts<List<int[]>, String> {
+
+        @Deprecated
+        final int z = 0;
+
+        int i = (int) -1;
+
+        public QWE(String... x) {
+            <String>super(x[0]);
+        }
+
+        public QWE(int... x) {
+            super(x[0]);
+            i = x[0];
+            assert true;
+            assert 1 == 1 : 2;
+            {
+                int iii = 3;
+                iii += 3;
+            }
+            label: {
+                int iii = 1;
+            }
+            ;
+            ;
+            int min = -2147483648;
+            long sl = 123123123123l;
+            long minl = -9223372036854775808L;
+            switch(i) {
+            }
+            ll: switch(i) {
+                case 1:
+                    System.out.println(1);
+                    break ll;
+                default:
+                    {
+                        System.out.println("default");
+                        break;
+                    }
+                case 2:
+                    if (t instanceof Base) {
+                        System.out.println(1);
+                    }
+                    i++;
+                    ++i;
+            }
+        }
+
+        private synchronized int[] doSomething() {
+            List<? extends Number> x = new ArrayList<Integer>();
+            return new int[] { 1 };
+        }
+    }
+
+    public static void main(String[] args) throws ParseException, IOException {
+        int x = 2;
+        CompilationUnit cu = parse(new File("src/japa/parser/javacc/Parser.java"));
+        System.out.println(cu);
+        JavaConcepts teste = new JavaConcepts(2);
+        JavaConcepts.QWE qwe = teste.new QWE(1);
+        if (1 + 1 == 2) {
+            teste = null;
+            teste = new JavaConcepts(1);
+        } else {
+            x = 3;
+            teste = new JavaConcepts(1);
+            x = x == 0 ? 2 : 4;
+        }
+        if (true)
+            x = 1;
+        else
+            x = 3;
+        if (true)
+            x = 1;
+        else if (false)
+            x = 3;
+        else
+            x = 2;
+        while (true) {
+            xxx: while (x == 3) continue xxx;
+            break;
+        }
+        do {
+            x++;
+        } while (x < 100);
+        do x++; while (x < 100);
+        for (@Deprecated int i : arr4[0]) {
+            x--;
+        }
+        for (@Deprecated final int i = 0, j = 1; i < 10; x++) {
+            break;
+        }
+        int i, j;
+        for (i = 0, j = 1; i < 10 && j < 2; i++, j--) {
+            break;
+        }
+    }
+
+    public static CompilationUnit parse(@Deprecated File file) throws ParseException, IOException {
+        String a = ((String) "qwe");
+        String x = ((String) clz1.getName());
+        int y = ((Integer) (Object) x).intValue();
+        synchronized (file) {
+            file = null;
+            file = new File("");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (final NullPointerException e) {
+            System.out.println("catch");
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream();
+            InputStream in2 = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        }
+        try {
+            System.out.println("whatever");
+        } catch (RuntimeException e) {
+            System.out.println(e);
+        } catch (final Exception | Error e) {
+            System.out.println(e);
+        }
+        return JavaParser.parse(file);
+    }
+
+    class A<T extends Integer & Serializable> implements XXX, Serializable {
+
+        public <ABC> A(Integer integer, ABC string) throws Exception, IOException {
+        }
+    }
+
+    private <Y> void x(Map<? extends X, ? super T> x) {
+        @Deprecated Comparator c = new Comparator() {
+
+            public int compare(Object o1, Object o2) {
+                try {
+                    A<Integer> a = new <String> A<Integer>(new Integer(11), "foo") {
+                    };
+                } catch (Exception e) {
+                }
+                return 0;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return super.equals(obj);
+            }
+        };
+    }
+
+    private static InputStream createInputStream() {
+        return new ByteArrayInputStream(null);
+    }
+}
+
+class Base {
+
+    public <A, B> void check2(A val1, B val2) {
+    }
+}
+
+interface XXX extends Serializable, Cloneable {
+}
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/printer/PrettyPrintVisitor_prettyprinted b/javaparser-testing/src/test/resources/com/github/javaparser/printer/PrettyPrintVisitor_prettyprinted
new file mode 100644
index 0000000..90048cf
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/printer/PrettyPrintVisitor_prettyprinted
@@ -0,0 +1,1353 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+package com.github.javaparser.printer;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+import static com.github.javaparser.utils.PositionUtils.sortByBeginPosition;
+import static com.github.javaparser.utils.Utils.isNullOrEmpty;
+
+/**
+ * Outputs the AST as formatted Java source code.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public class PrettyPrintVisitor implements VoidVisitor<Void> {
+
+    protected final PrettyPrinterConfiguration configuration;
+
+    protected final SourcePrinter printer;
+
+    public PrettyPrintVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) {
+        configuration = prettyPrinterConfiguration;
+        printer = new SourcePrinter(configuration.getIndent());
+    }
+
+    public String getSource() {
+        return printer.getSource();
+    }
+
+    private void printModifiers(final EnumSet<Modifier> modifiers) {
+        if (modifiers.size() > 0) {
+            printer.print(modifiers.stream().map(Modifier::asString).collect(Collectors.joining(" ")) + " ");
+        }
+    }
+
+    private void printMembers(final NodeList<BodyDeclaration<?>> members, final Void arg) {
+        for (final BodyDeclaration<?> member : members) {
+            printer.println();
+            member.accept(this, arg);
+            printer.println();
+        }
+    }
+
+    private void printMemberAnnotations(final NodeList<AnnotationExpr> annotations, final Void arg) {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        for (final AnnotationExpr a : annotations) {
+            a.accept(this, arg);
+            printer.println();
+        }
+    }
+
+    private void printAnnotations(final NodeList<AnnotationExpr> annotations, boolean prefixWithASpace, final Void arg) {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        if (prefixWithASpace) {
+            printer.print(" ");
+        }
+        for (AnnotationExpr annotation : annotations) {
+            annotation.accept(this, arg);
+            printer.print(" ");
+        }
+    }
+
+    private void printTypeArgs(final NodeWithTypeArguments<?> nodeWithTypeArguments, final Void arg) {
+        NodeList<Type> typeArguments = nodeWithTypeArguments.getTypeArguments().orElse(null);
+        if (!isNullOrEmpty(typeArguments)) {
+            printer.print("<");
+            for (final Iterator<Type> i = typeArguments.iterator(); i.hasNext(); ) {
+                final Type t = i.next();
+                t.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(">");
+        }
+    }
+
+    private void printTypeParameters(final NodeList<TypeParameter> args, final Void arg) {
+        if (!isNullOrEmpty(args)) {
+            printer.print("<");
+            for (final Iterator<TypeParameter> i = args.iterator(); i.hasNext(); ) {
+                final TypeParameter t = i.next();
+                t.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(">");
+        }
+    }
+
+    private void printArguments(final NodeList<Expression> args, final Void arg) {
+        printer.print("(");
+        if (!isNullOrEmpty(args)) {
+            for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+    }
+
+    private void printJavaComment(final Comment javacomment, final Void arg) {
+        if (javacomment != null) {
+            javacomment.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final CompilationUnit n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getPackageDeclaration().isPresent()) {
+            n.getPackageDeclaration().get().accept(this, arg);
+        }
+        n.getImports().accept(this, arg);
+        if (!n.getImports().isEmpty()) {
+            printer.println();
+        }
+        for (final Iterator<TypeDeclaration<?>> i = n.getTypes().iterator(); i.hasNext(); ) {
+            i.next().accept(this, arg);
+            printer.println();
+            if (i.hasNext()) {
+                printer.println();
+            }
+        }
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final PackageDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("package ");
+        n.getName().accept(this, arg);
+        printer.println(";");
+        printer.println();
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final NameExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final Name n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getQualifier().isPresent()) {
+            n.getQualifier().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print(n.getIdentifier());
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(SimpleName n, Void arg) {
+        printer.print(n.getIdentifier());
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        if (n.isInterface()) {
+            printer.print("interface ");
+        } else {
+            printer.print("class ");
+        }
+        n.getName().accept(this, arg);
+        printTypeParameters(n.getTypeParameters(), arg);
+        if (!n.getExtendedTypes().isEmpty()) {
+            printer.print(" extends ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getExtendedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        if (!n.getImplementedTypes().isEmpty()) {
+            printer.print(" implements ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.println(" {");
+        printer.indent();
+        if (!isNullOrEmpty(n.getMembers())) {
+            printMembers(n.getMembers(), arg);
+        }
+        printOrphanCommentsEnding(n);
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final JavadocComment n, final Void arg) {
+        printer.print("/**");
+        printer.print(n.getContent());
+        printer.println("*/");
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+        for (AnnotationExpr ae : n.getAnnotations()) {
+            ae.accept(this, arg);
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+        if (n.isUsingDiamondOperator()) {
+            printer.print("<>");
+        } else {
+            printTypeArgs(n, arg);
+        }
+    }
+
+    @Override
+    public void visit(final TypeParameter n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        for (AnnotationExpr ann : n.getAnnotations()) {
+            ann.accept(this, arg);
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+        if (!isNullOrEmpty(n.getTypeBound())) {
+            printer.print(" extends ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getTypeBound().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(" & ");
+                }
+            }
+        }
+    }
+
+    @Override
+    public void visit(final PrimitiveType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), true, arg);
+        printer.print(n.getType().asString());
+    }
+
+    @Override
+    public void visit(final ArrayType n, final Void arg) {
+        final List<ArrayType> arrayTypeBuffer = new LinkedList<>();
+        Type type = n;
+        while (type instanceof ArrayType) {
+            final ArrayType arrayType = (ArrayType) type;
+            arrayTypeBuffer.add(arrayType);
+            type = arrayType.getComponentType();
+        }
+        type.accept(this, arg);
+        for (ArrayType arrayType : arrayTypeBuffer) {
+            printAnnotations(arrayType.getAnnotations(), true, arg);
+            printer.print("[]");
+        }
+    }
+
+    @Override
+    public void visit(final ArrayCreationLevel n, final Void arg) {
+        printAnnotations(n.getAnnotations(), true, arg);
+        printer.print("[");
+        if (n.getDimension().isPresent()) {
+            n.getDimension().get().accept(this, arg);
+        }
+        printer.print("]");
+    }
+
+    @Override
+    public void visit(final IntersectionType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" & ");
+            }
+        }
+    }
+
+    @Override
+    public void visit(final UnionType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), true, arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" | ");
+            }
+            element.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final WildcardType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("?");
+        if (n.getExtendedTypes().isPresent()) {
+            printer.print(" extends ");
+            n.getExtendedTypes().get().accept(this, arg);
+        }
+        if (n.getSuperTypes().isPresent()) {
+            printer.print(" super ");
+            n.getSuperTypes().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final UnknownType n, final Void arg) {
+    // Nothing to print
+    }
+
+    @Override
+    public void visit(final FieldDeclaration n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        if (!n.getVariables().isEmpty()) {
+            n.getMaximumCommonType().accept(this, arg);
+        }
+        printer.print(" ");
+        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+            final VariableDeclarator var = i.next();
+            var.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final VariableDeclarator n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        Type commonType = n.getAncestorOfType(NodeWithVariables.class).get().getMaximumCommonType();
+        Type type = n.getType();
+        ArrayType arrayType = null;
+        for (int i = commonType.getArrayLevel(); i < type.getArrayLevel(); i++) {
+            if (arrayType == null) {
+                arrayType = (ArrayType) type;
+            } else {
+                arrayType = (ArrayType) arrayType.getComponentType();
+            }
+            printAnnotations(arrayType.getAnnotations(), true, arg);
+            printer.print("[]");
+        }
+        if (n.getInitializer().isPresent()) {
+            printer.print(" = ");
+            n.getInitializer().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final ArrayInitializerExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("{");
+        if (!isNullOrEmpty(n.getValues())) {
+            printer.print(" ");
+            for (final Iterator<Expression> i = n.getValues().iterator(); i.hasNext(); ) {
+                final Expression expr = i.next();
+                expr.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(" ");
+        }
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final VoidType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("void");
+    }
+
+    @Override
+    public void visit(final ArrayAccessExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        printer.print("[");
+        n.getIndex().accept(this, arg);
+        printer.print("]");
+    }
+
+    @Override
+    public void visit(final ArrayCreationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("new ");
+        n.getElementType().accept(this, arg);
+        for (ArrayCreationLevel level : n.getLevels()) {
+            level.accept(this, arg);
+        }
+        if (n.getInitializer().isPresent()) {
+            printer.print(" ");
+            n.getInitializer().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final AssignExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getTarget().accept(this, arg);
+        printer.print(" ");
+        printer.print(n.getOperator().asString());
+        printer.print(" ");
+        n.getValue().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final BinaryExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getLeft().accept(this, arg);
+        printer.print(" ");
+        printer.print(n.getOperator().asString());
+        printer.print(" ");
+        n.getRight().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final CastExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("(");
+        n.getType().accept(this, arg);
+        printer.print(") ");
+        n.getExpression().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ClassExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getType().accept(this, arg);
+        printer.print(".class");
+    }
+
+    @Override
+    public void visit(final ConditionalExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getCondition().accept(this, arg);
+        printer.print(" ? ");
+        n.getThenExpr().accept(this, arg);
+        printer.print(" : ");
+        n.getElseExpr().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final EnclosedExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("(");
+        if (n.getInner().isPresent()) {
+            n.getInner().get().accept(this, arg);
+        }
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final FieldAccessExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getScope().isPresent())
+            n.getScope().get().accept(this, arg);
+        printer.print(".");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final InstanceOfExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getExpression().accept(this, arg);
+        printer.print(" instanceof ");
+        n.getType().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final CharLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("'");
+        printer.print(n.getValue());
+        printer.print("'");
+    }
+
+    @Override
+    public void visit(final DoubleLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final IntegerLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final LongLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final StringLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("\"");
+        printer.print(n.getValue());
+        printer.print("\"");
+    }
+
+    @Override
+    public void visit(final BooleanLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(String.valueOf(n.getValue()));
+    }
+
+    @Override
+    public void visit(final NullLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("null");
+    }
+
+    @Override
+    public void visit(final ThisExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getClassExpr().isPresent()) {
+            n.getClassExpr().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print("this");
+    }
+
+    @Override
+    public void visit(final SuperExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getClassExpr().isPresent()) {
+            n.getClassExpr().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print("super");
+    }
+
+    @Override
+    public void visit(final MethodCallExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+        printTypeArgs(n, arg);
+        n.getName().accept(this, arg);
+        printArguments(n.getArguments(), arg);
+    }
+
+    @Override
+    public void visit(final ObjectCreationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print("new ");
+        printTypeArgs(n, arg);
+        if (!isNullOrEmpty(n.getTypeArguments().orElse(null))) {
+            printer.print(" ");
+        }
+        n.getType().accept(this, arg);
+        printArguments(n.getArguments(), arg);
+        if (n.getAnonymousClassBody().isPresent()) {
+            printer.println(" {");
+            printer.indent();
+            printMembers(n.getAnonymousClassBody().get(), arg);
+            printer.unindent();
+            printer.print("}");
+        }
+    }
+
+    @Override
+    public void visit(final UnaryExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getOperator().isPrefix()) {
+            printer.print(n.getOperator().asString());
+        }
+        n.getExpression().accept(this, arg);
+        if (n.getOperator().isPostfix()) {
+            printer.print(n.getOperator().asString());
+        }
+    }
+
+    @Override
+    public void visit(final ConstructorDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        printTypeParameters(n.getTypeParameters(), arg);
+        if (n.isGeneric()) {
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+        printer.print("(");
+        if (!n.getParameters().isEmpty()) {
+            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+                final Parameter p = i.next();
+                p.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+        if (!isNullOrEmpty(n.getThrownExceptions())) {
+            printer.print(" throws ");
+            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
+                final ReferenceType name = i.next();
+                name.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(" ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final MethodDeclaration n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        if (n.isDefault()) {
+            printer.print("default ");
+        }
+        printTypeParameters(n.getTypeParameters(), arg);
+        if (!isNullOrEmpty(n.getTypeParameters())) {
+            printer.print(" ");
+        }
+        n.getType().accept(this, arg);
+        printer.print(" ");
+        n.getName().accept(this, arg);
+        printer.print("(");
+        if (!isNullOrEmpty(n.getParameters())) {
+            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+                final Parameter p = i.next();
+                p.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+        if (!isNullOrEmpty(n.getThrownExceptions())) {
+            printer.print(" throws ");
+            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
+                final ReferenceType name = i.next();
+                name.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        if (!n.getBody().isPresent()) {
+            printer.print(";");
+        } else {
+            printer.print(" ");
+            n.getBody().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final Parameter n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printModifiers(n.getModifiers());
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+        if (n.isVarArgs()) {
+            printer.print("...");
+        }
+        printer.print(" ");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ExplicitConstructorInvocationStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.isThis()) {
+            printTypeArgs(n, arg);
+            printer.print("this");
+        } else {
+            if (n.getExpression().isPresent()) {
+                n.getExpression().get().accept(this, arg);
+                printer.print(".");
+            }
+            printTypeArgs(n, arg);
+            printer.print("super");
+        }
+        printArguments(n.getArguments(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final VariableDeclarationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printModifiers(n.getModifiers());
+        if (!n.getVariables().isEmpty()) {
+            n.getMaximumCommonType().accept(this, arg);
+        }
+        printer.print(" ");
+        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+            final VariableDeclarator v = i.next();
+            v.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+    }
+
+    @Override
+    public void visit(final LocalClassDeclarationStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getClassDeclaration().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final AssertStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("assert ");
+        n.getCheck().accept(this, arg);
+        if (n.getMessage().isPresent()) {
+            printer.print(" : ");
+            n.getMessage().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final BlockStmt n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printJavaComment(n.getComment(), arg);
+        printer.println("{");
+        if (n.getStatements() != null) {
+            printer.indent();
+            for (final Statement s : n.getStatements()) {
+                s.accept(this, arg);
+                printer.println();
+            }
+            printer.unindent();
+        }
+        printOrphanCommentsEnding(n);
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final LabeledStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getLabel().accept(this, arg);
+        printer.print(": ");
+        n.getStatement().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final EmptyStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final ExpressionStmt n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printJavaComment(n.getComment(), arg);
+        n.getExpression().accept(this, arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final SwitchStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("switch(");
+        n.getSelector().accept(this, arg);
+        printer.println(") {");
+        if (n.getEntries() != null) {
+            printer.indent();
+            for (final SwitchEntryStmt e : n.getEntries()) {
+                e.accept(this, arg);
+            }
+            printer.unindent();
+        }
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final SwitchEntryStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getLabel().isPresent()) {
+            printer.print("case ");
+            n.getLabel().get().accept(this, arg);
+            printer.print(":");
+        } else {
+            printer.print("default:");
+        }
+        printer.println();
+        printer.indent();
+        if (n.getStatements() != null) {
+            for (final Statement s : n.getStatements()) {
+                s.accept(this, arg);
+                printer.println();
+            }
+        }
+        printer.unindent();
+    }
+
+    @Override
+    public void visit(final BreakStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("break");
+        n.getLabel().ifPresent( l -> printer.print(" ").print(l.getIdentifier()));
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final ReturnStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("return");
+        if (n.getExpression().isPresent()) {
+            printer.print(" ");
+            n.getExpression().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final EnumDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        printer.print("enum ");
+        n.getName().accept(this, arg);
+        if (!n.getImplementedTypes().isEmpty()) {
+            printer.print(" implements ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.println(" {");
+        printer.indent();
+        if (n.getEntries() != null) {
+            printer.println();
+            for (final Iterator<EnumConstantDeclaration> i = n.getEntries().iterator(); i.hasNext(); ) {
+                final EnumConstantDeclaration e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        if (!n.getMembers().isEmpty()) {
+            printer.println(";");
+            printMembers(n.getMembers(), arg);
+        } else {
+            if (!n.getEntries().isEmpty()) {
+                printer.println();
+            }
+        }
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final EnumConstantDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        n.getName().accept(this, arg);
+        if (!n.getArguments().isEmpty()) {
+            printArguments(n.getArguments(), arg);
+        }
+        if (!n.getClassBody().isEmpty()) {
+            printer.println(" {");
+            printer.indent();
+            printMembers(n.getClassBody(), arg);
+            printer.unindent();
+            printer.println("}");
+        }
+    }
+
+    @Override
+    public void visit(final EmptyMemberDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final InitializerDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.isStatic()) {
+            printer.print("static ");
+        }
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final IfStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("if (");
+        n.getCondition().accept(this, arg);
+        final boolean thenBlock = n.getThenStmt() instanceof BlockStmt;
+        if (// block statement should start on the same line
+        thenBlock)
+            printer.print(") ");
+        else {
+            printer.println(")");
+            printer.indent();
+        }
+        n.getThenStmt().accept(this, arg);
+        if (!thenBlock)
+            printer.unindent();
+        if (n.getElseStmt().isPresent()) {
+            if (thenBlock)
+                printer.print(" ");
+            else
+                printer.println();
+            final boolean elseIf = n.getElseStmt().orElse(null) instanceof IfStmt;
+            final boolean elseBlock = n.getElseStmt().orElse(null) instanceof BlockStmt;
+            if (// put chained if and start of block statement on a same level
+            elseIf || elseBlock)
+                printer.print("else ");
+            else {
+                printer.println("else");
+                printer.indent();
+            }
+            if (n.getElseStmt().isPresent())
+                n.getElseStmt().get().accept(this, arg);
+            if (!(elseIf || elseBlock))
+                printer.unindent();
+        }
+    }
+
+    @Override
+    public void visit(final WhileStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("while (");
+        n.getCondition().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ContinueStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("continue");
+        n.getLabel().ifPresent( l -> printer.print(" ").print(l.getIdentifier()));
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final DoStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("do ");
+        n.getBody().accept(this, arg);
+        printer.print(" while (");
+        n.getCondition().accept(this, arg);
+        printer.print(");");
+    }
+
+    @Override
+    public void visit(final ForeachStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("for (");
+        n.getVariable().accept(this, arg);
+        printer.print(" : ");
+        n.getIterable().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ForStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("for (");
+        if (n.getInitialization() != null) {
+            for (final Iterator<Expression> i = n.getInitialization().iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print("; ");
+        if (n.getCompare().isPresent()) {
+            n.getCompare().get().accept(this, arg);
+        }
+        printer.print("; ");
+        if (n.getUpdate() != null) {
+            for (final Iterator<Expression> i = n.getUpdate().iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ThrowStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("throw ");
+        n.getExpression().accept(this, arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final SynchronizedStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("synchronized (");
+        n.getExpression().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final TryStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("try ");
+        if (!n.getResources().isEmpty()) {
+            printer.print("(");
+            Iterator<VariableDeclarationExpr> resources = n.getResources().iterator();
+            boolean first = true;
+            while (resources.hasNext()) {
+                visit(resources.next(), arg);
+                if (resources.hasNext()) {
+                    printer.print(";");
+                    printer.println();
+                    if (first) {
+                        printer.indent();
+                    }
+                }
+                first = false;
+            }
+            if (n.getResources().size() > 1) {
+                printer.unindent();
+            }
+            printer.print(") ");
+        }
+        if (n.getTryBlock().isPresent()) {
+            n.getTryBlock().get().accept(this, arg);
+        }
+        for (final CatchClause c : n.getCatchClauses()) {
+            c.accept(this, arg);
+        }
+        if (n.getFinallyBlock().isPresent()) {
+            printer.print(" finally ");
+            n.getFinallyBlock().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final CatchClause n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(" catch (");
+        n.getParameter().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final AnnotationDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        printer.print("@interface ");
+        n.getName().accept(this, arg);
+        printer.println(" {");
+        printer.indent();
+        if (n.getMembers() != null) {
+            printMembers(n.getMembers(), arg);
+        }
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final AnnotationMemberDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        n.getType().accept(this, arg);
+        printer.print(" ");
+        n.getName().accept(this, arg);
+        printer.print("()");
+        if (n.getDefaultValue().isPresent()) {
+            printer.print(" default ");
+            n.getDefaultValue().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final MarkerAnnotationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final SingleMemberAnnotationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+        printer.print("(");
+        n.getMemberValue().accept(this, arg);
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final NormalAnnotationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+        printer.print("(");
+        if (n.getPairs() != null) {
+            for (final Iterator<MemberValuePair> i = n.getPairs().iterator(); i.hasNext(); ) {
+                final MemberValuePair m = i.next();
+                m.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final MemberValuePair n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        printer.print(" = ");
+        n.getValue().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final LineComment n, final Void arg) {
+        if (!configuration.isPrintComments()) {
+            return;
+        }
+        printer.print("//");
+        String tmp = n.getContent();
+        tmp = tmp.replace('\r', ' ');
+        tmp = tmp.replace('\n', ' ');
+        printer.println(tmp);
+    }
+
+    @Override
+    public void visit(final BlockComment n, final Void arg) {
+        if (!configuration.isPrintComments()) {
+            return;
+        }
+        printer.print("/*").print(n.getContent()).println("*/");
+    }
+
+    @Override
+    public void visit(LambdaExpr n, Void arg) {
+        printJavaComment(n.getComment(), arg);
+        final NodeList<Parameter> parameters = n.getParameters();
+        final boolean printPar = n.isEnclosingParameters();
+        if (printPar) {
+            printer.print("(");
+        }
+        for (Iterator<Parameter> i = parameters.iterator(); i.hasNext(); ) {
+            Parameter p = i.next();
+            p.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+        if (printPar) {
+            printer.print(")");
+        }
+        printer.print(" -> ");
+        final Statement body = n.getBody();
+        if (body instanceof ExpressionStmt) {
+            // Print the expression directly
+            ((ExpressionStmt) body).getExpression().accept(this, arg);
+        } else {
+            body.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(MethodReferenceExpr n, Void arg) {
+        printJavaComment(n.getComment(), arg);
+        Expression scope = n.getScope();
+        String identifier = n.getIdentifier();
+        if (scope != null) {
+            n.getScope().accept(this, arg);
+        }
+        printer.print("::");
+        printTypeArgs(n, arg);
+        if (identifier != null) {
+            printer.print(identifier);
+        }
+    }
+
+    @Override
+    public void visit(TypeExpr n, Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(NodeList n, Void arg) {
+        for (Object node : n) {
+            ((Node) node).accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final ImportDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("import ");
+        if (n.isStatic()) {
+            printer.print("static ");
+        }
+        n.getName().accept(this, arg);
+        if (n.isAsterisk()) {
+            printer.print(".*");
+        }
+        printer.println(";");
+        printOrphanCommentsEnding(n);
+    }
+
+    private void printOrphanCommentsBeforeThisChildNode(final Node node) {
+        if (node instanceof Comment)
+            return;
+        Node parent = node.getParentNode().orElse(null);
+        if (parent == null)
+            return;
+        List<Node> everything = new LinkedList<>();
+        everything.addAll(parent.getChildNodes());
+        sortByBeginPosition(everything);
+        int positionOfTheChild = -1;
+        for (int i = 0; i < everything.size(); i++) {
+            if (everything.get(i) == node)
+                positionOfTheChild = i;
+        }
+        if (positionOfTheChild == -1) {
+            throw new AssertionError("I am not a child of my parent.");
+        }
+        int positionOfPreviousChild = -1;
+        for (int i = positionOfTheChild - 1; i >= 0 && positionOfPreviousChild == -1; i--) {
+            if (!(everything.get(i) instanceof Comment))
+                positionOfPreviousChild = i;
+        }
+        for (int i = positionOfPreviousChild + 1; i < positionOfTheChild; i++) {
+            Node nodeToPrint = everything.get(i);
+            if (!(nodeToPrint instanceof Comment))
+                throw new RuntimeException("Expected comment, instead " + nodeToPrint.getClass() + ". Position of previous child: " + positionOfPreviousChild + ", position of child " + positionOfTheChild);
+            nodeToPrint.accept(this, null);
+        }
+    }
+
+    private void printOrphanCommentsEnding(final Node node) {
+        List<Node> everything = new LinkedList<>();
+        everything.addAll(node.getChildNodes());
+        sortByBeginPosition(everything);
+        if (everything.isEmpty()) {
+            return;
+        }
+        int commentsAtEnd = 0;
+        boolean findingComments = true;
+        while (findingComments && commentsAtEnd < everything.size()) {
+            Node last = everything.get(everything.size() - 1 - commentsAtEnd);
+            findingComments = (last instanceof Comment);
+            if (findingComments) {
+                commentsAtEnd++;
+            }
+        }
+        for (int i = 0; i < commentsAtEnd; i++) {
+            everything.get(everything.size() - commentsAtEnd + i).accept(this, null);
+        }
+    }
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/source_zip/test.txt b/javaparser-testing/src/test/resources/com/github/javaparser/source_zip/test.txt
new file mode 100644
index 0000000..487e034
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/source_zip/test.txt
@@ -0,0 +1 @@
+foo bar qux
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/source_zip/test.zip b/javaparser-testing/src/test/resources/com/github/javaparser/source_zip/test.zip
new file mode 100644
index 0000000..dd9b18a
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/source_zip/test.zip
Binary files differ
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/storage/A.java b/javaparser-testing/src/test/resources/com/github/javaparser/storage/A.java
new file mode 100644
index 0000000..d0fc413
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/storage/A.java
@@ -0,0 +1 @@
+package com.blablabla.root;
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/storage/B.java b/javaparser-testing/src/test/resources/com/github/javaparser/storage/B.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/storage/B.java
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/storage/PrimaryType.java b/javaparser-testing/src/test/resources/com/github/javaparser/storage/PrimaryType.java
new file mode 100644
index 0000000..bac9587
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/storage/PrimaryType.java
@@ -0,0 +1,5 @@
+package com.github.javaparser.storage;
+
+public class PrimaryType {
+    
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/storage/PrimaryType2.java b/javaparser-testing/src/test/resources/com/github/javaparser/storage/PrimaryType2.java
new file mode 100644
index 0000000..81bcf0b
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/storage/PrimaryType2.java
@@ -0,0 +1 @@
+package com.github.javaparser.storage;
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/storage/Z.java b/javaparser-testing/src/test/resources/com/github/javaparser/storage/Z.java
new file mode 100644
index 0000000..0bf8867
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/storage/Z.java
@@ -0,0 +1 @@
+package com.github.javaparser.storage;
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/utils/.abc/bla.java b/javaparser-testing/src/test/resources/com/github/javaparser/utils/.abc/bla.java
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/utils/.abc/bla.java
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/utils/Bla.java b/javaparser-testing/src/test/resources/com/github/javaparser/utils/Bla.java
new file mode 100644
index 0000000..21adb88
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/utils/Bla.java
@@ -0,0 +1,3 @@
+class X {
+    
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/utils/module-info.java b/javaparser-testing/src/test/resources/com/github/javaparser/utils/module-info.java
new file mode 100644
index 0000000..2592490
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/utils/module-info.java
@@ -0,0 +1,2 @@
+module M.N {
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/utils/source/root/Y.java b/javaparser-testing/src/test/resources/com/github/javaparser/utils/source/root/Y.java
new file mode 100644
index 0000000..fb9b0d7
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/utils/source/root/Y.java
@@ -0,0 +1,3 @@
+class Y {
+    
+}
\ No newline at end of file
diff --git a/javaparser-testing/src/test/resources/com/github/javaparser/wiki_samples/TestFile.java b/javaparser-testing/src/test/resources/com/github/javaparser/wiki_samples/TestFile.java
new file mode 100644
index 0000000..77dcb5a
--- /dev/null
+++ b/javaparser-testing/src/test/resources/com/github/javaparser/wiki_samples/TestFile.java
@@ -0,0 +1,15 @@
+package com.github.javaparser.wiki_samples;
+
+public class TestFile {
+    public void foo(int e) {
+        int a = 20;
+    }
+
+    public void abc() {
+
+    }
+
+    public int def() {
+        return 10;
+    }
+}
diff --git a/javaparser-testing/src/test/test_sourcecode/com/github/javaparser/printer/JavaConcepts.java b/javaparser-testing/src/test/test_sourcecode/com/github/javaparser/printer/JavaConcepts.java
new file mode 100644
index 0000000..2a53e5f
--- /dev/null
+++ b/javaparser-testing/src/test/test_sourcecode/com/github/javaparser/printer/JavaConcepts.java
@@ -0,0 +1,393 @@
+package japa.bdd.samples;
+
+import com.github.javaparser.JavaParser;
+import japa.parser.ParseException;
+import com.github.javaparser.ast.CompilationUnit;
+import org.junit.Ignore;
+
+import java.io.*;
+import java.util.*;
+
+@Ignore
+@Deprecated
+public class JavaConcepts<T extends List<int[]>, X> extends Base implements Serializable {
+
+    static Class clz1 = String.class;
+
+    protected Class clz2 = (String.class);
+
+    Class clz3 = int.class;
+
+    Class clz4 = (int.class);
+
+    int[] arr = new int[10];
+
+    byte bye = 0;
+
+    byte byebye[] = null;
+
+    short sh1, sh2 = 1;
+
+    int intWithUnderscore = 1234_5678;
+
+    long longWithUnderscore = 1234_5678L;
+
+    float floatWithUnderscore = 1_234.5_678f;
+
+    float floatWithUnderscoreAndExponent = 1_234e1_0f;
+
+    double doubleWithUnderscore = 1_234.5_678;
+
+    double doubleWithUnderscoreAndExponent = 1_234e1_0;
+
+    int binaryLiteral = 0b101101;
+
+    List<String>[][] arrLS = (List<String>[][]) new List<?>[10][];
+
+    {
+        int z = 0, y = 0;
+        int a = (z) + y;
+        a = (+z) + y;
+        byte b = (byte) +y;
+    }
+
+    List<String> diamond1 = new LinkedList<>();
+
+    @Deprecated()
+    static class Ugly {
+
+        static int x = 0;
+
+        public static void main(String[] args) {
+            x = +x;
+            x = ~x;
+            --x;
+            boolean b = !false;
+            x &= 2;
+            x |= 2;
+            x ^= 2;
+            x -= 2;
+            x %= 2;
+            x /= 2;
+            x *= 2;
+            x <<= 2;
+            x >>= 2;
+            x >>>= 2;
+            b = b || false;
+            b = b | false;
+            b = b & false;
+            b = b ^ false;
+            b = b != false;
+            b = x > 1;
+            b = x < 1;
+            b = x >= 1;
+            b = x <= 1;
+            x = x << 1;
+            x = x >> 1;
+            x = x >>> 1;
+            x = x - 1;
+            x = x * 1;
+            x = x % 1;
+            x = x / 1;
+        }
+    }
+
+    @Deprecated()
+    int[][][][] arr2 = new int[10][2][1][0];
+
+    volatile float fff = 0x1.fffeP+127f;
+
+    char cc = 'a';
+
+    int[][] arr3 = {{1, 2}, {3, 4}};
+
+    static int[] arr4[] = {};
+
+    public static JavaConcepts t;
+
+    static {
+        arr4 = new int[][]{{2}, {1}};
+    }
+
+    {
+        arr3 = new int[][]{{2}, {1}};
+    }
+
+    public enum Teste {
+
+        asc, def
+    }
+
+    public enum Sexo {
+
+        m, @Deprecated
+        f;
+
+        public enum Sexo_ implements Serializable, Cloneable {
+        }
+
+        private Sexo() {
+        }
+    }
+
+    @Deprecated
+    public enum Enum {
+
+        m(1) {
+            @Override
+            void mm() {
+            }
+        }, f(2) {
+            void mm() {
+            }
+        };
+
+        native void nnn();
+
+        transient int x;
+
+        private Enum(int x) {
+            this.x = x;
+        }
+
+        abstract void mm();
+    }
+
+    strictfp double ddd() {
+        return 0.0;
+    }
+
+    public <T, E> JavaConcepts(int x) {
+        this.arr[0] = x;
+        T val1 = null;
+        E val2 = null;
+        super.<T, E>check2(val1, val2);
+        boolean b = true, y = false;
+        abstract class X {
+
+            int i = 0;
+
+            public <D> X() {
+            }
+
+            public void m() {
+            }
+        }
+        @Deprecated
+        final class Y extends X {
+
+            public Y() {
+                super();
+                JavaConcepts.this.cc = 'c';
+                super.i = 1;
+                Y.super.m();
+            }
+
+            public Y(int y) {
+                super();
+            }
+
+            public Y(long x) {
+                this();
+            }
+        }
+    }
+
+    public <T> JavaConcepts(String str) {
+    }
+
+    private class QWE extends JavaConcepts<List<int[]>, String> {
+
+        @Deprecated
+        final int z = 0;
+
+        int i = (int) -1;
+
+        public QWE(String... x) {
+            <String>super(x[0]);
+        }
+
+        public QWE(int... x) {
+            super(x[0]);
+            i = x[0];
+            assert true;
+            assert 1 == 1 : 2;
+            {
+                int iii = 3;
+                iii += 3;
+            }
+            label:
+            {
+                int iii = 1;
+            }
+            ;
+            ;
+            int min = -2147483648;
+            long sl = 123123123123l;
+            long minl = -9223372036854775808L;
+            switch (i) {
+            }
+            ll:
+            switch (i) {
+                case 1:
+                    System.out.println(1);
+                    break ll;
+                default: {
+                    System.out.println("default");
+                    break;
+                }
+                case 2:
+                    if (t instanceof Base) {
+                        System.out.println(1);
+                    }
+                    i++;
+                    ++i;
+            }
+        }
+
+        private synchronized int doSomething()[] {
+            List<? extends Number> x = new ArrayList<Integer>();
+            return new int[]{1};
+        }
+    }
+
+    public static void main(String[] args) throws ParseException, IOException {
+        int x = 2;
+        CompilationUnit cu = parse(new File("src/japa/parser/javacc/Parser.java"));
+        System.out.println(cu);
+        JavaConcepts teste = new JavaConcepts(2);
+        JavaConcepts.QWE qwe = teste.new QWE(1);
+        if (1 + 1 == 2) {
+            teste = null;
+            teste = new JavaConcepts(1);
+        } else {
+            x = 3;
+            teste = new JavaConcepts(1);
+            x = x == 0 ? 2 : 4;
+        }
+        if (true)
+            x = 1;
+        else
+            x = 3;
+        if (true)
+            x = 1;
+        else if (false)
+            x = 3;
+        else
+            x = 2;
+        while (true) {
+            xxx:
+            while (x == 3) continue xxx;
+            break;
+        }
+        do {
+            x++;
+        } while (x < 100);
+        do x++; while (x < 100);
+        for (@Deprecated int i : arr4[0]) {
+            x--;
+        }
+        for (@Deprecated final int i = 0, j = 1; i < 10; x++) {
+            break;
+        }
+        int i, j;
+        for (i = 0, j = 1; i < 10 && j < 2; i++, j--) {
+            break;
+        }
+    }
+
+    public static CompilationUnit parse(@Deprecated File file) throws ParseException, IOException {
+        String a = ((String) "qwe");
+        String x = ((String) clz1.getName());
+        int y = ((Integer) (Object) x).intValue();
+        synchronized (file) {
+            file = null;
+            file = new File("");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (final NullPointerException e) {
+            System.out.println("catch");
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } finally {
+            System.out.println("finally");
+        }
+        try {
+            if (file == null) {
+                throw new NullPointerException("blah");
+            }
+        } catch (RuntimeException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream();
+             InputStream in2 = createInputStream()) {
+            System.out.println(in);
+        } catch (IOException e) {
+            System.out.println("catch");
+        }
+        try (InputStream in = createInputStream()) {
+            System.out.println(in);
+        }
+        try {
+            System.out.println("whatever");
+        } catch (RuntimeException e) {
+            System.out.println(e);
+        } catch (final Exception | Error e) {
+            System.out.println(e);
+        }
+        return JavaParser.parse(file);
+    }
+
+    class A<T extends Integer & Serializable> implements XXX, Serializable {
+
+        public <ABC> A(Integer integer, ABC string) throws Exception, IOException {
+        }
+    }
+
+    private <Y> void x(Map<? extends X, ? super T> x) {
+        @Deprecated Comparator c = new Comparator() {
+
+            public int compare(Object o1, Object o2) {
+                try {
+                    A<Integer> a = new <String>A<Integer>(new Integer(11), "foo") {
+                    };
+                } catch (Exception e) {
+                }
+                return 0;
+            }
+
+            @Override
+            public boolean equals(Object obj) {
+                return super.equals(obj);
+            }
+        };
+    }
+
+    private static InputStream createInputStream() {
+        return new ByteArrayInputStream(null);
+    }
+}
+
+class Base {
+
+    public <A, B> void check2(A val1, B val2) {
+    }
+}
+
+interface XXX extends Serializable, Cloneable {
+}
diff --git a/javaparser-testing/src/test/test_sourcecode/com/github/javaparser/printer/PrettyPrintVisitor.java b/javaparser-testing/src/test/test_sourcecode/com/github/javaparser/printer/PrettyPrintVisitor.java
new file mode 100644
index 0000000..4a4c9f0
--- /dev/null
+++ b/javaparser-testing/src/test/test_sourcecode/com/github/javaparser/printer/PrettyPrintVisitor.java
@@ -0,0 +1,1413 @@
+/*
+ * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
+ * Copyright (C) 2011, 2013-2016 The JavaParser Team.
+ *
+ * This file is part of JavaParser.
+ *
+ * JavaParser can be used either under the terms of
+ * a) the GNU Lesser General Public License as published by
+ *     the Free Software Foundation, either version 3 of the License, or
+ *     (at your option) any later version.
+ * b) the terms of the Apache License
+ *
+ * You should have received a copy of both licenses in LICENCE.LGPL and
+ * LICENCE.APACHE. Please refer to those files for details.
+ *
+ * JavaParser is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ */
+
+package com.github.javaparser.printer;
+
+import com.github.javaparser.ast.*;
+import com.github.javaparser.ast.body.*;
+import com.github.javaparser.ast.comments.BlockComment;
+import com.github.javaparser.ast.comments.Comment;
+import com.github.javaparser.ast.comments.JavadocComment;
+import com.github.javaparser.ast.comments.LineComment;
+import com.github.javaparser.ast.expr.*;
+import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
+import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
+import com.github.javaparser.ast.stmt.*;
+import com.github.javaparser.ast.type.*;
+import com.github.javaparser.ast.visitor.VoidVisitor;
+
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.github.javaparser.utils.PositionUtils.sortByBeginPosition;
+import static com.github.javaparser.utils.Utils.isNullOrEmpty;
+
+/**
+ * Outputs the AST as formatted Java source code.
+ *
+ * @author Julio Vilmar Gesser
+ */
+public class PrettyPrintVisitor implements VoidVisitor<Void> {
+    protected final PrettyPrinterConfiguration configuration;
+    protected final SourcePrinter printer;
+
+    public PrettyPrintVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) {
+        configuration = prettyPrinterConfiguration;
+        printer = new SourcePrinter(configuration.getIndent());
+    }
+
+    public String getSource() {
+        return printer.getSource();
+    }
+
+    private void printModifiers(final EnumSet<Modifier> modifiers) {
+        if (modifiers.size() > 0) {
+            printer.print(modifiers.stream().map(Modifier::asString).collect(Collectors.joining(" ")) + " ");
+        }
+    }
+
+    private void printMembers(final NodeList<BodyDeclaration<?>> members, final Void arg) {
+        for (final BodyDeclaration<?> member : members) {
+            printer.println();
+            member.accept(this, arg);
+            printer.println();
+        }
+    }
+
+    private void printMemberAnnotations(final NodeList<AnnotationExpr> annotations, final Void arg) {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        for (final AnnotationExpr a : annotations) {
+            a.accept(this, arg);
+            printer.println();
+        }
+    }
+
+    private void printAnnotations(final NodeList<AnnotationExpr> annotations, boolean prefixWithASpace,
+                                  final Void arg) {
+        if (annotations.isEmpty()) {
+            return;
+        }
+        if (prefixWithASpace) {
+            printer.print(" ");
+        }
+        for (AnnotationExpr annotation : annotations) {
+            annotation.accept(this, arg);
+            printer.print(" ");
+        }
+    }
+
+    private void printTypeArgs(final NodeWithTypeArguments<?> nodeWithTypeArguments, final Void arg) {
+        NodeList<Type> typeArguments = nodeWithTypeArguments.getTypeArguments().orElse(null);
+        if (!isNullOrEmpty(typeArguments)) {
+            printer.print("<");
+            for (final Iterator<Type> i = typeArguments.iterator(); i.hasNext(); ) {
+                final Type t = i.next();
+                t.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(">");
+        }
+    }
+
+    private void printTypeParameters(final NodeList<TypeParameter> args, final Void arg) {
+        if (!isNullOrEmpty(args)) {
+            printer.print("<");
+            for (final Iterator<TypeParameter> i = args.iterator(); i.hasNext(); ) {
+                final TypeParameter t = i.next();
+                t.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(">");
+        }
+    }
+
+    private void printArguments(final NodeList<Expression> args, final Void arg) {
+        printer.print("(");
+        if (!isNullOrEmpty(args)) {
+            for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+    }
+
+    private void printJavaComment(final Comment javacomment, final Void arg) {
+        if (javacomment != null) {
+            javacomment.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final CompilationUnit n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+
+        if (n.getPackageDeclaration().isPresent()) {
+            n.getPackageDeclaration().get().accept(this, arg);
+        }
+
+        n.getImports().accept(this, arg);
+        if (!n.getImports().isEmpty()) {
+            printer.println();
+        }
+
+        for (final Iterator<TypeDeclaration<?>> i = n.getTypes().iterator(); i.hasNext(); ) {
+            i.next().accept(this, arg);
+            printer.println();
+            if (i.hasNext()) {
+                printer.println();
+            }
+        }
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final PackageDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("package ");
+        n.getName().accept(this, arg);
+        printer.println(";");
+        printer.println();
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final NameExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(final Name n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getQualifier().isPresent()) {
+            n.getQualifier().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print(n.getIdentifier());
+
+        printOrphanCommentsEnding(n);
+    }
+
+    @Override
+    public void visit(SimpleName n, Void arg) {
+        printer.print(n.getIdentifier());
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        if (n.isInterface()) {
+            printer.print("interface ");
+        } else {
+            printer.print("class ");
+        }
+
+        n.getName().accept(this, arg);
+
+        printTypeParameters(n.getTypeParameters(), arg);
+
+        if (!n.getExtendedTypes().isEmpty()) {
+            printer.print(" extends ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getExtendedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+
+        if (!n.getImplementedTypes().isEmpty()) {
+            printer.print(" implements ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+
+        printer.println(" {");
+        printer.indent();
+        if (!isNullOrEmpty(n.getMembers())) {
+            printMembers(n.getMembers(), arg);
+        }
+
+        printOrphanCommentsEnding(n);
+
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final JavadocComment n, final Void arg) {
+        printer.print("/**");
+        printer.print(n.getContent());
+        printer.println("*/");
+    }
+
+    @Override
+    public void visit(final ClassOrInterfaceType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+        for (AnnotationExpr ae : n.getAnnotations()) {
+            ae.accept(this, arg);
+            printer.print(" ");
+        }
+
+        n.getName().accept(this, arg);
+
+        if (n.isUsingDiamondOperator()) {
+            printer.print("<>");
+        } else {
+            printTypeArgs(n, arg);
+        }
+    }
+
+    @Override
+    public void visit(final TypeParameter n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        for (AnnotationExpr ann : n.getAnnotations()) {
+            ann.accept(this, arg);
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+        if (!isNullOrEmpty(n.getTypeBound())) {
+            printer.print(" extends ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getTypeBound().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(" & ");
+                }
+            }
+        }
+    }
+
+    @Override
+    public void visit(final PrimitiveType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), true, arg);
+        printer.print(n.getType().asString());
+    }
+
+    @Override
+    public void visit(final ArrayType n, final Void arg) {
+        final List<ArrayType> arrayTypeBuffer = new LinkedList<>();
+        Type type = n;
+        while (type instanceof ArrayType) {
+            final ArrayType arrayType = (ArrayType) type;
+            arrayTypeBuffer.add(arrayType);
+            type = arrayType.getComponentType();
+        }
+
+        type.accept(this, arg);
+        for (ArrayType arrayType : arrayTypeBuffer) {
+            printAnnotations(arrayType.getAnnotations(), true, arg);
+            printer.print("[]");
+        }
+    }
+
+    @Override
+    public void visit(final ArrayCreationLevel n, final Void arg) {
+        printAnnotations(n.getAnnotations(), true, arg);
+        printer.print("[");
+        if (n.getDimension().isPresent()) {
+            n.getDimension().get().accept(this, arg);
+        }
+        printer.print("]");
+    }
+
+    @Override
+    public void visit(final IntersectionType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            element.accept(this, arg);
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" & ");
+            }
+        }
+    }
+
+    @Override
+    public void visit(final UnionType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), true, arg);
+        boolean isFirst = true;
+        for (ReferenceType element : n.getElements()) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                printer.print(" | ");
+            }
+            element.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final WildcardType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("?");
+        if (n.getExtendedTypes().isPresent()) {
+            printer.print(" extends ");
+            n.getExtendedTypes().get().accept(this, arg);
+        }
+        if (n.getSuperTypes().isPresent()) {
+            printer.print(" super ");
+            n.getSuperTypes().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final UnknownType n, final Void arg) {
+        // Nothing to print
+    }
+
+    @Override
+    public void visit(final FieldDeclaration n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        if (!n.getVariables().isEmpty()) {
+            n.getMaximumCommonType().accept(this, arg);
+        }
+
+        printer.print(" ");
+        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+            final VariableDeclarator var = i.next();
+            var.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final VariableDeclarator n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+
+        Type commonType = n.getAncestorOfType(NodeWithVariables.class).get().getMaximumCommonType();
+
+        Type type = n.getType();
+
+        ArrayType arrayType = null;
+
+        for (int i = commonType.getArrayLevel(); i < type.getArrayLevel(); i++) {
+            if (arrayType == null) {
+                arrayType = (ArrayType) type;
+            } else {
+                arrayType = (ArrayType) arrayType.getComponentType();
+            }
+            printAnnotations(arrayType.getAnnotations(), true, arg);
+            printer.print("[]");
+        }
+
+        if (n.getInitializer().isPresent()) {
+            printer.print(" = ");
+            n.getInitializer().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final ArrayInitializerExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("{");
+        if (!isNullOrEmpty(n.getValues())) {
+            printer.print(" ");
+            for (final Iterator<Expression> i = n.getValues().iterator(); i.hasNext(); ) {
+                final Expression expr = i.next();
+                expr.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+            printer.print(" ");
+        }
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final VoidType n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printer.print("void");
+    }
+
+    @Override
+    public void visit(final ArrayAccessExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        printer.print("[");
+        n.getIndex().accept(this, arg);
+        printer.print("]");
+    }
+
+    @Override
+    public void visit(final ArrayCreationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("new ");
+        n.getElementType().accept(this, arg);
+        for (ArrayCreationLevel level : n.getLevels()) {
+            level.accept(this, arg);
+        }
+        if (n.getInitializer().isPresent()) {
+            printer.print(" ");
+            n.getInitializer().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final AssignExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getTarget().accept(this, arg);
+        printer.print(" ");
+        printer.print(n.getOperator().asString());
+        printer.print(" ");
+        n.getValue().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final BinaryExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getLeft().accept(this, arg);
+        printer.print(" ");
+        printer.print(n.getOperator().asString());
+        printer.print(" ");
+        n.getRight().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final CastExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("(");
+        n.getType().accept(this, arg);
+        printer.print(") ");
+        n.getExpression().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ClassExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getType().accept(this, arg);
+        printer.print(".class");
+    }
+
+    @Override
+    public void visit(final ConditionalExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getCondition().accept(this, arg);
+        printer.print(" ? ");
+        n.getThenExpr().accept(this, arg);
+        printer.print(" : ");
+        n.getElseExpr().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final EnclosedExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("(");
+        if (n.getInner().isPresent()) {
+            n.getInner().get().accept(this, arg);
+        }
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final FieldAccessExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getScope().isPresent())
+            n.getScope().get().accept(this, arg);
+        printer.print(".");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final InstanceOfExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getExpression().accept(this, arg);
+        printer.print(" instanceof ");
+        n.getType().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final CharLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("'");
+        printer.print(n.getValue());
+        printer.print("'");
+    }
+
+    @Override
+    public void visit(final DoubleLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final IntegerLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final LongLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(n.getValue());
+    }
+
+    @Override
+    public void visit(final StringLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("\"");
+        printer.print(n.getValue());
+        printer.print("\"");
+    }
+
+    @Override
+    public void visit(final BooleanLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(String.valueOf(n.getValue()));
+    }
+
+    @Override
+    public void visit(final NullLiteralExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("null");
+    }
+
+    @Override
+    public void visit(final ThisExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getClassExpr().isPresent()) {
+            n.getClassExpr().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print("this");
+    }
+
+    @Override
+    public void visit(final SuperExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getClassExpr().isPresent()) {
+            n.getClassExpr().get().accept(this, arg);
+            printer.print(".");
+        }
+        printer.print("super");
+    }
+
+    @Override
+    public void visit(final MethodCallExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+        printTypeArgs(n, arg);
+        n.getName().accept(this, arg);
+        printArguments(n.getArguments(), arg);
+    }
+
+    @Override
+    public void visit(final ObjectCreationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getScope().isPresent()) {
+            n.getScope().get().accept(this, arg);
+            printer.print(".");
+        }
+
+        printer.print("new ");
+
+        printTypeArgs(n, arg);
+        if (!isNullOrEmpty(n.getTypeArguments().orElse(null))) {
+            printer.print(" ");
+        }
+
+        n.getType().accept(this, arg);
+
+        printArguments(n.getArguments(), arg);
+
+        if (n.getAnonymousClassBody().isPresent()) {
+            printer.println(" {");
+            printer.indent();
+            printMembers(n.getAnonymousClassBody().get(), arg);
+            printer.unindent();
+            printer.print("}");
+        }
+    }
+
+    @Override
+    public void visit(final UnaryExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getOperator().isPrefix()) {
+            printer.print(n.getOperator().asString());
+        }
+
+        n.getExpression().accept(this, arg);
+
+        if (n.getOperator().isPostfix()) {
+            printer.print(n.getOperator().asString());
+        }
+    }
+
+    @Override
+    public void visit(final ConstructorDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        printTypeParameters(n.getTypeParameters(), arg);
+        if (n.isGeneric()) {
+            printer.print(" ");
+        }
+        n.getName().accept(this, arg);
+
+        printer.print("(");
+        if (!n.getParameters().isEmpty()) {
+            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+                final Parameter p = i.next();
+                p.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+
+        if (!isNullOrEmpty(n.getThrownExceptions())) {
+            printer.print(" throws ");
+            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
+                final ReferenceType name = i.next();
+                name.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(" ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final MethodDeclaration n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+        if (n.isDefault()) {
+            printer.print("default ");
+        }
+        printTypeParameters(n.getTypeParameters(), arg);
+        if (!isNullOrEmpty(n.getTypeParameters())) {
+            printer.print(" ");
+        }
+
+        n.getType().accept(this, arg);
+        printer.print(" ");
+        n.getName().accept(this, arg);
+
+        printer.print("(");
+        if (!isNullOrEmpty(n.getParameters())) {
+            for (final Iterator<Parameter> i = n.getParameters().iterator(); i.hasNext(); ) {
+                final Parameter p = i.next();
+                p.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+
+        if (!isNullOrEmpty(n.getThrownExceptions())) {
+            printer.print(" throws ");
+            for (final Iterator<ReferenceType> i = n.getThrownExceptions().iterator(); i.hasNext(); ) {
+                final ReferenceType name = i.next();
+                name.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        if (!n.getBody().isPresent()) {
+            printer.print(";");
+        } else {
+            printer.print(" ");
+            n.getBody().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final Parameter n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printModifiers(n.getModifiers());
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+        if (n.isVarArgs()) {
+            printer.print("...");
+        }
+        printer.print(" ");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ExplicitConstructorInvocationStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.isThis()) {
+            printTypeArgs(n, arg);
+            printer.print("this");
+        } else {
+            if (n.getExpression().isPresent()) {
+                n.getExpression().get().accept(this, arg);
+                printer.print(".");
+            }
+            printTypeArgs(n, arg);
+            printer.print("super");
+        }
+        printArguments(n.getArguments(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final VariableDeclarationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printAnnotations(n.getAnnotations(), false, arg);
+        printModifiers(n.getModifiers());
+
+        if (!n.getVariables().isEmpty()) {
+            n.getMaximumCommonType().accept(this, arg);
+        }
+        printer.print(" ");
+
+        for (final Iterator<VariableDeclarator> i = n.getVariables().iterator(); i.hasNext(); ) {
+            final VariableDeclarator v = i.next();
+            v.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+    }
+
+    @Override
+    public void visit(final LocalClassDeclarationStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getClassDeclaration().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final AssertStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("assert ");
+        n.getCheck().accept(this, arg);
+        if (n.getMessage().isPresent()) {
+            printer.print(" : ");
+            n.getMessage().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final BlockStmt n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printJavaComment(n.getComment(), arg);
+        printer.println("{");
+        if (n.getStatements() != null) {
+            printer.indent();
+            for (final Statement s : n.getStatements()) {
+                s.accept(this, arg);
+                printer.println();
+            }
+            printer.unindent();
+        }
+        printOrphanCommentsEnding(n);
+        printer.print("}");
+
+    }
+
+    @Override
+    public void visit(final LabeledStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getLabel().accept(this, arg);
+        printer.print(": ");
+        n.getStatement().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final EmptyStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final ExpressionStmt n, final Void arg) {
+        printOrphanCommentsBeforeThisChildNode(n);
+        printJavaComment(n.getComment(), arg);
+        n.getExpression().accept(this, arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final SwitchStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("switch(");
+        n.getSelector().accept(this, arg);
+        printer.println(") {");
+        if (n.getEntries() != null) {
+            printer.indent();
+            for (final SwitchEntryStmt e : n.getEntries()) {
+                e.accept(this, arg);
+            }
+            printer.unindent();
+        }
+        printer.print("}");
+
+    }
+
+    @Override
+    public void visit(final SwitchEntryStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getLabel().isPresent()) {
+            printer.print("case ");
+            n.getLabel().get().accept(this, arg);
+            printer.print(":");
+        } else {
+            printer.print("default:");
+        }
+        printer.println();
+        printer.indent();
+        if (n.getStatements() != null) {
+            for (final Statement s : n.getStatements()) {
+                s.accept(this, arg);
+                printer.println();
+            }
+        }
+        printer.unindent();
+    }
+
+    @Override
+    public void visit(final BreakStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("break");
+        n.getLabel().ifPresent(l -> printer.print(" ").print(l.getIdentifier()));
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final ReturnStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("return");
+        if (n.getExpression().isPresent()) {
+            printer.print(" ");
+            n.getExpression().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final EnumDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        printer.print("enum ");
+        n.getName().accept(this, arg);
+
+        if (!n.getImplementedTypes().isEmpty()) {
+            printer.print(" implements ");
+            for (final Iterator<ClassOrInterfaceType> i = n.getImplementedTypes().iterator(); i.hasNext(); ) {
+                final ClassOrInterfaceType c = i.next();
+                c.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+
+        printer.println(" {");
+        printer.indent();
+        if (n.getEntries() != null) {
+            printer.println();
+            for (final Iterator<EnumConstantDeclaration> i = n.getEntries().iterator(); i.hasNext(); ) {
+                final EnumConstantDeclaration e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        if (!n.getMembers().isEmpty()) {
+            printer.println(";");
+            printMembers(n.getMembers(), arg);
+        } else {
+            if (!n.getEntries().isEmpty()) {
+                printer.println();
+            }
+        }
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final EnumConstantDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        n.getName().accept(this, arg);
+
+        if (!n.getArguments().isEmpty()) {
+            printArguments(n.getArguments(), arg);
+        }
+
+        if (!n.getClassBody().isEmpty()) {
+            printer.println(" {");
+            printer.indent();
+            printMembers(n.getClassBody(), arg);
+            printer.unindent();
+            printer.println("}");
+        }
+    }
+
+    @Override
+    public void visit(final EmptyMemberDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final InitializerDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.isStatic()) {
+            printer.print("static ");
+        }
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final IfStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("if (");
+        n.getCondition().accept(this, arg);
+        final boolean thenBlock = n.getThenStmt() instanceof BlockStmt;
+        if (thenBlock) // block statement should start on the same line
+            printer.print(") ");
+        else {
+            printer.println(")");
+            printer.indent();
+        }
+        n.getThenStmt().accept(this, arg);
+        if (!thenBlock)
+            printer.unindent();
+        if (n.getElseStmt().isPresent()) {
+            if (thenBlock)
+                printer.print(" ");
+            else
+                printer.println();
+            final boolean elseIf = n.getElseStmt().orElse(null) instanceof IfStmt;
+            final boolean elseBlock = n.getElseStmt().orElse(null) instanceof BlockStmt;
+            if (elseIf || elseBlock) // put chained if and start of block statement on a same level
+                printer.print("else ");
+            else {
+                printer.println("else");
+                printer.indent();
+            }
+            if (n.getElseStmt().isPresent())
+                n.getElseStmt().get().accept(this, arg);
+            if (!(elseIf || elseBlock))
+                printer.unindent();
+        }
+    }
+
+    @Override
+    public void visit(final WhileStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("while (");
+        n.getCondition().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ContinueStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("continue");
+        n.getLabel().ifPresent(l -> printer.print(" ").print(l.getIdentifier()));
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final DoStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("do ");
+        n.getBody().accept(this, arg);
+        printer.print(" while (");
+        n.getCondition().accept(this, arg);
+        printer.print(");");
+    }
+
+    @Override
+    public void visit(final ForeachStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("for (");
+        n.getVariable().accept(this, arg);
+        printer.print(" : ");
+        n.getIterable().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ForStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("for (");
+        if (n.getInitialization() != null) {
+            for (final Iterator<Expression> i = n.getInitialization().iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print("; ");
+        if (n.getCompare().isPresent()) {
+            n.getCompare().get().accept(this, arg);
+        }
+        printer.print("; ");
+        if (n.getUpdate() != null) {
+            for (final Iterator<Expression> i = n.getUpdate().iterator(); i.hasNext(); ) {
+                final Expression e = i.next();
+                e.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final ThrowStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("throw ");
+        n.getExpression().accept(this, arg);
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final SynchronizedStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("synchronized (");
+        n.getExpression().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final TryStmt n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("try ");
+        if (!n.getResources().isEmpty()) {
+            printer.print("(");
+            Iterator<VariableDeclarationExpr> resources = n.getResources().iterator();
+            boolean first = true;
+            while (resources.hasNext()) {
+                visit(resources.next(), arg);
+                if (resources.hasNext()) {
+                    printer.print(";");
+                    printer.println();
+                    if (first) {
+                        printer.indent();
+                    }
+                }
+                first = false;
+            }
+            if (n.getResources().size() > 1) {
+                printer.unindent();
+            }
+            printer.print(") ");
+        }
+        if (n.getTryBlock().isPresent()) {
+            n.getTryBlock().get().accept(this, arg);
+        }
+        for (final CatchClause c : n.getCatchClauses()) {
+            c.accept(this, arg);
+        }
+        if (n.getFinallyBlock().isPresent()) {
+            printer.print(" finally ");
+            n.getFinallyBlock().get().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final CatchClause n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print(" catch (");
+        n.getParameter().accept(this, arg);
+        printer.print(") ");
+        n.getBody().accept(this, arg);
+
+    }
+
+    @Override
+    public void visit(final AnnotationDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        printer.print("@interface ");
+        n.getName().accept(this, arg);
+        printer.println(" {");
+        printer.indent();
+        if (n.getMembers() != null) {
+            printMembers(n.getMembers(), arg);
+        }
+        printer.unindent();
+        printer.print("}");
+    }
+
+    @Override
+    public void visit(final AnnotationMemberDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printMemberAnnotations(n.getAnnotations(), arg);
+        printModifiers(n.getModifiers());
+
+        n.getType().accept(this, arg);
+        printer.print(" ");
+        n.getName().accept(this, arg);
+        printer.print("()");
+        if (n.getDefaultValue().isPresent()) {
+            printer.print(" default ");
+            n.getDefaultValue().get().accept(this, arg);
+        }
+        printer.print(";");
+    }
+
+    @Override
+    public void visit(final MarkerAnnotationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final SingleMemberAnnotationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+        printer.print("(");
+        n.getMemberValue().accept(this, arg);
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final NormalAnnotationExpr n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("@");
+        n.getName().accept(this, arg);
+        printer.print("(");
+        if (n.getPairs() != null) {
+            for (final Iterator<MemberValuePair> i = n.getPairs().iterator(); i.hasNext(); ) {
+                final MemberValuePair m = i.next();
+                m.accept(this, arg);
+                if (i.hasNext()) {
+                    printer.print(", ");
+                }
+            }
+        }
+        printer.print(")");
+    }
+
+    @Override
+    public void visit(final MemberValuePair n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        n.getName().accept(this, arg);
+        printer.print(" = ");
+        n.getValue().accept(this, arg);
+    }
+
+    @Override
+    public void visit(final LineComment n, final Void arg) {
+        if (!configuration.isPrintComments()) {
+            return;
+        }
+        printer.print("//");
+        String tmp = n.getContent();
+        tmp = tmp.replace('\r', ' ');
+        tmp = tmp.replace('\n', ' ');
+        printer.println(tmp);
+    }
+
+    @Override
+    public void visit(final BlockComment n, final Void arg) {
+        if (!configuration.isPrintComments()) {
+            return;
+        }
+        printer.print("/*").print(n.getContent()).println("*/");
+    }
+
+    @Override
+    public void visit(LambdaExpr n, Void arg) {
+        printJavaComment(n.getComment(), arg);
+
+        final NodeList<Parameter> parameters = n.getParameters();
+        final boolean printPar = n.isEnclosingParameters();
+
+        if (printPar) {
+            printer.print("(");
+        }
+        for (Iterator<Parameter> i = parameters.iterator(); i.hasNext(); ) {
+            Parameter p = i.next();
+            p.accept(this, arg);
+            if (i.hasNext()) {
+                printer.print(", ");
+            }
+        }
+        if (printPar) {
+            printer.print(")");
+        }
+
+        printer.print(" -> ");
+        final Statement body = n.getBody();
+        if (body instanceof ExpressionStmt) {
+            // Print the expression directly
+            ((ExpressionStmt) body).getExpression().accept(this, arg);
+        } else {
+            body.accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(MethodReferenceExpr n, Void arg) {
+        printJavaComment(n.getComment(), arg);
+        Expression scope = n.getScope();
+        String identifier = n.getIdentifier();
+        if (scope != null) {
+            n.getScope().accept(this, arg);
+        }
+
+        printer.print("::");
+        printTypeArgs(n, arg);
+        if (identifier != null) {
+            printer.print(identifier);
+        }
+
+    }
+
+    @Override
+    public void visit(TypeExpr n, Void arg) {
+        printJavaComment(n.getComment(), arg);
+        if (n.getType() != null) {
+            n.getType().accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(NodeList n, Void arg) {
+        for (Object node : n) {
+            ((Node) node).accept(this, arg);
+        }
+    }
+
+    @Override
+    public void visit(final ImportDeclaration n, final Void arg) {
+        printJavaComment(n.getComment(), arg);
+        printer.print("import ");
+        if (n.isStatic()) {
+            printer.print("static ");
+        }
+        n.getName().accept(this, arg);
+        if (n.isAsterisk()) {
+            printer.print(".*");
+        }
+        printer.println(";");
+
+        printOrphanCommentsEnding(n);
+    }
+
+    private void printOrphanCommentsBeforeThisChildNode(final Node node) {
+        if (node instanceof Comment) return;
+
+        Node parent = node.getParentNode().orElse(null);
+        if (parent == null) return;
+        List<Node> everything = new LinkedList<>();
+        everything.addAll(parent.getChildNodes());
+        sortByBeginPosition(everything);
+        int positionOfTheChild = -1;
+        for (int i = 0; i < everything.size(); i++) {
+            if (everything.get(i) == node) positionOfTheChild = i;
+        }
+        if (positionOfTheChild == -1) {
+            throw new AssertionError("I am not a child of my parent.");
+        }
+        int positionOfPreviousChild = -1;
+        for (int i = positionOfTheChild - 1; i >= 0 && positionOfPreviousChild == -1; i--) {
+            if (!(everything.get(i) instanceof Comment)) positionOfPreviousChild = i;
+        }
+        for (int i = positionOfPreviousChild + 1; i < positionOfTheChild; i++) {
+            Node nodeToPrint = everything.get(i);
+            if (!(nodeToPrint instanceof Comment))
+                throw new RuntimeException(
+                        "Expected comment, instead " + nodeToPrint.getClass() + ". Position of previous child: "
+                                + positionOfPreviousChild + ", position of child " + positionOfTheChild);
+            nodeToPrint.accept(this, null);
+        }
+    }
+
+    private void printOrphanCommentsEnding(final Node node) {
+        List<Node> everything = new LinkedList<>();
+        everything.addAll(node.getChildNodes());
+        sortByBeginPosition(everything);
+        if (everything.isEmpty()) {
+            return;
+        }
+
+        int commentsAtEnd = 0;
+        boolean findingComments = true;
+        while (findingComments && commentsAtEnd < everything.size()) {
+            Node last = everything.get(everything.size() - 1 - commentsAtEnd);
+            findingComments = (last instanceof Comment);
+            if (findingComments) {
+                commentsAtEnd++;
+            }
+        }
+        for (int i = 0; i < commentsAtEnd; i++) {
+            everything.get(everything.size() - commentsAtEnd + i).accept(this, null);
+        }
+    }
+
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..3e83d99
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,336 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <modules>
+        <module>javaparser-core</module>
+        <module>javaparser-testing</module>
+        <module>javaparser-core-generators</module>
+        <module>javaparser-metamodel-generator</module>
+        <module>javaparser-symbol-solver-model</module>
+        <module>javaparser-symbol-solver-logic</module>
+        <module>javaparser-symbol-solver-core</module>
+        <module>javaparser-symbol-solver-testing</module>
+    </modules>
+
+    <groupId>com.github.javaparser</groupId>
+    <artifactId>javaparser-parent</artifactId>
+    <packaging>pom</packaging>
+    <version>3.5.16-SNAPSHOT</version>
+
+    <name>javaparser-parent</name>
+    <url>https://github.com/javaparser</url>
+    <inceptionYear>2007</inceptionYear>
+    <description>Java 9 Parser Parser and Abstract Syntax Tree for Java</description>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
+            <distribution>repo</distribution>
+        </license>
+        <license>
+            <name>Apache License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+            <comments>A business-friendly OSS license</comments>
+        </license>
+    </licenses>
+
+    <developers>
+        <developer>
+            <name>Danny van Bruggen</name>
+            <email>hexagonaal@gmail.com</email>
+            <url>https://github.com/matozoid</url>
+            <id>matozoid</id>
+        </developer>
+        <developer>
+            <name>Júlio Vilmar Gesser</name>
+            <email>jgesser@gmail.com</email>
+        </developer>
+        <developer>
+            <name>Sebastian Kirsch</name>
+            <email>sebastian.kirsch@immobilienscout24.de</email>
+            <url>https://github.com/sebastiankirsch</url>
+            <id>sebastiankirsch</id>
+        </developer>
+        <developer>
+            <name>André Rouél</name>
+            <url>https://github.com/before</url>
+            <id>before</id>
+        </developer>
+        <developer>
+            <name>Nicholas Smith</name>
+            <email>smiddypence@gmail.com</email>
+            <url>https://github.com/SmiddyPence</url>
+            <id>SmiddyPence</id>
+        </developer>
+        <developer>
+            <name>Federico Tomassetti</name>
+            <email>federico@tomassetti.me</email>
+            <url>https://github.com/ftomassetti</url>
+            <id>ftomassetti</id>
+        </developer>
+        <developer>
+            <name>Didier Villevalois</name>
+            <email>ptitjes@free.fr</email>
+            <url>https://github.com/ptitjes</url>
+            <id>ptitjes</id>
+        </developer>
+    </developers>
+    <contributors>
+        <contributor>
+            <name>Sebastian Kürten</name>
+            <email>sebastian@topobyte.de</email>
+            <url>https://github.com/sebkur</url>
+        </contributor>
+        <contributor>
+            <name>Junfei Liang</name>
+            <email>fly2best@gmail.com</email>
+            <url>https://github.com/fly2best</url>
+        </contributor>
+        <contributor>
+            <name>Jarkko Miettinen</name>
+            <url>https://github.com/jmiettinen</url>
+        </contributor>
+        <contributor>
+            <name>Alexey Morozov</name>
+            <email>morozov@altlinux.org</email>
+            <url>https://github.com/amorozov</url>
+        </contributor>
+        <contributor>
+            <name>Donny Nadolny</name>
+            <email>donny.nadolny@gmail.com</email>
+            <url>https://github.com/dnadolny</url>
+        </contributor>
+        <contributor>
+            <name>Raquel Pau</name>
+            <email>raquelpau@gmail.com</email>
+            <url>https://github.com/rpau</url>
+        </contributor>
+        <contributor>
+            <name>Chao Shi</name>
+            <email>stepinto@live.com</email>
+            <url>https://github.com/stepinto</url>
+        </contributor>
+        <contributor>
+            <name>Michael Schieder</name>
+            <email>michael.schieder@gmail.com</email>
+            <url>https://github.com/mschieder</url>
+        </contributor>
+        <contributor>
+            <name>CRUZ Maximilien</name>
+            <email>maximilien.cruz@gmail.com</email>
+            <url>https://github.com/DeepSnowNeeL</url>
+        </contributor>
+    </contributors>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <java.version>1.8</java.version>
+
+        <!-- Maven Plugins -->
+    </properties>
+
+    <scm>
+        <connection>scm:git:git://github.com/javaparser/javaparser.git</connection>
+        <developerConnection>scm:git:git@github.com:javaparser/javaparser.git</developerConnection>
+        <url>https://github.com/javaparser/javaparser.git</url>
+        <tag>HEAD</tag>
+    </scm>
+
+    <issueManagement>
+        <system>GitHub Issue Tracker</system>
+        <url>https://github.com/javaparser/javaparser/issues</url>
+    </issueManagement>
+
+    <distributionManagement>
+        <repository>
+            <id>bintray-javaparser-JavaParser</id>
+            <name>javaparser-JavaParser</name>
+            <url>https://api.bintray.com/maven/javaparser/JavaParser/javaparser/;publish=1</url>
+        </repository>
+    </distributionManagement>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>com.helger.maven</groupId>
+                    <artifactId>ph-javacc-maven-plugin</artifactId>
+                    <version>3.0.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-clean-plugin</artifactId>
+                    <version>3.0.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.7.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-install-plugin</artifactId>
+                    <version>2.5.2</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-release-plugin</artifactId>
+                    <version>2.5.3</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-source-plugin</artifactId>
+                    <version>3.0.1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-resources-plugin</artifactId>
+                    <version>3.0.1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>3.0.2</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.eluder.coveralls</groupId>
+                    <artifactId>coveralls-maven-plugin</artifactId>
+                    <version>4.3.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.jacoco</groupId>
+                    <artifactId>jacoco-maven-plugin</artifactId>
+                    <version>0.7.9</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <version>3.0.0</version>
+                    <configuration>
+                        <additionalOptions>
+                            <additionalOption>-Xdoclint:none</additionalOption>
+                        </additionalOptions>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-site-plugin</artifactId>
+                    <version>3.7</version>
+                    <configuration>
+                        <additionalOptions>
+                            <additionalOption>-Xdoclint:none</additionalOption>
+                        </additionalOptions>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>biz.aQute.bnd</groupId>
+                    <artifactId>bnd-maven-plugin</artifactId>
+                    <version>3.4.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-enforcer-plugin</artifactId>
+                    <version>3.0.0-M1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.20.1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>animal-sniffer-maven-plugin</artifactId>
+                    <version>1.16</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>exec-maven-plugin</artifactId>
+                    <version>1.6.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-deploy-plugin</artifactId>
+                    <version>2.8.2</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>build-helper-maven-plugin</artifactId>
+                    <version>3.0.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>templating-maven-plugin</artifactId>
+                    <version>1.0.0</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-dependency-plugin</artifactId>
+                    <version>3.0.2</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.javassist</groupId>
+                <artifactId>javassist</artifactId>
+                <version>3.22.0-GA</version>
+            </dependency>
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>23.4-jre</version>
+            </dependency>
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>4.12</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.junit.jupiter</groupId>
+                <artifactId>junit-jupiter-api</artifactId>
+                <version>5.0.0</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.mockito</groupId>
+                <artifactId>mockito-core</artifactId>
+                <version>2.13.0</version>
+                <scope>test</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+    <profiles>
+        <profile>
+            <id>doclint-java8-disable</id>
+            <activation>
+                <jdk>[1.8,)</jdk>
+            </activation>
+        </profile>
+    </profiles>
+</project>
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..5596fdf
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,93 @@
+# JavaParser

+

+[![Maven Central](https://img.shields.io/maven-central/v/com.github.javaparser/javaparser-core.svg)](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.javaparser%22%20AND%20a%3A%22javaparser-core%22)

+[![Build Status](https://travis-ci.org/javaparser/javaparser.svg?branch=master)](https://travis-ci.org/javaparser/javaparser)

+[![Coverage Status](https://coveralls.io/repos/javaparser/javaparser/badge.svg?branch=master&service=github)](https://coveralls.io/github/javaparser/javaparser?branch=master)

+[![Join the chat at https://gitter.im/javaparser/javaparser](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/javaparser/javaparser?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

+

+This project contains a set of libraries implementing a Java 1.0 - Java 9 Parser with advanced analysis functionalities.

+

+Our main site is at [JavaParser.org](http://javaparser.org)

+

+## Setup

+

+The project binaries are available in Maven Central. 

+

+We strongly advises users to adopt Maven, Gradle or another build system for their projects. If you are not familiar with them

+we suggest taking a look at the maven quickstart projects 

+([javaparser-maven-sample](https://github.com/javaparser/javaparser-maven-sample), 

+[javasymbolsolver-maven-sample](https://github.com/javaparser/javasymbolsolver-maven-sample)).

+

+Just add the following to your maven configuration or tailor to your own dependency management system.

+

+[Please refer to the Migration Guide when upgrading from 2.5.1 to 3.0.0+](https://github.com/javaparser/javaparser/wiki/Migration-Guide)

+

+**Maven**: 

+

+```xml

+<dependency>

+    <groupId>com.github.javaparser</groupId>

+    <artifactId>javaparser-symbol-solver-core</artifactId>

+    <version>3.5.15</version>

+</dependency>

+```

+

+**Gradle**:

+

+```

+compile 'com.github.javaparser:javaparser-symbol-solver-core:3.5.15'

+```

+

+Since Version 3.5.10, the JavaParser project includes the JavaSymbolSolver. 

+While JavaParser generates an Abstract Syntax Tree, JavaSymbolSolver analyzes that AST and is able to find 

+the relation between an element and its declaration (e.g. for a variable name it could be a parameter of a method, providing information about its type, position in the AST, ect).

+

+Using the dependency above will add both JavaParser and JavaSymbolSolver to your project. If you only need the core functionality of parsing Java source code in order to traverse and manipulate the generated AST, you can reduce your projects boilerplate by only including JavaParser to your project:

+

+**Maven**: 

+

+```xml

+<dependency>

+    <groupId>com.github.javaparser</groupId>

+    <artifactId>javaparser-core</artifactId>

+    <version>3.5.15</version>

+</dependency>

+```

+

+**Gradle**:

+

+```

+compile 'com.github.javaparser:javaparser-core:3.5.15'

+```

+

+## How To Compile Sources

+

+If you checked out the project from GitHub you can build the project with maven using:

+

+```

+mvn clean install

+```

+

+If you checkout the sources and want to view the project in an IDE, it is best to first generate some of the source files; otherwise you will get many compilation complaints in the IDE. (mvn clean install already does this for you.)

+

+```

+mvn javacc:javacc

+```

+

+If you modify the code of the AST nodes, specifically if you add or remove fields or node classes,

+the code generators will update a lot of code for you.

+The `run_metamodel_generator.sh` script will rebuild the metamodel,

+which is used by the code generators which are run by `run_core_generators.sh`

+Make sure that `javaparser-core` at least compiles before you run these.

+

+## More information

+

+#### [JavaParser.org](https://www.javaparser.org) is the main information site.

+

+## License

+

+JavaParser is available either under the terms of the LGPL License or the Apache License. You as the user are entitled to choose the terms under which adopt JavaParser.

+

+For details about the LGPL License please refer to [LICENSE.LGPL](ttps://github.com/javaparser/javaparser/blob/master/LICENSE.LGPL).

+

+For details about the Apache License please refer to [LICENSE.APACHE](ttps://github.com/javaparser/javaparser/blob/master/LICENSE.APACHE).

diff --git a/run_core_generators.sh b/run_core_generators.sh
new file mode 100755
index 0000000..3fb9241
--- /dev/null
+++ b/run_core_generators.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+
+# Runs all the code generators.
+# If the node structure was changed, run_metamodel_generator.sh first!
+
+# Remember current directory
+pushd javaparser-core-generators
+
+# Generate code
+mvn clean package -P run-core-generators -DskipTests
+
+# Go back to previous directory
+popd
+
+# Fresh code has been generated in core, so rebuild the whole thing again.
+mvn clean install -DskipTests
+if [ "$?" -ne 0 ]; then
+    exit 1
+fi
diff --git a/run_metamodel_generator.sh b/run_metamodel_generator.sh
new file mode 100755
index 0000000..2644f98
--- /dev/null
+++ b/run_metamodel_generator.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+# Rebuilds the metamodel based on the nodes in javaparser-core
+
+# We introspect the nodes in javaparser-core, so we need an update build of it. 
+mvn clean install -DskipTests
+if [ "$?" -ne 0 ]; then
+    exit 1
+fi
+
+# Remember current directory
+pushd javaparser-metamodel-generator
+
+# Generate code
+mvn clean package -P run-metamodel-generator -DskipTests
+
+# Go back to previous directory
+popd
+
+# Fresh code has been generated in core, so rebuild the whole thing again.
+mvn clean install -DskipTests
+if [ "$?" -ne 0 ]; then
+    exit 1
+fi